aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/Makefile29
-rw-r--r--tools/bugpoint/BugDriver.cpp239
-rw-r--r--tools/bugpoint/BugDriver.h316
-rw-r--r--tools/bugpoint/CrashDebugger.cpp559
-rw-r--r--tools/bugpoint/ExecutionDriver.cpp404
-rw-r--r--tools/bugpoint/ExtractFunction.cpp368
-rw-r--r--tools/bugpoint/FindBugs.cpp115
-rw-r--r--tools/bugpoint/ListReducer.h190
-rw-r--r--tools/bugpoint/Makefile17
-rw-r--r--tools/bugpoint/Miscompilation.cpp915
-rw-r--r--tools/bugpoint/OptimizerDriver.cpp254
-rw-r--r--tools/bugpoint/TestPasses.cpp75
-rw-r--r--tools/bugpoint/ToolRunner.cpp626
-rw-r--r--tools/bugpoint/ToolRunner.h214
-rw-r--r--tools/bugpoint/bugpoint.cpp94
-rw-r--r--tools/gccas/Makefile28
-rw-r--r--tools/gccas/gccas.sh64
-rw-r--r--tools/gccld/Makefile29
-rw-r--r--tools/gccld/gccld.sh23
-rw-r--r--tools/llc/Makefile21
-rw-r--r--tools/llc/llc.cpp304
-rw-r--r--tools/lli/Makefile15
-rw-r--r--tools/lli/lli.cpp160
-rw-r--r--tools/llvm-ar/Makefile22
-rw-r--r--tools/llvm-ar/llvm-ar.cpp773
-rw-r--r--tools/llvm-as/Makefile15
-rw-r--r--tools/llvm-as/llvm-as.cpp141
-rw-r--r--tools/llvm-bcanalyzer/Makefile15
-rw-r--r--tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp504
-rw-r--r--tools/llvm-config/Makefile87
-rwxr-xr-xtools/llvm-config/find-cycles.pl165
-rw-r--r--tools/llvm-config/llvm-config.in.in445
-rw-r--r--tools/llvm-db/CLICommand.h111
-rw-r--r--tools/llvm-db/CLIDebugger.cpp308
-rw-r--r--tools/llvm-db/CLIDebugger.h205
-rw-r--r--tools/llvm-db/Commands.cpp863
-rw-r--r--tools/llvm-db/Makefile15
-rw-r--r--tools/llvm-db/llvm-db.cpp96
-rw-r--r--tools/llvm-dis/Makefile15
-rw-r--r--tools/llvm-dis/llvm-dis.cpp138
-rw-r--r--tools/llvm-extract/Makefile15
-rw-r--r--tools/llvm-extract/llvm-extract.cpp117
-rw-r--r--tools/llvm-ld/Makefile16
-rw-r--r--tools/llvm-ld/Optimize.cpp216
-rw-r--r--tools/llvm-ld/llvm-ld.cpp653
-rw-r--r--tools/llvm-link/Makefile14
-rw-r--r--tools/llvm-link/llvm-link.cpp150
-rw-r--r--tools/llvm-nm/Makefile14
-rw-r--r--tools/llvm-nm/llvm-nm.cpp184
-rw-r--r--tools/llvm-prof/Makefile15
-rw-r--r--tools/llvm-prof/llvm-prof.cpp251
-rw-r--r--tools/llvm-ranlib/Makefile15
-rw-r--r--tools/llvm-ranlib/llvm-ranlib.cpp96
-rw-r--r--tools/llvm-stub/Makefile13
-rw-r--r--tools/llvm-stub/llvm-stub.c69
-rw-r--r--tools/llvm-upgrade/Makefile32
-rw-r--r--tools/llvm-upgrade/UpgradeInternals.h395
-rw-r--r--tools/llvm-upgrade/UpgradeLexer.cpp.cvs3077
-rw-r--r--tools/llvm-upgrade/UpgradeLexer.l427
-rw-r--r--tools/llvm-upgrade/UpgradeLexer.l.cvs427
-rw-r--r--tools/llvm-upgrade/UpgradeParser.cpp.cvs6944
-rw-r--r--tools/llvm-upgrade/UpgradeParser.h.cvs390
-rw-r--r--tools/llvm-upgrade/UpgradeParser.y3957
-rw-r--r--tools/llvm-upgrade/UpgradeParser.y.cvs3957
-rw-r--r--tools/llvm-upgrade/llvm-upgrade.cpp144
-rw-r--r--tools/llvm2cpp/CppWriter.cpp1884
-rw-r--r--tools/llvm2cpp/CppWriter.h18
-rw-r--r--tools/llvm2cpp/Makefile15
-rw-r--r--tools/llvm2cpp/llvm2cpp.cpp122
-rw-r--r--tools/llvmc/CompilerDriver.cpp1032
-rw-r--r--tools/llvmc/CompilerDriver.h206
-rw-r--r--tools/llvmc/ConfigLexer.cpp.cvs2724
-rw-r--r--tools/llvmc/ConfigLexer.h113
-rw-r--r--tools/llvmc/ConfigLexer.l201
-rw-r--r--tools/llvmc/ConfigLexer.l.cvs201
-rw-r--r--tools/llvmc/Configuration.cpp633
-rw-r--r--tools/llvmc/Configuration.h62
-rw-r--r--tools/llvmc/LICENSE.TXT6
-rw-r--r--tools/llvmc/Makefile34
-rw-r--r--tools/llvmc/c60
-rw-r--r--tools/llvmc/cpp61
-rw-r--r--tools/llvmc/ll11
-rw-r--r--tools/llvmc/llvmc.cpp370
-rw-r--r--tools/llvmc/st63
-rw-r--r--tools/lto/Makefile30
-rw-r--r--tools/lto/lto-c.cpp66
-rw-r--r--tools/lto/lto.cpp496
-rw-r--r--tools/opt/AnalysisWrappers.cpp88
-rw-r--r--tools/opt/GraphPrinters.cpp83
-rw-r--r--tools/opt/Makefile15
-rw-r--r--tools/opt/PrintSCC.cpp112
-rw-r--r--tools/opt/opt.cpp441
92 files changed, 39712 insertions, 0 deletions
diff --git a/tools/Makefile b/tools/Makefile
new file mode 100644
index 0000000..3d2c1f0
--- /dev/null
+++ b/tools/Makefile
@@ -0,0 +1,29 @@
+##===- tools/Makefile --------------------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file was developed by the LLVM research group and is distributed under
+# the University of Illinois Open Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL := ..
+# NOTE: The tools are organized into five groups of four consisting of one
+# large and three small executables. This is done to minimize memory load
+# in parallel builds. Please retain this ordering.
+PARALLEL_DIRS := llvm-config \
+ opt llvm-as llvm-dis llvm-upgrade \
+ llc llvm-ranlib llvm-ar llvm-nm \
+ llvm-ld llvmc llvm-prof llvm-link \
+ lli gccas gccld llvm-extract llvm-db llvm2cpp \
+ bugpoint llvm-stub llvm-bcanalyzer llvm-stub
+
+
+include $(LEVEL)/Makefile.config
+
+# Disable liblto on Windows until compatability is determined.
+ifneq ($(OS), MingW)
+PARALLEL_DIRS += lto
+endif
+
+include $(LEVEL)/Makefile.common
diff --git a/tools/bugpoint/BugDriver.cpp b/tools/bugpoint/BugDriver.cpp
new file mode 100644
index 0000000..e8c47a5
--- /dev/null
+++ b/tools/bugpoint/BugDriver.cpp
@@ -0,0 +1,239 @@
+//===- BugDriver.cpp - Top-Level BugPoint class implementation ------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class contains all of the shared state and information that is used by
+// the BugPoint tool to track down errors in optimizations. This class is the
+// main driver class that invokes all sub-functionality.
+//
+//===----------------------------------------------------------------------===//
+
+#include "BugDriver.h"
+#include "ToolRunner.h"
+#include "llvm/Linker.h"
+#include "llvm/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Assembly/Parser.h"
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FileUtilities.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include <iostream>
+#include <memory>
+using namespace llvm;
+
+// Anonymous namespace to define command line options for debugging.
+//
+namespace {
+ // Output - The user can specify a file containing the expected output of the
+ // program. If this filename is set, it is used as the reference diff source,
+ // otherwise the raw input run through an interpreter is used as the reference
+ // source.
+ //
+ cl::opt<std::string>
+ OutputFile("output", cl::desc("Specify a reference program output "
+ "(for miscompilation detection)"));
+}
+
+/// setNewProgram - If we reduce or update the program somehow, call this method
+/// to update bugdriver with it. This deletes the old module and sets the
+/// specified one as the current program.
+void BugDriver::setNewProgram(Module *M) {
+ delete Program;
+ Program = M;
+}
+
+
+/// getPassesString - Turn a list of passes into a string which indicates the
+/// command line options that must be passed to add the passes.
+///
+std::string llvm::getPassesString(const std::vector<const PassInfo*> &Passes) {
+ std::string Result;
+ for (unsigned i = 0, e = Passes.size(); i != e; ++i) {
+ if (i) Result += " ";
+ Result += "-";
+ Result += Passes[i]->getPassArgument();
+ }
+ return Result;
+}
+
+BugDriver::BugDriver(const char *toolname, bool as_child, bool find_bugs,
+ unsigned timeout, unsigned memlimit)
+ : ToolName(toolname), ReferenceOutputFile(OutputFile),
+ Program(0), Interpreter(0), cbe(0), gcc(0), run_as_child(as_child),
+ run_find_bugs(find_bugs), Timeout(timeout), MemoryLimit(memlimit) {}
+
+
+/// ParseInputFile - Given a bitcode or assembly input filename, parse and
+/// return it, or return null if not possible.
+///
+Module *llvm::ParseInputFile(const std::string &Filename) {
+ std::auto_ptr<MemoryBuffer> Buffer(MemoryBuffer::getFileOrSTDIN(Filename));
+ Module *Result = 0;
+ if (Buffer.get())
+ Result = ParseBitcodeFile(Buffer.get());
+
+ ParseError Err;
+ if (!Result && !(Result = ParseAssemblyFile(Filename, &Err))) {
+ std::cerr << "bugpoint: " << Err.getMessage() << "\n";
+ Result = 0;
+ }
+
+ return Result;
+}
+
+// This method takes the specified list of LLVM input files, attempts to load
+// them, either as assembly or bitcode, then link them together. It returns
+// true on failure (if, for example, an input bitcode file could not be
+// parsed), and false on success.
+//
+bool BugDriver::addSources(const std::vector<std::string> &Filenames) {
+ assert(Program == 0 && "Cannot call addSources multiple times!");
+ assert(!Filenames.empty() && "Must specify at least on input filename!");
+
+ try {
+ // Load the first input file.
+ Program = ParseInputFile(Filenames[0]);
+ if (Program == 0) return true;
+
+ if (!run_as_child)
+ std::cout << "Read input file : '" << Filenames[0] << "'\n";
+
+ for (unsigned i = 1, e = Filenames.size(); i != e; ++i) {
+ std::auto_ptr<Module> M(ParseInputFile(Filenames[i]));
+ if (M.get() == 0) return true;
+
+ if (!run_as_child)
+ std::cout << "Linking in input file: '" << Filenames[i] << "'\n";
+ std::string ErrorMessage;
+ if (Linker::LinkModules(Program, M.get(), &ErrorMessage)) {
+ std::cerr << ToolName << ": error linking in '" << Filenames[i] << "': "
+ << ErrorMessage << '\n';
+ return true;
+ }
+ }
+ } catch (const std::string &Error) {
+ std::cerr << ToolName << ": error reading input '" << Error << "'\n";
+ return true;
+ }
+
+ if (!run_as_child)
+ std::cout << "*** All input ok\n";
+
+ // All input files read successfully!
+ return false;
+}
+
+
+
+/// run - The top level method that is invoked after all of the instance
+/// variables are set up from command line arguments.
+///
+bool BugDriver::run() {
+ // The first thing to do is determine if we're running as a child. If we are,
+ // then what to do is very narrow. This form of invocation is only called
+ // from the runPasses method to actually run those passes in a child process.
+ if (run_as_child) {
+ // Execute the passes
+ return runPassesAsChild(PassesToRun);
+ }
+
+ if (run_find_bugs) {
+ // Rearrange the passes and apply them to the program. Repeat this process
+ // until the user kills the program or we find a bug.
+ return runManyPasses(PassesToRun);
+ }
+
+ // If we're not running as a child, the first thing that we must do is
+ // determine what the problem is. Does the optimization series crash the
+ // compiler, or does it produce illegal code? We make the top-level
+ // decision by trying to run all of the passes on the the input program,
+ // which should generate a bitcode file. If it does generate a bitcode
+ // file, then we know the compiler didn't crash, so try to diagnose a
+ // miscompilation.
+ if (!PassesToRun.empty()) {
+ std::cout << "Running selected passes on program to test for crash: ";
+ if (runPasses(PassesToRun))
+ return debugOptimizerCrash();
+ }
+
+ // Set up the execution environment, selecting a method to run LLVM bitcode.
+ if (initializeExecutionEnvironment()) return true;
+
+ // Test to see if we have a code generator crash.
+ std::cout << "Running the code generator to test for a crash: ";
+ try {
+ compileProgram(Program);
+ std::cout << '\n';
+ } catch (ToolExecutionError &TEE) {
+ std::cout << TEE.what();
+ return debugCodeGeneratorCrash();
+ }
+
+
+ // Run the raw input to see where we are coming from. If a reference output
+ // was specified, make sure that the raw output matches it. If not, it's a
+ // problem in the front-end or the code generator.
+ //
+ bool CreatedOutput = false;
+ if (ReferenceOutputFile.empty()) {
+ std::cout << "Generating reference output from raw program: ";
+ if(!createReferenceFile(Program)){
+ return debugCodeGeneratorCrash();
+ }
+ CreatedOutput = true;
+ }
+
+ // Make sure the reference output file gets deleted on exit from this
+ // function, if appropriate.
+ sys::Path ROF(ReferenceOutputFile);
+ FileRemover RemoverInstance(ROF, CreatedOutput);
+
+ // Diff the output of the raw program against the reference output. If it
+ // matches, then we assume there is a miscompilation bug and try to
+ // diagnose it.
+ std::cout << "*** Checking the code generator...\n";
+ try {
+ if (!diffProgram()) {
+ std::cout << "\n*** Debugging miscompilation!\n";
+ return debugMiscompilation();
+ }
+ } catch (ToolExecutionError &TEE) {
+ std::cerr << TEE.what();
+ return debugCodeGeneratorCrash();
+ }
+
+ std::cout << "\n*** Input program does not match reference diff!\n";
+ std::cout << "Debugging code generator problem!\n";
+ try {
+ return debugCodeGenerator();
+ } catch (ToolExecutionError &TEE) {
+ std::cerr << TEE.what();
+ return debugCodeGeneratorCrash();
+ }
+}
+
+void llvm::PrintFunctionList(const std::vector<Function*> &Funcs) {
+ unsigned NumPrint = Funcs.size();
+ if (NumPrint > 10) NumPrint = 10;
+ for (unsigned i = 0; i != NumPrint; ++i)
+ std::cout << " " << Funcs[i]->getName();
+ if (NumPrint < Funcs.size())
+ std::cout << "... <" << Funcs.size() << " total>";
+ std::cout << std::flush;
+}
+
+void llvm::PrintGlobalVariableList(const std::vector<GlobalVariable*> &GVs) {
+ unsigned NumPrint = GVs.size();
+ if (NumPrint > 10) NumPrint = 10;
+ for (unsigned i = 0; i != NumPrint; ++i)
+ std::cout << " " << GVs[i]->getName();
+ if (NumPrint < GVs.size())
+ std::cout << "... <" << GVs.size() << " total>";
+ std::cout << std::flush;
+}
diff --git a/tools/bugpoint/BugDriver.h b/tools/bugpoint/BugDriver.h
new file mode 100644
index 0000000..4652e37
--- /dev/null
+++ b/tools/bugpoint/BugDriver.h
@@ -0,0 +1,316 @@
+//===- BugDriver.h - Top-Level BugPoint class -------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class contains all of the shared state and information that is used by
+// the BugPoint tool to track down errors in optimizations. This class is the
+// main driver class that invokes all sub-functionality.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef BUGDRIVER_H
+#define BUGDRIVER_H
+
+#include <vector>
+#include <string>
+
+namespace llvm {
+
+class PassInfo;
+class Module;
+class GlobalVariable;
+class Function;
+class BasicBlock;
+class AbstractInterpreter;
+class Instruction;
+
+class DebugCrashes;
+
+class GCC;
+
+extern bool DisableSimplifyCFG;
+
+/// BugpointIsInterrupted - Set to true when the user presses ctrl-c.
+///
+extern bool BugpointIsInterrupted;
+
+class BugDriver {
+ const std::string ToolName; // Name of bugpoint
+ std::string ReferenceOutputFile; // Name of `good' output file
+ Module *Program; // The raw program, linked together
+ std::vector<const PassInfo*> PassesToRun;
+ AbstractInterpreter *Interpreter; // How to run the program
+ AbstractInterpreter *cbe;
+ GCC *gcc;
+ bool run_as_child;
+ bool run_find_bugs;
+ unsigned Timeout;
+ unsigned MemoryLimit;
+
+ // FIXME: sort out public/private distinctions...
+ friend class ReducePassList;
+ friend class ReduceMisCodegenFunctions;
+
+public:
+ BugDriver(const char *toolname, bool as_child, bool find_bugs,
+ unsigned timeout, unsigned memlimit);
+
+ const std::string &getToolName() const { return ToolName; }
+
+ // Set up methods... these methods are used to copy information about the
+ // command line arguments into instance variables of BugDriver.
+ //
+ bool addSources(const std::vector<std::string> &FileNames);
+ template<class It>
+ void addPasses(It I, It E) { PassesToRun.insert(PassesToRun.end(), I, E); }
+ void setPassesToRun(const std::vector<const PassInfo*> &PTR) {
+ PassesToRun = PTR;
+ }
+ const std::vector<const PassInfo*> &getPassesToRun() const {
+ return PassesToRun;
+ }
+
+ /// run - The top level method that is invoked after all of the instance
+ /// variables are set up from command line arguments. The \p as_child argument
+ /// indicates whether the driver is to run in parent mode or child mode.
+ ///
+ bool run();
+
+ /// debugOptimizerCrash - This method is called when some optimizer pass
+ /// crashes on input. It attempts to prune down the testcase to something
+ /// reasonable, and figure out exactly which pass is crashing.
+ ///
+ bool debugOptimizerCrash(const std::string &ID = "passes");
+
+ /// debugCodeGeneratorCrash - This method is called when the code generator
+ /// crashes on an input. It attempts to reduce the input as much as possible
+ /// while still causing the code generator to crash.
+ bool debugCodeGeneratorCrash();
+
+ /// debugMiscompilation - This method is used when the passes selected are not
+ /// crashing, but the generated output is semantically different from the
+ /// input.
+ bool debugMiscompilation();
+
+ /// debugPassMiscompilation - This method is called when the specified pass
+ /// miscompiles Program as input. It tries to reduce the testcase to
+ /// something that smaller that still miscompiles the program.
+ /// ReferenceOutput contains the filename of the file containing the output we
+ /// are to match.
+ ///
+ bool debugPassMiscompilation(const PassInfo *ThePass,
+ const std::string &ReferenceOutput);
+
+ /// compileSharedObject - This method creates a SharedObject from a given
+ /// BitcodeFile for debugging a code generator.
+ ///
+ std::string compileSharedObject(const std::string &BitcodeFile);
+
+ /// debugCodeGenerator - This method narrows down a module to a function or
+ /// set of functions, using the CBE as a ``safe'' code generator for other
+ /// functions that are not under consideration.
+ bool debugCodeGenerator();
+
+ /// isExecutingJIT - Returns true if bugpoint is currently testing the JIT
+ ///
+ bool isExecutingJIT();
+
+ /// runPasses - Run all of the passes in the "PassesToRun" list, discard the
+ /// output, and return true if any of the passes crashed.
+ bool runPasses(Module *M = 0) {
+ if (M == 0) M = Program;
+ std::swap(M, Program);
+ bool Result = runPasses(PassesToRun);
+ std::swap(M, Program);
+ return Result;
+ }
+
+ Module *getProgram() const { return Program; }
+
+ /// swapProgramIn - Set the current module to the specified module, returning
+ /// the old one.
+ Module *swapProgramIn(Module *M) {
+ Module *OldProgram = Program;
+ Program = M;
+ return OldProgram;
+ }
+
+ AbstractInterpreter *switchToCBE() {
+ AbstractInterpreter *Old = Interpreter;
+ Interpreter = (AbstractInterpreter*)cbe;
+ return Old;
+ }
+
+ void switchToInterpreter(AbstractInterpreter *AI) {
+ Interpreter = AI;
+ }
+
+ /// setNewProgram - If we reduce or update the program somehow, call this
+ /// method to update bugdriver with it. This deletes the old module and sets
+ /// the specified one as the current program.
+ void setNewProgram(Module *M);
+
+ /// compileProgram - Try to compile the specified module, throwing an
+ /// exception if an error occurs, or returning normally if not. This is used
+ /// for code generation crash testing.
+ ///
+ void compileProgram(Module *M);
+
+ /// executeProgram - This method runs "Program", capturing the output of the
+ /// program to a file, returning the filename of the file. A recommended
+ /// filename may be optionally specified. If there is a problem with the code
+ /// generator (e.g., llc crashes), this will throw an exception.
+ ///
+ std::string executeProgram(std::string RequestedOutputFilename = "",
+ std::string Bitcode = "",
+ const std::string &SharedObjects = "",
+ AbstractInterpreter *AI = 0,
+ bool *ProgramExitedNonzero = 0);
+
+ /// executeProgramWithCBE - Used to create reference output with the C
+ /// backend, if reference output is not provided. If there is a problem with
+ /// the code generator (e.g., llc crashes), this will throw an exception.
+ ///
+ std::string executeProgramWithCBE(std::string OutputFile = "");
+
+ /// createReferenceFile - calls compileProgram and then records the output
+ /// into ReferenceOutputFile. Returns true if reference file created, false
+ /// otherwise. Note: initializeExecutionEnvironment should be called BEFORE
+ /// this function.
+ ///
+ bool createReferenceFile(Module *M, const std::string &Filename
+ = "bugpoint.reference.out");
+
+ /// diffProgram - This method executes the specified module and diffs the
+ /// output against the file specified by ReferenceOutputFile. If the output
+ /// is different, true is returned. If there is a problem with the code
+ /// generator (e.g., llc crashes), this will throw an exception.
+ ///
+ bool diffProgram(const std::string &BitcodeFile = "",
+ const std::string &SharedObj = "",
+ bool RemoveBitcode = false);
+
+ /// EmitProgressBitcode - This function is used to output the current Program
+ /// to a file named "bugpoint-ID.bc".
+ ///
+ void EmitProgressBitcode(const std::string &ID, bool NoFlyer = false);
+
+ /// deleteInstructionFromProgram - This method clones the current Program and
+ /// deletes the specified instruction from the cloned module. It then runs a
+ /// series of cleanup passes (ADCE and SimplifyCFG) to eliminate any code
+ /// which depends on the value. The modified module is then returned.
+ ///
+ Module *deleteInstructionFromProgram(const Instruction *I, unsigned Simp)
+ const;
+
+ /// performFinalCleanups - This method clones the current Program and performs
+ /// a series of cleanups intended to get rid of extra cruft on the module. If
+ /// the MayModifySemantics argument is true, then the cleanups is allowed to
+ /// modify how the code behaves.
+ ///
+ Module *performFinalCleanups(Module *M, bool MayModifySemantics = false);
+
+ /// ExtractLoop - Given a module, extract up to one loop from it into a new
+ /// function. This returns null if there are no extractable loops in the
+ /// program or if the loop extractor crashes.
+ Module *ExtractLoop(Module *M);
+
+ /// ExtractMappedBlocksFromModule - Extract all but the specified basic blocks
+ /// into their own functions. The only detail is that M is actually a module
+ /// cloned from the one the BBs are in, so some mapping needs to be performed.
+ /// If this operation fails for some reason (ie the implementation is buggy),
+ /// this function should return null, otherwise it returns a new Module.
+ Module *ExtractMappedBlocksFromModule(const std::vector<BasicBlock*> &BBs,
+ Module *M);
+
+ /// runPassesOn - Carefully run the specified set of pass on the specified
+ /// module, returning the transformed module on success, or a null pointer on
+ /// failure. If AutoDebugCrashes is set to true, then bugpoint will
+ /// automatically attempt to track down a crashing pass if one exists, and
+ /// this method will never return null.
+ Module *runPassesOn(Module *M, const std::vector<const PassInfo*> &Passes,
+ bool AutoDebugCrashes = false);
+
+ /// runPasses - Run the specified passes on Program, outputting a bitcode
+ /// file and writting the filename into OutputFile if successful. If the
+ /// optimizations fail for some reason (optimizer crashes), return true,
+ /// otherwise return false. If DeleteOutput is set to true, the bitcode is
+ /// deleted on success, and the filename string is undefined. This prints to
+ /// cout a single line message indicating whether compilation was successful
+ /// or failed, unless Quiet is set.
+ ///
+ bool runPasses(const std::vector<const PassInfo*> &PassesToRun,
+ std::string &OutputFilename, bool DeleteOutput = false,
+ bool Quiet = false) const;
+
+ /// runManyPasses - Take the specified pass list and create different
+ /// combinations of passes to compile the program with. Compile the program with
+ /// each set and mark test to see if it compiled correctly. If the passes
+ /// compiled correctly output nothing and rearrange the passes into a new order.
+ /// If the passes did not compile correctly, output the command required to
+ /// recreate the failure. This returns true if a compiler error is found.
+ ///
+ bool runManyPasses(const std::vector<const PassInfo*> &AllPasses);
+
+ /// writeProgramToFile - This writes the current "Program" to the named
+ /// bitcode file. If an error occurs, true is returned.
+ ///
+ bool writeProgramToFile(const std::string &Filename, Module *M = 0) const;
+
+private:
+ /// runPasses - Just like the method above, but this just returns true or
+ /// false indicating whether or not the optimizer crashed on the specified
+ /// input (true = crashed).
+ ///
+ bool runPasses(const std::vector<const PassInfo*> &PassesToRun,
+ bool DeleteOutput = true) const {
+ std::string Filename;
+ return runPasses(PassesToRun, Filename, DeleteOutput);
+ }
+
+ /// runAsChild - The actual "runPasses" guts that runs in a child process.
+ int runPassesAsChild(const std::vector<const PassInfo*> &PassesToRun);
+
+ /// initializeExecutionEnvironment - This method is used to set up the
+ /// environment for executing LLVM programs.
+ ///
+ bool initializeExecutionEnvironment();
+};
+
+/// ParseInputFile - Given a bitcode or assembly input filename, parse and
+/// return it, or return null if not possible.
+///
+Module *ParseInputFile(const std::string &InputFilename);
+
+
+/// getPassesString - Turn a list of passes into a string which indicates the
+/// command line options that must be passed to add the passes.
+///
+std::string getPassesString(const std::vector<const PassInfo*> &Passes);
+
+/// PrintFunctionList - prints out list of problematic functions
+///
+void PrintFunctionList(const std::vector<Function*> &Funcs);
+
+/// PrintGlobalVariableList - prints out list of problematic global variables
+///
+void PrintGlobalVariableList(const std::vector<GlobalVariable*> &GVs);
+
+// DeleteFunctionBody - "Remove" the function by deleting all of it's basic
+// blocks, making it external.
+//
+void DeleteFunctionBody(Function *F);
+
+/// SplitFunctionsOutOfModule - Given a module and a list of functions in the
+/// module, split the functions OUT of the specified module, and place them in
+/// the new module.
+Module *SplitFunctionsOutOfModule(Module *M, const std::vector<Function*> &F);
+
+} // End llvm namespace
+
+#endif
diff --git a/tools/bugpoint/CrashDebugger.cpp b/tools/bugpoint/CrashDebugger.cpp
new file mode 100644
index 0000000..dac8538
--- /dev/null
+++ b/tools/bugpoint/CrashDebugger.cpp
@@ -0,0 +1,559 @@
+//===- CrashDebugger.cpp - Debug compilation crashes ----------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the bugpoint internals that narrow down compilation crashes
+//
+//===----------------------------------------------------------------------===//
+
+#include "BugDriver.h"
+#include "ToolRunner.h"
+#include "ListReducer.h"
+#include "llvm/Constant.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/PassManager.h"
+#include "llvm/ValueSymbolTable.h"
+#include "llvm/Analysis/Verifier.h"
+#include "llvm/Support/CFG.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Utils/Cloning.h"
+#include "llvm/Support/FileUtilities.h"
+#include "llvm/Support/CommandLine.h"
+#include <fstream>
+#include <set>
+using namespace llvm;
+
+namespace {
+ cl::opt<bool>
+ KeepMain("keep-main",
+ cl::desc("Force function reduction to keep main"),
+ cl::init(false));
+}
+
+namespace llvm {
+ class ReducePassList : public ListReducer<const PassInfo*> {
+ BugDriver &BD;
+ public:
+ ReducePassList(BugDriver &bd) : BD(bd) {}
+
+ // doTest - Return true iff running the "removed" passes succeeds, and
+ // running the "Kept" passes fail when run on the output of the "removed"
+ // passes. If we return true, we update the current module of bugpoint.
+ //
+ virtual TestResult doTest(std::vector<const PassInfo*> &Removed,
+ std::vector<const PassInfo*> &Kept);
+ };
+}
+
+ReducePassList::TestResult
+ReducePassList::doTest(std::vector<const PassInfo*> &Prefix,
+ std::vector<const PassInfo*> &Suffix) {
+ sys::Path PrefixOutput;
+ Module *OrigProgram = 0;
+ if (!Prefix.empty()) {
+ std::cout << "Checking to see if these passes crash: "
+ << getPassesString(Prefix) << ": ";
+ std::string PfxOutput;
+ if (BD.runPasses(Prefix, PfxOutput))
+ return KeepPrefix;
+
+ PrefixOutput.set(PfxOutput);
+ OrigProgram = BD.Program;
+
+ BD.Program = ParseInputFile(PrefixOutput.toString());
+ if (BD.Program == 0) {
+ std::cerr << BD.getToolName() << ": Error reading bitcode file '"
+ << PrefixOutput << "'!\n";
+ exit(1);
+ }
+ PrefixOutput.eraseFromDisk();
+ }
+
+ std::cout << "Checking to see if these passes crash: "
+ << getPassesString(Suffix) << ": ";
+
+ if (BD.runPasses(Suffix)) {
+ delete OrigProgram; // The suffix crashes alone...
+ return KeepSuffix;
+ }
+
+ // Nothing failed, restore state...
+ if (OrigProgram) {
+ delete BD.Program;
+ BD.Program = OrigProgram;
+ }
+ return NoFailure;
+}
+
+namespace {
+ /// ReduceCrashingGlobalVariables - This works by removing the global
+ /// variable's initializer and seeing if the program still crashes. If it
+ /// does, then we keep that program and try again.
+ ///
+ class ReduceCrashingGlobalVariables : public ListReducer<GlobalVariable*> {
+ BugDriver &BD;
+ bool (*TestFn)(BugDriver &, Module *);
+ public:
+ ReduceCrashingGlobalVariables(BugDriver &bd,
+ bool (*testFn)(BugDriver&, Module*))
+ : BD(bd), TestFn(testFn) {}
+
+ virtual TestResult doTest(std::vector<GlobalVariable*>& Prefix,
+ std::vector<GlobalVariable*>& Kept) {
+ if (!Kept.empty() && TestGlobalVariables(Kept))
+ return KeepSuffix;
+
+ if (!Prefix.empty() && TestGlobalVariables(Prefix))
+ return KeepPrefix;
+
+ return NoFailure;
+ }
+
+ bool TestGlobalVariables(std::vector<GlobalVariable*>& GVs);
+ };
+}
+
+bool
+ReduceCrashingGlobalVariables::TestGlobalVariables(
+ std::vector<GlobalVariable*>& GVs) {
+ // Clone the program to try hacking it apart...
+ Module *M = CloneModule(BD.getProgram());
+
+ // Convert list to set for fast lookup...
+ std::set<GlobalVariable*> GVSet;
+
+ for (unsigned i = 0, e = GVs.size(); i != e; ++i) {
+ GlobalVariable* CMGV = M->getNamedGlobal(GVs[i]->getName());
+ assert(CMGV && "Global Variable not in module?!");
+ GVSet.insert(CMGV);
+ }
+
+ std::cout << "Checking for crash with only these global variables: ";
+ PrintGlobalVariableList(GVs);
+ std::cout << ": ";
+
+ // Loop over and delete any global variables which we aren't supposed to be
+ // playing with...
+ for (Module::global_iterator I = M->global_begin(), E = M->global_end();
+ I != E; ++I)
+ if (I->hasInitializer()) {
+ I->setInitializer(0);
+ I->setLinkage(GlobalValue::ExternalLinkage);
+ }
+
+ // Try running the hacked up program...
+ if (TestFn(BD, M)) {
+ BD.setNewProgram(M); // It crashed, keep the trimmed version...
+
+ // Make sure to use global variable pointers that point into the now-current
+ // module.
+ GVs.assign(GVSet.begin(), GVSet.end());
+ return true;
+ }
+
+ delete M;
+ return false;
+}
+
+namespace llvm {
+ /// ReduceCrashingFunctions reducer - This works by removing functions and
+ /// seeing if the program still crashes. If it does, then keep the newer,
+ /// smaller program.
+ ///
+ class ReduceCrashingFunctions : public ListReducer<Function*> {
+ BugDriver &BD;
+ bool (*TestFn)(BugDriver &, Module *);
+ public:
+ ReduceCrashingFunctions(BugDriver &bd,
+ bool (*testFn)(BugDriver &, Module *))
+ : BD(bd), TestFn(testFn) {}
+
+ virtual TestResult doTest(std::vector<Function*> &Prefix,
+ std::vector<Function*> &Kept) {
+ if (!Kept.empty() && TestFuncs(Kept))
+ return KeepSuffix;
+ if (!Prefix.empty() && TestFuncs(Prefix))
+ return KeepPrefix;
+ return NoFailure;
+ }
+
+ bool TestFuncs(std::vector<Function*> &Prefix);
+ };
+}
+
+bool ReduceCrashingFunctions::TestFuncs(std::vector<Function*> &Funcs) {
+
+ //if main isn't present, claim there is no problem
+ if (KeepMain && find(Funcs.begin(), Funcs.end(),
+ BD.getProgram()->getFunction("main")) == Funcs.end())
+ return false;
+
+ // Clone the program to try hacking it apart...
+ Module *M = CloneModule(BD.getProgram());
+
+ // Convert list to set for fast lookup...
+ std::set<Function*> Functions;
+ for (unsigned i = 0, e = Funcs.size(); i != e; ++i) {
+ // FIXME: bugpoint should add names to all stripped symbols.
+ assert(!Funcs[i]->getName().empty() &&
+ "Bugpoint doesn't work on stripped modules yet PR718!");
+ Function *CMF = M->getFunction(Funcs[i]->getName());
+ assert(CMF && "Function not in module?!");
+ assert(CMF->getFunctionType() == Funcs[i]->getFunctionType() && "wrong ty");
+ Functions.insert(CMF);
+ }
+
+ std::cout << "Checking for crash with only these functions: ";
+ PrintFunctionList(Funcs);
+ std::cout << ": ";
+
+ // Loop over and delete any functions which we aren't supposed to be playing
+ // with...
+ for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
+ if (!I->isDeclaration() && !Functions.count(I))
+ DeleteFunctionBody(I);
+
+ // Try running the hacked up program...
+ if (TestFn(BD, M)) {
+ BD.setNewProgram(M); // It crashed, keep the trimmed version...
+
+ // Make sure to use function pointers that point into the now-current
+ // module.
+ Funcs.assign(Functions.begin(), Functions.end());
+ return true;
+ }
+ delete M;
+ return false;
+}
+
+
+namespace {
+ /// ReduceCrashingBlocks reducer - This works by setting the terminators of
+ /// all terminators except the specified basic blocks to a 'ret' instruction,
+ /// then running the simplify-cfg pass. This has the effect of chopping up
+ /// the CFG really fast which can reduce large functions quickly.
+ ///
+ class ReduceCrashingBlocks : public ListReducer<const BasicBlock*> {
+ BugDriver &BD;
+ bool (*TestFn)(BugDriver &, Module *);
+ public:
+ ReduceCrashingBlocks(BugDriver &bd, bool (*testFn)(BugDriver &, Module *))
+ : BD(bd), TestFn(testFn) {}
+
+ virtual TestResult doTest(std::vector<const BasicBlock*> &Prefix,
+ std::vector<const BasicBlock*> &Kept) {
+ if (!Kept.empty() && TestBlocks(Kept))
+ return KeepSuffix;
+ if (!Prefix.empty() && TestBlocks(Prefix))
+ return KeepPrefix;
+ return NoFailure;
+ }
+
+ bool TestBlocks(std::vector<const BasicBlock*> &Prefix);
+ };
+}
+
+bool ReduceCrashingBlocks::TestBlocks(std::vector<const BasicBlock*> &BBs) {
+ // Clone the program to try hacking it apart...
+ Module *M = CloneModule(BD.getProgram());
+
+ // Convert list to set for fast lookup...
+ std::set<BasicBlock*> Blocks;
+ for (unsigned i = 0, e = BBs.size(); i != e; ++i) {
+ // Convert the basic block from the original module to the new module...
+ const Function *F = BBs[i]->getParent();
+ Function *CMF = M->getFunction(F->getName());
+ assert(CMF && "Function not in module?!");
+ assert(CMF->getFunctionType() == F->getFunctionType() && "wrong type?");
+
+ // Get the mapped basic block...
+ Function::iterator CBI = CMF->begin();
+ std::advance(CBI, std::distance(F->begin(),
+ Function::const_iterator(BBs[i])));
+ Blocks.insert(CBI);
+ }
+
+ std::cout << "Checking for crash with only these blocks:";
+ unsigned NumPrint = Blocks.size();
+ if (NumPrint > 10) NumPrint = 10;
+ for (unsigned i = 0, e = NumPrint; i != e; ++i)
+ std::cout << " " << BBs[i]->getName();
+ if (NumPrint < Blocks.size())
+ std::cout << "... <" << Blocks.size() << " total>";
+ std::cout << ": ";
+
+ // Loop over and delete any hack up any blocks that are not listed...
+ for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
+ for (Function::iterator BB = I->begin(), E = I->end(); BB != E; ++BB)
+ if (!Blocks.count(BB) && BB->getTerminator()->getNumSuccessors()) {
+ // Loop over all of the successors of this block, deleting any PHI nodes
+ // that might include it.
+ for (succ_iterator SI = succ_begin(BB), E = succ_end(BB); SI != E; ++SI)
+ (*SI)->removePredecessor(BB);
+
+ if (BB->getTerminator()->getType() != Type::VoidTy)
+ BB->getTerminator()->replaceAllUsesWith(
+ Constant::getNullValue(BB->getTerminator()->getType()));
+
+ // Delete the old terminator instruction...
+ BB->getInstList().pop_back();
+
+ // Add a new return instruction of the appropriate type...
+ const Type *RetTy = BB->getParent()->getReturnType();
+ new ReturnInst(RetTy == Type::VoidTy ? 0 :
+ Constant::getNullValue(RetTy), BB);
+ }
+
+ // The CFG Simplifier pass may delete one of the basic blocks we are
+ // interested in. If it does we need to take the block out of the list. Make
+ // a "persistent mapping" by turning basic blocks into <function, name> pairs.
+ // This won't work well if blocks are unnamed, but that is just the risk we
+ // have to take.
+ std::vector<std::pair<Function*, std::string> > BlockInfo;
+
+ for (std::set<BasicBlock*>::iterator I = Blocks.begin(), E = Blocks.end();
+ I != E; ++I)
+ BlockInfo.push_back(std::make_pair((*I)->getParent(), (*I)->getName()));
+
+ // Now run the CFG simplify pass on the function...
+ PassManager Passes;
+ Passes.add(createCFGSimplificationPass());
+ Passes.add(createVerifierPass());
+ Passes.run(*M);
+
+ // Try running on the hacked up program...
+ if (TestFn(BD, M)) {
+ BD.setNewProgram(M); // It crashed, keep the trimmed version...
+
+ // Make sure to use basic block pointers that point into the now-current
+ // module, and that they don't include any deleted blocks.
+ BBs.clear();
+ for (unsigned i = 0, e = BlockInfo.size(); i != e; ++i) {
+ ValueSymbolTable &ST = BlockInfo[i].first->getValueSymbolTable();
+ Value* V = ST.lookup(BlockInfo[i].second);
+ if (V && V->getType() == Type::LabelTy)
+ BBs.push_back(cast<BasicBlock>(V));
+ }
+ return true;
+ }
+ delete M; // It didn't crash, try something else.
+ return false;
+}
+
+/// DebugACrash - Given a predicate that determines whether a component crashes
+/// on a program, try to destructively reduce the program while still keeping
+/// the predicate true.
+static bool DebugACrash(BugDriver &BD, bool (*TestFn)(BugDriver &, Module *)) {
+ // See if we can get away with nuking some of the global variable initializers
+ // in the program...
+ if (BD.getProgram()->global_begin() != BD.getProgram()->global_end()) {
+ // Now try to reduce the number of global variable initializers in the
+ // module to something small.
+ Module *M = CloneModule(BD.getProgram());
+ bool DeletedInit = false;
+
+ for (Module::global_iterator I = M->global_begin(), E = M->global_end();
+ I != E; ++I)
+ if (I->hasInitializer()) {
+ I->setInitializer(0);
+ I->setLinkage(GlobalValue::ExternalLinkage);
+ DeletedInit = true;
+ }
+
+ if (!DeletedInit) {
+ delete M; // No change made...
+ } else {
+ // See if the program still causes a crash...
+ std::cout << "\nChecking to see if we can delete global inits: ";
+
+ if (TestFn(BD, M)) { // Still crashes?
+ BD.setNewProgram(M);
+ std::cout << "\n*** Able to remove all global initializers!\n";
+ } else { // No longer crashes?
+ std::cout << " - Removing all global inits hides problem!\n";
+ delete M;
+
+ std::vector<GlobalVariable*> GVs;
+
+ for (Module::global_iterator I = BD.getProgram()->global_begin(),
+ E = BD.getProgram()->global_end(); I != E; ++I)
+ if (I->hasInitializer())
+ GVs.push_back(I);
+
+ if (GVs.size() > 1 && !BugpointIsInterrupted) {
+ std::cout << "\n*** Attempting to reduce the number of global "
+ << "variables in the testcase\n";
+
+ unsigned OldSize = GVs.size();
+ ReduceCrashingGlobalVariables(BD, TestFn).reduceList(GVs);
+
+ if (GVs.size() < OldSize)
+ BD.EmitProgressBitcode("reduced-global-variables");
+ }
+ }
+ }
+ }
+
+ // Now try to reduce the number of functions in the module to something small.
+ std::vector<Function*> Functions;
+ for (Module::iterator I = BD.getProgram()->begin(),
+ E = BD.getProgram()->end(); I != E; ++I)
+ if (!I->isDeclaration())
+ Functions.push_back(I);
+
+ if (Functions.size() > 1 && !BugpointIsInterrupted) {
+ std::cout << "\n*** Attempting to reduce the number of functions "
+ "in the testcase\n";
+
+ unsigned OldSize = Functions.size();
+ ReduceCrashingFunctions(BD, TestFn).reduceList(Functions);
+
+ if (Functions.size() < OldSize)
+ BD.EmitProgressBitcode("reduced-function");
+ }
+
+ // Attempt to delete entire basic blocks at a time to speed up
+ // convergence... this actually works by setting the terminator of the blocks
+ // to a return instruction then running simplifycfg, which can potentially
+ // shrinks the code dramatically quickly
+ //
+ if (!DisableSimplifyCFG && !BugpointIsInterrupted) {
+ std::vector<const BasicBlock*> Blocks;
+ for (Module::const_iterator I = BD.getProgram()->begin(),
+ E = BD.getProgram()->end(); I != E; ++I)
+ for (Function::const_iterator FI = I->begin(), E = I->end(); FI !=E; ++FI)
+ Blocks.push_back(FI);
+ ReduceCrashingBlocks(BD, TestFn).reduceList(Blocks);
+ }
+
+ // FIXME: This should use the list reducer to converge faster by deleting
+ // larger chunks of instructions at a time!
+ unsigned Simplification = 2;
+ do {
+ if (BugpointIsInterrupted) break;
+ --Simplification;
+ std::cout << "\n*** Attempting to reduce testcase by deleting instruc"
+ << "tions: Simplification Level #" << Simplification << '\n';
+
+ // Now that we have deleted the functions that are unnecessary for the
+ // program, try to remove instructions that are not necessary to cause the
+ // crash. To do this, we loop through all of the instructions in the
+ // remaining functions, deleting them (replacing any values produced with
+ // nulls), and then running ADCE and SimplifyCFG. If the transformed input
+ // still triggers failure, keep deleting until we cannot trigger failure
+ // anymore.
+ //
+ unsigned InstructionsToSkipBeforeDeleting = 0;
+ TryAgain:
+
+ // Loop over all of the (non-terminator) instructions remaining in the
+ // function, attempting to delete them.
+ unsigned CurInstructionNum = 0;
+ for (Module::const_iterator FI = BD.getProgram()->begin(),
+ E = BD.getProgram()->end(); FI != E; ++FI)
+ if (!FI->isDeclaration())
+ for (Function::const_iterator BI = FI->begin(), E = FI->end(); BI != E;
+ ++BI)
+ for (BasicBlock::const_iterator I = BI->begin(), E = --BI->end();
+ I != E; ++I, ++CurInstructionNum)
+ if (InstructionsToSkipBeforeDeleting) {
+ --InstructionsToSkipBeforeDeleting;
+ } else {
+ if (BugpointIsInterrupted) goto ExitLoops;
+
+ std::cout << "Checking instruction '" << I->getName() << "': ";
+ Module *M = BD.deleteInstructionFromProgram(I, Simplification);
+
+ // Find out if the pass still crashes on this pass...
+ if (TestFn(BD, M)) {
+ // Yup, it does, we delete the old module, and continue trying
+ // to reduce the testcase...
+ BD.setNewProgram(M);
+ InstructionsToSkipBeforeDeleting = CurInstructionNum;
+ goto TryAgain; // I wish I had a multi-level break here!
+ }
+
+ // This pass didn't crash without this instruction, try the next
+ // one.
+ delete M;
+ }
+
+ if (InstructionsToSkipBeforeDeleting) {
+ InstructionsToSkipBeforeDeleting = 0;
+ goto TryAgain;
+ }
+
+ } while (Simplification);
+ExitLoops:
+
+ // Try to clean up the testcase by running funcresolve and globaldce...
+ if (!BugpointIsInterrupted) {
+ std::cout << "\n*** Attempting to perform final cleanups: ";
+ Module *M = CloneModule(BD.getProgram());
+ M = BD.performFinalCleanups(M, true);
+
+ // Find out if the pass still crashes on the cleaned up program...
+ if (TestFn(BD, M)) {
+ BD.setNewProgram(M); // Yup, it does, keep the reduced version...
+ } else {
+ delete M;
+ }
+ }
+
+ BD.EmitProgressBitcode("reduced-simplified");
+
+ return false;
+}
+
+static bool TestForOptimizerCrash(BugDriver &BD, Module *M) {
+ return BD.runPasses(M);
+}
+
+/// debugOptimizerCrash - This method is called when some pass crashes on input.
+/// It attempts to prune down the testcase to something reasonable, and figure
+/// out exactly which pass is crashing.
+///
+bool BugDriver::debugOptimizerCrash(const std::string &ID) {
+ std::cout << "\n*** Debugging optimizer crash!\n";
+
+ // Reduce the list of passes which causes the optimizer to crash...
+ if (!BugpointIsInterrupted)
+ ReducePassList(*this).reduceList(PassesToRun);
+
+ std::cout << "\n*** Found crashing pass"
+ << (PassesToRun.size() == 1 ? ": " : "es: ")
+ << getPassesString(PassesToRun) << '\n';
+
+ EmitProgressBitcode(ID);
+
+ return DebugACrash(*this, TestForOptimizerCrash);
+}
+
+static bool TestForCodeGenCrash(BugDriver &BD, Module *M) {
+ try {
+ std::cerr << '\n';
+ BD.compileProgram(M);
+ std::cerr << '\n';
+ return false;
+ } catch (ToolExecutionError &) {
+ std::cerr << "<crash>\n";
+ return true; // Tool is still crashing.
+ }
+}
+
+/// debugCodeGeneratorCrash - This method is called when the code generator
+/// crashes on an input. It attempts to reduce the input as much as possible
+/// while still causing the code generator to crash.
+bool BugDriver::debugCodeGeneratorCrash() {
+ std::cerr << "*** Debugging code generator crash!\n";
+
+ return DebugACrash(*this, TestForCodeGenCrash);
+}
diff --git a/tools/bugpoint/ExecutionDriver.cpp b/tools/bugpoint/ExecutionDriver.cpp
new file mode 100644
index 0000000..395ac2f
--- /dev/null
+++ b/tools/bugpoint/ExecutionDriver.cpp
@@ -0,0 +1,404 @@
+//===- ExecutionDriver.cpp - Allow execution of LLVM program --------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains code used to execute the program utilizing one of the
+// various ways of running LLVM bitcode.
+//
+//===----------------------------------------------------------------------===//
+
+#include "BugDriver.h"
+#include "ToolRunner.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/FileUtilities.h"
+#include "llvm/Support/SystemUtils.h"
+#include <fstream>
+#include <iostream>
+
+using namespace llvm;
+
+namespace {
+ // OutputType - Allow the user to specify the way code should be run, to test
+ // for miscompilation.
+ //
+ enum OutputType {
+ AutoPick, RunLLI, RunJIT, RunLLC, RunCBE, CBE_bug, LLC_Safe
+ };
+
+ cl::opt<double>
+ AbsTolerance("abs-tolerance", cl::desc("Absolute error tolerated"),
+ cl::init(0.0));
+ cl::opt<double>
+ RelTolerance("rel-tolerance", cl::desc("Relative error tolerated"),
+ cl::init(0.0));
+
+ cl::opt<OutputType>
+ InterpreterSel(cl::desc("Specify how LLVM code should be executed:"),
+ cl::values(clEnumValN(AutoPick, "auto", "Use best guess"),
+ clEnumValN(RunLLI, "run-int",
+ "Execute with the interpreter"),
+ clEnumValN(RunJIT, "run-jit", "Execute with JIT"),
+ clEnumValN(RunLLC, "run-llc", "Compile with LLC"),
+ clEnumValN(RunCBE, "run-cbe", "Compile with CBE"),
+ clEnumValN(CBE_bug,"cbe-bug", "Find CBE bugs"),
+ clEnumValN(LLC_Safe, "llc-safe", "Use LLC for all"),
+ clEnumValEnd),
+ cl::init(AutoPick));
+
+ cl::opt<bool>
+ CheckProgramExitCode("check-exit-code",
+ cl::desc("Assume nonzero exit code is failure (default on)"),
+ cl::init(true));
+
+ cl::opt<bool>
+ AppendProgramExitCode("append-exit-code",
+ cl::desc("Append the exit code to the output so it gets diff'd too"),
+ cl::init(false));
+
+ cl::opt<std::string>
+ InputFile("input", cl::init("/dev/null"),
+ cl::desc("Filename to pipe in as stdin (default: /dev/null)"));
+
+ cl::list<std::string>
+ AdditionalSOs("additional-so",
+ cl::desc("Additional shared objects to load "
+ "into executing programs"));
+
+ cl::list<std::string>
+ AdditionalLinkerArgs("Xlinker",
+ cl::desc("Additional arguments to pass to the linker"));
+}
+
+namespace llvm {
+ // Anything specified after the --args option are taken as arguments to the
+ // program being debugged.
+ cl::list<std::string>
+ InputArgv("args", cl::Positional, cl::desc("<program arguments>..."),
+ cl::ZeroOrMore, cl::PositionalEatsArgs);
+
+ cl::list<std::string>
+ ToolArgv("tool-args", cl::Positional, cl::desc("<tool arguments>..."),
+ cl::ZeroOrMore, cl::PositionalEatsArgs);
+}
+
+//===----------------------------------------------------------------------===//
+// BugDriver method implementation
+//
+
+/// initializeExecutionEnvironment - This method is used to set up the
+/// environment for executing LLVM programs.
+///
+bool BugDriver::initializeExecutionEnvironment() {
+ std::cout << "Initializing execution environment: ";
+
+ // Create an instance of the AbstractInterpreter interface as specified on
+ // the command line
+ cbe = 0;
+ std::string Message;
+
+ switch (InterpreterSel) {
+ case AutoPick:
+ InterpreterSel = RunCBE;
+ Interpreter = cbe = AbstractInterpreter::createCBE(getToolName(), Message,
+ &ToolArgv);
+ if (!Interpreter) {
+ InterpreterSel = RunJIT;
+ Interpreter = AbstractInterpreter::createJIT(getToolName(), Message,
+ &ToolArgv);
+ }
+ if (!Interpreter) {
+ InterpreterSel = RunLLC;
+ Interpreter = AbstractInterpreter::createLLC(getToolName(), Message,
+ &ToolArgv);
+ }
+ if (!Interpreter) {
+ InterpreterSel = RunLLI;
+ Interpreter = AbstractInterpreter::createLLI(getToolName(), Message,
+ &ToolArgv);
+ }
+ if (!Interpreter) {
+ InterpreterSel = AutoPick;
+ Message = "Sorry, I can't automatically select an interpreter!\n";
+ }
+ break;
+ case RunLLI:
+ Interpreter = AbstractInterpreter::createLLI(getToolName(), Message,
+ &ToolArgv);
+ break;
+ case RunLLC:
+ Interpreter = AbstractInterpreter::createLLC(getToolName(), Message,
+ &ToolArgv);
+ break;
+ case RunJIT:
+ Interpreter = AbstractInterpreter::createJIT(getToolName(), Message,
+ &ToolArgv);
+ break;
+ case LLC_Safe:
+ Interpreter = AbstractInterpreter::createLLC(getToolName(), Message,
+ &ToolArgv);
+ break;
+ case RunCBE:
+ case CBE_bug:
+ Interpreter = AbstractInterpreter::createCBE(getToolName(), Message,
+ &ToolArgv);
+ break;
+ default:
+ Message = "Sorry, this back-end is not supported by bugpoint right now!\n";
+ break;
+ }
+ std::cerr << Message;
+
+ // Initialize auxiliary tools for debugging
+ if (InterpreterSel == RunCBE) {
+ // We already created a CBE, reuse it.
+ cbe = Interpreter;
+ } else if (InterpreterSel == CBE_bug || InterpreterSel == LLC_Safe) {
+ // We want to debug the CBE itself or LLC is known-good. Use LLC as the
+ // 'known-good' compiler.
+ std::vector<std::string> ToolArgs;
+ ToolArgs.push_back("--relocation-model=pic");
+ cbe = AbstractInterpreter::createLLC(getToolName(), Message, &ToolArgs);
+ } else {
+ cbe = AbstractInterpreter::createCBE(getToolName(), Message, &ToolArgv);
+ }
+ if (!cbe) { std::cout << Message << "\nExiting.\n"; exit(1); }
+
+ gcc = GCC::create(getToolName(), Message);
+ if (!gcc) { std::cout << Message << "\nExiting.\n"; exit(1); }
+
+ // If there was an error creating the selected interpreter, quit with error.
+ return Interpreter == 0;
+}
+
+/// compileProgram - Try to compile the specified module, throwing an exception
+/// if an error occurs, or returning normally if not. This is used for code
+/// generation crash testing.
+///
+void BugDriver::compileProgram(Module *M) {
+ // Emit the program to a bitcode file...
+ sys::Path BitcodeFile ("bugpoint-test-program.bc");
+ std::string ErrMsg;
+ if (BitcodeFile.makeUnique(true,&ErrMsg)) {
+ std::cerr << ToolName << ": Error making unique filename: " << ErrMsg
+ << "\n";
+ exit(1);
+ }
+ if (writeProgramToFile(BitcodeFile.toString(), M)) {
+ std::cerr << ToolName << ": Error emitting bitcode to file '"
+ << BitcodeFile << "'!\n";
+ exit(1);
+ }
+
+ // Remove the temporary bitcode file when we are done.
+ FileRemover BitcodeFileRemover(BitcodeFile);
+
+ // Actually compile the program!
+ Interpreter->compileProgram(BitcodeFile.toString());
+}
+
+
+/// executeProgram - This method runs "Program", capturing the output of the
+/// program to a file, returning the filename of the file. A recommended
+/// filename may be optionally specified.
+///
+std::string BugDriver::executeProgram(std::string OutputFile,
+ std::string BitcodeFile,
+ const std::string &SharedObj,
+ AbstractInterpreter *AI,
+ bool *ProgramExitedNonzero) {
+ if (AI == 0) AI = Interpreter;
+ assert(AI && "Interpreter should have been created already!");
+ bool CreatedBitcode = false;
+ std::string ErrMsg;
+ if (BitcodeFile.empty()) {
+ // Emit the program to a bitcode file...
+ sys::Path uniqueFilename("bugpoint-test-program.bc");
+ if (uniqueFilename.makeUnique(true, &ErrMsg)) {
+ std::cerr << ToolName << ": Error making unique filename: "
+ << ErrMsg << "!\n";
+ exit(1);
+ }
+ BitcodeFile = uniqueFilename.toString();
+
+ if (writeProgramToFile(BitcodeFile, Program)) {
+ std::cerr << ToolName << ": Error emitting bitcode to file '"
+ << BitcodeFile << "'!\n";
+ exit(1);
+ }
+ CreatedBitcode = true;
+ }
+
+ // Remove the temporary bitcode file when we are done.
+ sys::Path BitcodePath (BitcodeFile);
+ FileRemover BitcodeFileRemover(BitcodePath, CreatedBitcode);
+
+ if (OutputFile.empty()) OutputFile = "bugpoint-execution-output";
+
+ // Check to see if this is a valid output filename...
+ sys::Path uniqueFile(OutputFile);
+ if (uniqueFile.makeUnique(true, &ErrMsg)) {
+ std::cerr << ToolName << ": Error making unique filename: "
+ << ErrMsg << "\n";
+ exit(1);
+ }
+ OutputFile = uniqueFile.toString();
+
+ // Figure out which shared objects to run, if any.
+ std::vector<std::string> SharedObjs(AdditionalSOs);
+ if (!SharedObj.empty())
+ SharedObjs.push_back(SharedObj);
+
+
+ // If this is an LLC or CBE run, then the GCC compiler might get run to
+ // compile the program. If so, we should pass the user's -Xlinker options
+ // as the GCCArgs.
+ int RetVal = 0;
+ if (InterpreterSel == RunLLC || InterpreterSel == RunCBE ||
+ InterpreterSel == CBE_bug || InterpreterSel == LLC_Safe)
+ RetVal = AI->ExecuteProgram(BitcodeFile, InputArgv, InputFile,
+ OutputFile, AdditionalLinkerArgs, SharedObjs,
+ Timeout, MemoryLimit);
+ else
+ RetVal = AI->ExecuteProgram(BitcodeFile, InputArgv, InputFile,
+ OutputFile, std::vector<std::string>(),
+ SharedObjs, Timeout, MemoryLimit);
+
+ if (RetVal == -1) {
+ std::cerr << "<timeout>";
+ static bool FirstTimeout = true;
+ if (FirstTimeout) {
+ std::cout << "\n"
+ "*** Program execution timed out! This mechanism is designed to handle\n"
+ " programs stuck in infinite loops gracefully. The -timeout option\n"
+ " can be used to change the timeout threshold or disable it completely\n"
+ " (with -timeout=0). This message is only displayed once.\n";
+ FirstTimeout = false;
+ }
+ }
+
+ if (AppendProgramExitCode) {
+ std::ofstream outFile(OutputFile.c_str(), std::ios_base::app);
+ outFile << "exit " << RetVal << '\n';
+ outFile.close();
+ }
+
+ if (ProgramExitedNonzero != 0)
+ *ProgramExitedNonzero = (RetVal != 0);
+
+ // Return the filename we captured the output to.
+ return OutputFile;
+}
+
+/// executeProgramWithCBE - Used to create reference output with the C
+/// backend, if reference output is not provided.
+///
+std::string BugDriver::executeProgramWithCBE(std::string OutputFile) {
+ bool ProgramExitedNonzero;
+ std::string outFN = executeProgram(OutputFile, "", "", cbe,
+ &ProgramExitedNonzero);
+ if (ProgramExitedNonzero) {
+ std::cerr
+ << "Warning: While generating reference output, program exited with\n"
+ << "non-zero exit code. This will NOT be treated as a failure.\n";
+ CheckProgramExitCode = false;
+ }
+ return outFN;
+}
+
+std::string BugDriver::compileSharedObject(const std::string &BitcodeFile) {
+ assert(Interpreter && "Interpreter should have been created already!");
+ sys::Path OutputFile;
+
+ // Using CBE
+ GCC::FileType FT = cbe->OutputCode(BitcodeFile, OutputFile);
+
+ std::string SharedObjectFile;
+ if (gcc->MakeSharedObject(OutputFile.toString(), FT,
+ SharedObjectFile, AdditionalLinkerArgs))
+ exit(1);
+
+ // Remove the intermediate C file
+ OutputFile.eraseFromDisk();
+
+ return "./" + SharedObjectFile;
+}
+
+/// createReferenceFile - calls compileProgram and then records the output
+/// into ReferenceOutputFile. Returns true if reference file created, false
+/// otherwise. Note: initializeExecutionEnvironment should be called BEFORE
+/// this function.
+///
+bool BugDriver::createReferenceFile(Module *M, const std::string &Filename) {
+ try {
+ compileProgram(Program);
+ } catch (ToolExecutionError &) {
+ return false;
+ }
+ try {
+ ReferenceOutputFile = executeProgramWithCBE(Filename);
+ std::cout << "Reference output is: " << ReferenceOutputFile << "\n\n";
+ } catch (ToolExecutionError &TEE) {
+ std::cerr << TEE.what();
+ if (Interpreter != cbe) {
+ std::cerr << "*** There is a bug running the C backend. Either debug"
+ << " it (use the -run-cbe bugpoint option), or fix the error"
+ << " some other way.\n";
+ }
+ return false;
+ }
+ return true;
+}
+
+/// diffProgram - This method executes the specified module and diffs the
+/// output against the file specified by ReferenceOutputFile. If the output
+/// is different, true is returned. If there is a problem with the code
+/// generator (e.g., llc crashes), this will throw an exception.
+///
+bool BugDriver::diffProgram(const std::string &BitcodeFile,
+ const std::string &SharedObject,
+ bool RemoveBitcode) {
+ bool ProgramExitedNonzero;
+
+ // Execute the program, generating an output file...
+ sys::Path Output(executeProgram("", BitcodeFile, SharedObject, 0,
+ &ProgramExitedNonzero));
+
+ // If we're checking the program exit code, assume anything nonzero is bad.
+ if (CheckProgramExitCode && ProgramExitedNonzero) {
+ Output.eraseFromDisk();
+ if (RemoveBitcode)
+ sys::Path(BitcodeFile).eraseFromDisk();
+ return true;
+ }
+
+ std::string Error;
+ bool FilesDifferent = false;
+ if (int Diff = DiffFilesWithTolerance(sys::Path(ReferenceOutputFile),
+ sys::Path(Output.toString()),
+ AbsTolerance, RelTolerance, &Error)) {
+ if (Diff == 2) {
+ std::cerr << "While diffing output: " << Error << '\n';
+ exit(1);
+ }
+ FilesDifferent = true;
+ }
+
+ // Remove the generated output.
+ Output.eraseFromDisk();
+
+ // Remove the bitcode file if we are supposed to.
+ if (RemoveBitcode)
+ sys::Path(BitcodeFile).eraseFromDisk();
+ return FilesDifferent;
+}
+
+bool BugDriver::isExecutingJIT() {
+ return InterpreterSel == RunJIT;
+}
+
diff --git a/tools/bugpoint/ExtractFunction.cpp b/tools/bugpoint/ExtractFunction.cpp
new file mode 100644
index 0000000..31f7fa4
--- /dev/null
+++ b/tools/bugpoint/ExtractFunction.cpp
@@ -0,0 +1,368 @@
+//===- ExtractFunction.cpp - Extract a function from Program --------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements several methods that are used to extract functions,
+// loops, or portions of a module from the rest of the module.
+//
+//===----------------------------------------------------------------------===//
+
+#include "BugDriver.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Module.h"
+#include "llvm/PassManager.h"
+#include "llvm/Pass.h"
+#include "llvm/Analysis/Verifier.h"
+#include "llvm/Transforms/IPO.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Utils/Cloning.h"
+#include "llvm/Transforms/Utils/FunctionUtils.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/FileUtilities.h"
+#include <set>
+#include <iostream>
+using namespace llvm;
+
+namespace llvm {
+ bool DisableSimplifyCFG = false;
+} // End llvm namespace
+
+namespace {
+ cl::opt<bool>
+ NoDCE ("disable-dce",
+ cl::desc("Do not use the -dce pass to reduce testcases"));
+ cl::opt<bool, true>
+ NoSCFG("disable-simplifycfg", cl::location(DisableSimplifyCFG),
+ cl::desc("Do not use the -simplifycfg pass to reduce testcases"));
+}
+
+/// deleteInstructionFromProgram - This method clones the current Program and
+/// deletes the specified instruction from the cloned module. It then runs a
+/// series of cleanup passes (ADCE and SimplifyCFG) to eliminate any code which
+/// depends on the value. The modified module is then returned.
+///
+Module *BugDriver::deleteInstructionFromProgram(const Instruction *I,
+ unsigned Simplification) const {
+ Module *Result = CloneModule(Program);
+
+ const BasicBlock *PBB = I->getParent();
+ const Function *PF = PBB->getParent();
+
+ Module::iterator RFI = Result->begin(); // Get iterator to corresponding fn
+ std::advance(RFI, std::distance(PF->getParent()->begin(),
+ Module::const_iterator(PF)));
+
+ Function::iterator RBI = RFI->begin(); // Get iterator to corresponding BB
+ std::advance(RBI, std::distance(PF->begin(), Function::const_iterator(PBB)));
+
+ BasicBlock::iterator RI = RBI->begin(); // Get iterator to corresponding inst
+ std::advance(RI, std::distance(PBB->begin(), BasicBlock::const_iterator(I)));
+ Instruction *TheInst = RI; // Got the corresponding instruction!
+
+ // If this instruction produces a value, replace any users with null values
+ if (TheInst->getType() != Type::VoidTy)
+ TheInst->replaceAllUsesWith(Constant::getNullValue(TheInst->getType()));
+
+ // Remove the instruction from the program.
+ TheInst->getParent()->getInstList().erase(TheInst);
+
+
+ //writeProgramToFile("current.bc", Result);
+
+ // Spiff up the output a little bit.
+ PassManager Passes;
+ // Make sure that the appropriate target data is always used...
+ Passes.add(new TargetData(Result));
+
+ /// FIXME: If this used runPasses() like the methods below, we could get rid
+ /// of the -disable-* options!
+ if (Simplification > 1 && !NoDCE)
+ Passes.add(createDeadCodeEliminationPass());
+ if (Simplification && !DisableSimplifyCFG)
+ Passes.add(createCFGSimplificationPass()); // Delete dead control flow
+
+ Passes.add(createVerifierPass());
+ Passes.run(*Result);
+ return Result;
+}
+
+static const PassInfo *getPI(Pass *P) {
+ const PassInfo *PI = P->getPassInfo();
+ delete P;
+ return PI;
+}
+
+/// performFinalCleanups - This method clones the current Program and performs
+/// a series of cleanups intended to get rid of extra cruft on the module
+/// before handing it to the user.
+///
+Module *BugDriver::performFinalCleanups(Module *M, bool MayModifySemantics) {
+ // Make all functions external, so GlobalDCE doesn't delete them...
+ for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
+ I->setLinkage(GlobalValue::ExternalLinkage);
+
+ std::vector<const PassInfo*> CleanupPasses;
+ CleanupPasses.push_back(getPI(createGlobalDCEPass()));
+ CleanupPasses.push_back(getPI(createDeadTypeEliminationPass()));
+
+ if (MayModifySemantics)
+ CleanupPasses.push_back(getPI(createDeadArgHackingPass()));
+ else
+ CleanupPasses.push_back(getPI(createDeadArgEliminationPass()));
+
+ Module *New = runPassesOn(M, CleanupPasses);
+ if (New == 0) {
+ std::cerr << "Final cleanups failed. Sorry. :( Please report a bug!\n";
+ return M;
+ }
+ delete M;
+ return New;
+}
+
+
+/// ExtractLoop - Given a module, extract up to one loop from it into a new
+/// function. This returns null if there are no extractable loops in the
+/// program or if the loop extractor crashes.
+Module *BugDriver::ExtractLoop(Module *M) {
+ std::vector<const PassInfo*> LoopExtractPasses;
+ LoopExtractPasses.push_back(getPI(createSingleLoopExtractorPass()));
+
+ Module *NewM = runPassesOn(M, LoopExtractPasses);
+ if (NewM == 0) {
+ Module *Old = swapProgramIn(M);
+ std::cout << "*** Loop extraction failed: ";
+ EmitProgressBitcode("loopextraction", true);
+ std::cout << "*** Sorry. :( Please report a bug!\n";
+ swapProgramIn(Old);
+ return 0;
+ }
+
+ // Check to see if we created any new functions. If not, no loops were
+ // extracted and we should return null. Limit the number of loops we extract
+ // to avoid taking forever.
+ static unsigned NumExtracted = 32;
+ if (M->size() == NewM->size() || --NumExtracted == 0) {
+ delete NewM;
+ return 0;
+ } else {
+ assert(M->size() < NewM->size() && "Loop extract removed functions?");
+ Module::iterator MI = NewM->begin();
+ for (unsigned i = 0, e = M->size(); i != e; ++i)
+ ++MI;
+ }
+
+ return NewM;
+}
+
+
+// DeleteFunctionBody - "Remove" the function by deleting all of its basic
+// blocks, making it external.
+//
+void llvm::DeleteFunctionBody(Function *F) {
+ // delete the body of the function...
+ F->deleteBody();
+ assert(F->isDeclaration() && "This didn't make the function external!");
+}
+
+/// GetTorInit - Given a list of entries for static ctors/dtors, return them
+/// as a constant array.
+static Constant *GetTorInit(std::vector<std::pair<Function*, int> > &TorList) {
+ assert(!TorList.empty() && "Don't create empty tor list!");
+ std::vector<Constant*> ArrayElts;
+ for (unsigned i = 0, e = TorList.size(); i != e; ++i) {
+ std::vector<Constant*> Elts;
+ Elts.push_back(ConstantInt::get(Type::Int32Ty, TorList[i].second));
+ Elts.push_back(TorList[i].first);
+ ArrayElts.push_back(ConstantStruct::get(Elts));
+ }
+ return ConstantArray::get(ArrayType::get(ArrayElts[0]->getType(),
+ ArrayElts.size()),
+ ArrayElts);
+}
+
+/// SplitStaticCtorDtor - A module was recently split into two parts, M1/M2, and
+/// M1 has all of the global variables. If M2 contains any functions that are
+/// static ctors/dtors, we need to add an llvm.global_[cd]tors global to M2, and
+/// prune appropriate entries out of M1s list.
+static void SplitStaticCtorDtor(const char *GlobalName, Module *M1, Module *M2){
+ GlobalVariable *GV = M1->getNamedGlobal(GlobalName);
+ if (!GV || GV->isDeclaration() || GV->hasInternalLinkage() ||
+ !GV->use_empty()) return;
+
+ std::vector<std::pair<Function*, int> > M1Tors, M2Tors;
+ ConstantArray *InitList = dyn_cast<ConstantArray>(GV->getInitializer());
+ if (!InitList) return;
+
+ for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {
+ if (ConstantStruct *CS = dyn_cast<ConstantStruct>(InitList->getOperand(i))){
+ if (CS->getNumOperands() != 2) return; // Not array of 2-element structs.
+
+ if (CS->getOperand(1)->isNullValue())
+ break; // Found a null terminator, stop here.
+
+ ConstantInt *CI = dyn_cast<ConstantInt>(CS->getOperand(0));
+ int Priority = CI ? CI->getSExtValue() : 0;
+
+ Constant *FP = CS->getOperand(1);
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(FP))
+ if (CE->isCast())
+ FP = CE->getOperand(0);
+ if (Function *F = dyn_cast<Function>(FP)) {
+ if (!F->isDeclaration())
+ M1Tors.push_back(std::make_pair(F, Priority));
+ else {
+ // Map to M2's version of the function.
+ F = M2->getFunction(F->getName());
+ M2Tors.push_back(std::make_pair(F, Priority));
+ }
+ }
+ }
+ }
+
+ GV->eraseFromParent();
+ if (!M1Tors.empty()) {
+ Constant *M1Init = GetTorInit(M1Tors);
+ new GlobalVariable(M1Init->getType(), false, GlobalValue::AppendingLinkage,
+ M1Init, GlobalName, M1);
+ }
+
+ GV = M2->getNamedGlobal(GlobalName);
+ assert(GV && "Not a clone of M1?");
+ assert(GV->use_empty() && "llvm.ctors shouldn't have uses!");
+
+ GV->eraseFromParent();
+ if (!M2Tors.empty()) {
+ Constant *M2Init = GetTorInit(M2Tors);
+ new GlobalVariable(M2Init->getType(), false, GlobalValue::AppendingLinkage,
+ M2Init, GlobalName, M2);
+ }
+}
+
+
+/// SplitFunctionsOutOfModule - Given a module and a list of functions in the
+/// module, split the functions OUT of the specified module, and place them in
+/// the new module.
+Module *llvm::SplitFunctionsOutOfModule(Module *M,
+ const std::vector<Function*> &F) {
+ // Make sure functions & globals are all external so that linkage
+ // between the two modules will work.
+ for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
+ I->setLinkage(GlobalValue::ExternalLinkage);
+ for (Module::global_iterator I = M->global_begin(), E = M->global_end();
+ I != E; ++I)
+ I->setLinkage(GlobalValue::ExternalLinkage);
+
+ Module *New = CloneModule(M);
+
+ // Make sure global initializers exist only in the safe module (CBE->.so)
+ for (Module::global_iterator I = New->global_begin(), E = New->global_end();
+ I != E; ++I)
+ I->setInitializer(0); // Delete the initializer to make it external
+
+ // Remove the Test functions from the Safe module
+ std::set<std::pair<std::string, const PointerType*> > TestFunctions;
+ for (unsigned i = 0, e = F.size(); i != e; ++i) {
+ TestFunctions.insert(std::make_pair(F[i]->getName(), F[i]->getType()));
+ Function *TNOF = M->getFunction(F[i]->getName());
+ assert(TNOF && "Function doesn't exist in module!");
+ assert(TNOF->getFunctionType() == F[i]->getFunctionType() && "wrong type?");
+ DEBUG(std::cerr << "Removing function " << F[i]->getName() << "\n");
+ DeleteFunctionBody(TNOF); // Function is now external in this module!
+ }
+
+
+ // Remove the Safe functions from the Test module
+ for (Module::iterator I = New->begin(), E = New->end(); I != E; ++I)
+ if (!TestFunctions.count(std::make_pair(I->getName(), I->getType())))
+ DeleteFunctionBody(I);
+
+
+ // Make sure that there is a global ctor/dtor array in both halves of the
+ // module if they both have static ctor/dtor functions.
+ SplitStaticCtorDtor("llvm.global_ctors", M, New);
+ SplitStaticCtorDtor("llvm.global_dtors", M, New);
+
+ return New;
+}
+
+//===----------------------------------------------------------------------===//
+// Basic Block Extraction Code
+//===----------------------------------------------------------------------===//
+
+namespace {
+ std::vector<BasicBlock*> BlocksToNotExtract;
+
+ /// BlockExtractorPass - This pass is used by bugpoint to extract all blocks
+ /// from the module into their own functions except for those specified by the
+ /// BlocksToNotExtract list.
+ class BlockExtractorPass : public ModulePass {
+ bool runOnModule(Module &M);
+ public:
+ static char ID; // Pass ID, replacement for typeid
+ BlockExtractorPass() : ModulePass((intptr_t)&ID) {}
+ };
+ char BlockExtractorPass::ID = 0;
+ RegisterPass<BlockExtractorPass>
+ XX("extract-bbs", "Extract Basic Blocks From Module (for bugpoint use)");
+}
+
+bool BlockExtractorPass::runOnModule(Module &M) {
+ std::set<BasicBlock*> TranslatedBlocksToNotExtract;
+ for (unsigned i = 0, e = BlocksToNotExtract.size(); i != e; ++i) {
+ BasicBlock *BB = BlocksToNotExtract[i];
+ Function *F = BB->getParent();
+
+ // Map the corresponding function in this module.
+ Function *MF = M.getFunction(F->getName());
+
+ // Figure out which index the basic block is in its function.
+ Function::iterator BBI = MF->begin();
+ std::advance(BBI, std::distance(F->begin(), Function::iterator(BB)));
+ TranslatedBlocksToNotExtract.insert(BBI);
+ }
+
+ // Now that we know which blocks to not extract, figure out which ones we WANT
+ // to extract.
+ std::vector<BasicBlock*> BlocksToExtract;
+ for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F)
+ for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
+ if (!TranslatedBlocksToNotExtract.count(BB))
+ BlocksToExtract.push_back(BB);
+
+ for (unsigned i = 0, e = BlocksToExtract.size(); i != e; ++i)
+ ExtractBasicBlock(BlocksToExtract[i]);
+
+ return !BlocksToExtract.empty();
+}
+
+/// ExtractMappedBlocksFromModule - Extract all but the specified basic blocks
+/// into their own functions. The only detail is that M is actually a module
+/// cloned from the one the BBs are in, so some mapping needs to be performed.
+/// If this operation fails for some reason (ie the implementation is buggy),
+/// this function should return null, otherwise it returns a new Module.
+Module *BugDriver::ExtractMappedBlocksFromModule(const
+ std::vector<BasicBlock*> &BBs,
+ Module *M) {
+ // Set the global list so that pass will be able to access it.
+ BlocksToNotExtract = BBs;
+
+ std::vector<const PassInfo*> PI;
+ PI.push_back(getPI(new BlockExtractorPass()));
+ Module *Ret = runPassesOn(M, PI);
+ BlocksToNotExtract.clear();
+ if (Ret == 0) {
+ std::cout << "*** Basic Block extraction failed, please report a bug!\n";
+ M = swapProgramIn(M);
+ EmitProgressBitcode("basicblockextractfail", true);
+ swapProgramIn(M);
+ }
+ return Ret;
+}
diff --git a/tools/bugpoint/FindBugs.cpp b/tools/bugpoint/FindBugs.cpp
new file mode 100644
index 0000000..ac602ac
--- /dev/null
+++ b/tools/bugpoint/FindBugs.cpp
@@ -0,0 +1,115 @@
+//===-- FindBugs.cpp - Run Many Different Optimizations -------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Patrick Jenkins and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines an interface that allows bugpoint to choose different
+// combinations of optimizations to run on the selected input. Bugpoint will
+// run these optimizations and record the success/failure of each. This way
+// we can hopefully spot bugs in the optimizations.
+//
+//===----------------------------------------------------------------------===//
+
+#include "BugDriver.h"
+#include "ToolRunner.h"
+#include "llvm/Pass.h"
+#include <algorithm>
+#include <ctime>
+#include <iostream>
+using namespace llvm;
+
+/// runManyPasses - Take the specified pass list and create different
+/// combinations of passes to compile the program with. Compile the program with
+/// each set and mark test to see if it compiled correctly. If the passes
+/// compiled correctly output nothing and rearrange the passes into a new order.
+/// If the passes did not compile correctly, output the command required to
+/// recreate the failure. This returns true if a compiler error is found.
+///
+bool BugDriver::runManyPasses(const std::vector<const PassInfo*> &AllPasses) {
+ std::string Filename;
+ std::vector<const PassInfo*> TempPass(AllPasses);
+ std::cout << "Starting bug finding procedure...\n\n";
+
+ // Creating a reference output if necessary
+ if (initializeExecutionEnvironment()) return false;
+
+ std::cout << "\n";
+ if (ReferenceOutputFile.empty()) {
+ std::cout << "Generating reference output from raw program: \n";
+ if (!createReferenceFile(Program))
+ return false;
+ }
+
+ srand(time(NULL));
+ std::vector<const PassInfo*>::iterator I = TempPass.begin();
+ std::vector<const PassInfo*>::iterator E = TempPass.end();
+
+ unsigned num = 1;
+ while(1) {
+ //
+ // Step 1: Randomize the order of the optimizer passes.
+ //
+ std::random_shuffle(TempPass.begin(), TempPass.end());
+
+ //
+ // Step 2: Run optimizer passes on the program and check for success.
+ //
+ std::cout << "Running selected passes on program to test for crash: ";
+ for(int i = 0, e = TempPass.size(); i != e; i++) {
+ std::cout << "-" << TempPass[i]->getPassArgument( )<< " ";
+ }
+
+ std::string Filename;
+ if(runPasses(TempPass, Filename, false)) {
+ std::cout << "\n";
+ std::cout << "Optimizer passes caused failure!\n\n";
+ debugOptimizerCrash();
+ return true;
+ } else {
+ std::cout << "Combination " << num << " optimized successfully!\n";
+ }
+
+ //
+ // Step 3: Compile the optimized code.
+ //
+ std::cout << "Running the code generator to test for a crash: ";
+ try {
+ compileProgram(Program);
+ std::cout << '\n';
+ } catch (ToolExecutionError &TEE) {
+ std::cout << "\n*** compileProgram threw an exception: ";
+ std::cout << TEE.what();
+ return debugCodeGeneratorCrash();
+ }
+
+ //
+ // Step 4: Run the program and compare its output to the reference
+ // output (created above).
+ //
+ std::cout << "*** Checking if passes caused miscompliation:\n";
+ try {
+ if (diffProgram(Filename, "", false)) {
+ std::cout << "\n*** diffProgram returned true!\n";
+ debugMiscompilation();
+ return true;
+ } else {
+ std::cout << "\n*** diff'd output matches!\n";
+ }
+ } catch (ToolExecutionError &TEE) {
+ std::cerr << TEE.what();
+ debugCodeGeneratorCrash();
+ return true;
+ }
+
+ sys::Path(Filename).eraseFromDisk();
+
+ std::cout << "\n\n";
+ num++;
+ } //end while
+
+ // Unreachable.
+}
diff --git a/tools/bugpoint/ListReducer.h b/tools/bugpoint/ListReducer.h
new file mode 100644
index 0000000..a8f538a
--- /dev/null
+++ b/tools/bugpoint/ListReducer.h
@@ -0,0 +1,190 @@
+//===- ListReducer.h - Trim down list while retaining property --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class is to be used as a base class for operations that want to zero in
+// on a subset of the input which still causes the bug we are tracking.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef BUGPOINT_LIST_REDUCER_H
+#define BUGPOINT_LIST_REDUCER_H
+
+#include <vector>
+#include <iostream>
+#include <cstdlib>
+#include <algorithm>
+
+namespace llvm {
+
+ extern bool BugpointIsInterrupted;
+
+template<typename ElTy>
+struct ListReducer {
+ enum TestResult {
+ NoFailure, // No failure of the predicate was detected
+ KeepSuffix, // The suffix alone satisfies the predicate
+ KeepPrefix // The prefix alone satisfies the predicate
+ };
+
+ virtual ~ListReducer() {}
+
+ // doTest - This virtual function should be overriden by subclasses to
+ // implement the test desired. The testcase is only required to test to see
+ // if the Kept list still satisfies the property, but if it is going to check
+ // the prefix anyway, it can.
+ //
+ virtual TestResult doTest(std::vector<ElTy> &Prefix,
+ std::vector<ElTy> &Kept) = 0;
+
+ // reduceList - This function attempts to reduce the length of the specified
+ // list while still maintaining the "test" property. This is the core of the
+ // "work" that bugpoint does.
+ //
+ bool reduceList(std::vector<ElTy> &TheList) {
+ std::vector<ElTy> empty;
+ std::srand(0x6e5ea738); // Seed the random number generator
+ switch (doTest(TheList, empty)) {
+ case KeepPrefix:
+ if (TheList.size() == 1) // we are done, it's the base case and it fails
+ return true;
+ else
+ break; // there's definitely an error, but we need to narrow it down
+
+ case KeepSuffix:
+ // cannot be reached!
+ std::cerr << "bugpoint ListReducer internal error: selected empty set.\n";
+ abort();
+
+ case NoFailure:
+ return false; // there is no failure with the full set of passes/funcs!
+ }
+
+ // Maximal number of allowed splitting iterations,
+ // before the elements are randomly shuffled.
+ const unsigned MaxIterationsWithoutProgress = 3;
+ bool ShufflingEnabled = true;
+
+Backjump:
+ unsigned MidTop = TheList.size();
+ unsigned MaxIterations = MaxIterationsWithoutProgress;
+ unsigned NumOfIterationsWithoutProgress = 0;
+ while (MidTop > 1) { // Binary split reduction loop
+ // Halt if the user presses ctrl-c.
+ if (BugpointIsInterrupted) {
+ std::cerr << "\n\n*** Reduction Interrupted, cleaning up...\n\n";
+ return true;
+ }
+
+ // If the loop doesn't make satisfying progress, try shuffling.
+ // The purpose of shuffling is to avoid the heavy tails of the
+ // distribution (improving the speed of convergence).
+ if (ShufflingEnabled &&
+ NumOfIterationsWithoutProgress > MaxIterations) {
+
+ std::vector<ElTy> ShuffledList(TheList);
+ std::random_shuffle(ShuffledList.begin(), ShuffledList.end());
+ std::cerr << "\n\n*** Testing shuffled set...\n\n";
+ // Check that random shuffle doesn't loose the bug
+ if (doTest(ShuffledList, empty) == KeepPrefix) {
+ // If the bug is still here, use the shuffled list.
+ TheList.swap(ShuffledList);
+ MidTop = TheList.size();
+ // Must increase the shuffling treshold to avoid the small
+ // probability of inifinite looping without making progress.
+ MaxIterations += 2;
+ std::cerr << "\n\n*** Shuffling does not hide the bug...\n\n";
+ } else {
+ ShufflingEnabled = false; // Disable shuffling further on
+ std::cerr << "\n\n*** Shuffling hides the bug...\n\n";
+ }
+ NumOfIterationsWithoutProgress = 0;
+ }
+
+ unsigned Mid = MidTop / 2;
+ std::vector<ElTy> Prefix(TheList.begin(), TheList.begin()+Mid);
+ std::vector<ElTy> Suffix(TheList.begin()+Mid, TheList.end());
+
+ switch (doTest(Prefix, Suffix)) {
+ case KeepSuffix:
+ // The property still holds. We can just drop the prefix elements, and
+ // shorten the list to the "kept" elements.
+ TheList.swap(Suffix);
+ MidTop = TheList.size();
+ // Reset progress treshold and progress counter
+ MaxIterations = MaxIterationsWithoutProgress;
+ NumOfIterationsWithoutProgress = 0;
+ break;
+ case KeepPrefix:
+ // The predicate still holds, shorten the list to the prefix elements.
+ TheList.swap(Prefix);
+ MidTop = TheList.size();
+ // Reset progress treshold and progress counter
+ MaxIterations = MaxIterationsWithoutProgress;
+ NumOfIterationsWithoutProgress = 0;
+ break;
+ case NoFailure:
+ // Otherwise the property doesn't hold. Some of the elements we removed
+ // must be necessary to maintain the property.
+ MidTop = Mid;
+ NumOfIterationsWithoutProgress++;
+ break;
+ }
+ }
+
+ // Probability of backjumping from the trimming loop back to the binary
+ // split reduction loop.
+ const int BackjumpProbability = 10;
+
+ // Okay, we trimmed as much off the top and the bottom of the list as we
+ // could. If there is more than two elements in the list, try deleting
+ // interior elements and testing that.
+ //
+ if (TheList.size() > 2) {
+ bool Changed = true;
+ std::vector<ElTy> EmptyList;
+ while (Changed) { // Trimming loop.
+ Changed = false;
+
+ // If the binary split reduction loop made an unfortunate sequence of
+ // splits, the trimming loop might be left off with a huge number of
+ // remaining elements (large search space). Backjumping out of that
+ // search space and attempting a different split can significantly
+ // improve the convergence speed.
+ if (std::rand() % 100 < BackjumpProbability)
+ goto Backjump;
+
+ for (unsigned i = 1; i < TheList.size()-1; ++i) { // Check interior elts
+ if (BugpointIsInterrupted) {
+ std::cerr << "\n\n*** Reduction Interrupted, cleaning up...\n\n";
+ return true;
+ }
+
+ std::vector<ElTy> TestList(TheList);
+ TestList.erase(TestList.begin()+i);
+
+ if (doTest(EmptyList, TestList) == KeepSuffix) {
+ // We can trim down the list!
+ TheList.swap(TestList);
+ --i; // Don't skip an element of the list
+ Changed = true;
+ }
+ }
+ // This can take a long time if left uncontrolled. For now, don't
+ // iterate.
+ break;
+ }
+ }
+
+ return true; // there are some failure and we've narrowed them down
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/tools/bugpoint/Makefile b/tools/bugpoint/Makefile
new file mode 100644
index 0000000..6d8d7a0
--- /dev/null
+++ b/tools/bugpoint/Makefile
@@ -0,0 +1,17 @@
+##===- tools/bugpoint/Makefile -----------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file was developed by the LLVM research group and is distributed under
+# the University of Illinois Open Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+LEVEL = ../..
+
+TOOLNAME = bugpoint
+
+LINK_COMPONENTS := asmparser instrumentation scalaropts ipo \
+ linker bitreader bitwriter
+REQUIRES_EH := 1
+
+include $(LEVEL)/Makefile.common
diff --git a/tools/bugpoint/Miscompilation.cpp b/tools/bugpoint/Miscompilation.cpp
new file mode 100644
index 0000000..925a7a8
--- /dev/null
+++ b/tools/bugpoint/Miscompilation.cpp
@@ -0,0 +1,915 @@
+//===- Miscompilation.cpp - Debug program miscompilations -----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements optimizer and code generation miscompilation debugging
+// support.
+//
+//===----------------------------------------------------------------------===//
+
+#include "BugDriver.h"
+#include "ListReducer.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Instructions.h"
+#include "llvm/Linker.h"
+#include "llvm/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Analysis/Verifier.h"
+#include "llvm/Support/Mangler.h"
+#include "llvm/Transforms/Utils/Cloning.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FileUtilities.h"
+#include "llvm/Config/config.h" // for HAVE_LINK_R
+using namespace llvm;
+
+namespace llvm {
+ extern cl::list<std::string> InputArgv;
+}
+
+namespace {
+ static llvm::cl::opt<bool>
+ DisableLoopExtraction("disable-loop-extraction",
+ cl::desc("Don't extract loops when searching for miscompilations"),
+ cl::init(false));
+
+ class ReduceMiscompilingPasses : public ListReducer<const PassInfo*> {
+ BugDriver &BD;
+ public:
+ ReduceMiscompilingPasses(BugDriver &bd) : BD(bd) {}
+
+ virtual TestResult doTest(std::vector<const PassInfo*> &Prefix,
+ std::vector<const PassInfo*> &Suffix);
+ };
+}
+
+/// TestResult - After passes have been split into a test group and a control
+/// group, see if they still break the program.
+///
+ReduceMiscompilingPasses::TestResult
+ReduceMiscompilingPasses::doTest(std::vector<const PassInfo*> &Prefix,
+ std::vector<const PassInfo*> &Suffix) {
+ // First, run the program with just the Suffix passes. If it is still broken
+ // with JUST the kept passes, discard the prefix passes.
+ std::cout << "Checking to see if '" << getPassesString(Suffix)
+ << "' compile correctly: ";
+
+ std::string BitcodeResult;
+ if (BD.runPasses(Suffix, BitcodeResult, false/*delete*/, true/*quiet*/)) {
+ std::cerr << " Error running this sequence of passes"
+ << " on the input program!\n";
+ BD.setPassesToRun(Suffix);
+ BD.EmitProgressBitcode("pass-error", false);
+ exit(BD.debugOptimizerCrash());
+ }
+
+ // Check to see if the finished program matches the reference output...
+ if (BD.diffProgram(BitcodeResult, "", true /*delete bitcode*/)) {
+ std::cout << " nope.\n";
+ if (Suffix.empty()) {
+ std::cerr << BD.getToolName() << ": I'm confused: the test fails when "
+ << "no passes are run, nondeterministic program?\n";
+ exit(1);
+ }
+ return KeepSuffix; // Miscompilation detected!
+ }
+ std::cout << " yup.\n"; // No miscompilation!
+
+ if (Prefix.empty()) return NoFailure;
+
+ // Next, see if the program is broken if we run the "prefix" passes first,
+ // then separately run the "kept" passes.
+ std::cout << "Checking to see if '" << getPassesString(Prefix)
+ << "' compile correctly: ";
+
+ // If it is not broken with the kept passes, it's possible that the prefix
+ // passes must be run before the kept passes to break it. If the program
+ // WORKS after the prefix passes, but then fails if running the prefix AND
+ // kept passes, we can update our bitcode file to include the result of the
+ // prefix passes, then discard the prefix passes.
+ //
+ if (BD.runPasses(Prefix, BitcodeResult, false/*delete*/, true/*quiet*/)) {
+ std::cerr << " Error running this sequence of passes"
+ << " on the input program!\n";
+ BD.setPassesToRun(Prefix);
+ BD.EmitProgressBitcode("pass-error", false);
+ exit(BD.debugOptimizerCrash());
+ }
+
+ // If the prefix maintains the predicate by itself, only keep the prefix!
+ if (BD.diffProgram(BitcodeResult)) {
+ std::cout << " nope.\n";
+ sys::Path(BitcodeResult).eraseFromDisk();
+ return KeepPrefix;
+ }
+ std::cout << " yup.\n"; // No miscompilation!
+
+ // Ok, so now we know that the prefix passes work, try running the suffix
+ // passes on the result of the prefix passes.
+ //
+ Module *PrefixOutput = ParseInputFile(BitcodeResult);
+ if (PrefixOutput == 0) {
+ std::cerr << BD.getToolName() << ": Error reading bitcode file '"
+ << BitcodeResult << "'!\n";
+ exit(1);
+ }
+ sys::Path(BitcodeResult).eraseFromDisk(); // No longer need the file on disk
+
+ // Don't check if there are no passes in the suffix.
+ if (Suffix.empty())
+ return NoFailure;
+
+ std::cout << "Checking to see if '" << getPassesString(Suffix)
+ << "' passes compile correctly after the '"
+ << getPassesString(Prefix) << "' passes: ";
+
+ Module *OriginalInput = BD.swapProgramIn(PrefixOutput);
+ if (BD.runPasses(Suffix, BitcodeResult, false/*delete*/, true/*quiet*/)) {
+ std::cerr << " Error running this sequence of passes"
+ << " on the input program!\n";
+ BD.setPassesToRun(Suffix);
+ BD.EmitProgressBitcode("pass-error", false);
+ exit(BD.debugOptimizerCrash());
+ }
+
+ // Run the result...
+ if (BD.diffProgram(BitcodeResult, "", true/*delete bitcode*/)) {
+ std::cout << " nope.\n";
+ delete OriginalInput; // We pruned down the original input...
+ return KeepSuffix;
+ }
+
+ // Otherwise, we must not be running the bad pass anymore.
+ std::cout << " yup.\n"; // No miscompilation!
+ delete BD.swapProgramIn(OriginalInput); // Restore orig program & free test
+ return NoFailure;
+}
+
+namespace {
+ class ReduceMiscompilingFunctions : public ListReducer<Function*> {
+ BugDriver &BD;
+ bool (*TestFn)(BugDriver &, Module *, Module *);
+ public:
+ ReduceMiscompilingFunctions(BugDriver &bd,
+ bool (*F)(BugDriver &, Module *, Module *))
+ : BD(bd), TestFn(F) {}
+
+ virtual TestResult doTest(std::vector<Function*> &Prefix,
+ std::vector<Function*> &Suffix) {
+ if (!Suffix.empty() && TestFuncs(Suffix))
+ return KeepSuffix;
+ if (!Prefix.empty() && TestFuncs(Prefix))
+ return KeepPrefix;
+ return NoFailure;
+ }
+
+ bool TestFuncs(const std::vector<Function*> &Prefix);
+ };
+}
+
+/// TestMergedProgram - Given two modules, link them together and run the
+/// program, checking to see if the program matches the diff. If the diff
+/// matches, return false, otherwise return true. If the DeleteInputs argument
+/// is set to true then this function deletes both input modules before it
+/// returns.
+///
+static bool TestMergedProgram(BugDriver &BD, Module *M1, Module *M2,
+ bool DeleteInputs) {
+ // Link the two portions of the program back to together.
+ std::string ErrorMsg;
+ if (!DeleteInputs) {
+ M1 = CloneModule(M1);
+ M2 = CloneModule(M2);
+ }
+ if (Linker::LinkModules(M1, M2, &ErrorMsg)) {
+ std::cerr << BD.getToolName() << ": Error linking modules together:"
+ << ErrorMsg << '\n';
+ exit(1);
+ }
+ delete M2; // We are done with this module.
+
+ Module *OldProgram = BD.swapProgramIn(M1);
+
+ // Execute the program. If it does not match the expected output, we must
+ // return true.
+ bool Broken = BD.diffProgram();
+
+ // Delete the linked module & restore the original
+ BD.swapProgramIn(OldProgram);
+ delete M1;
+ return Broken;
+}
+
+/// TestFuncs - split functions in a Module into two groups: those that are
+/// under consideration for miscompilation vs. those that are not, and test
+/// accordingly. Each group of functions becomes a separate Module.
+///
+bool ReduceMiscompilingFunctions::TestFuncs(const std::vector<Function*>&Funcs){
+ // Test to see if the function is misoptimized if we ONLY run it on the
+ // functions listed in Funcs.
+ std::cout << "Checking to see if the program is misoptimized when "
+ << (Funcs.size()==1 ? "this function is" : "these functions are")
+ << " run through the pass"
+ << (BD.getPassesToRun().size() == 1 ? "" : "es") << ":";
+ PrintFunctionList(Funcs);
+ std::cout << '\n';
+
+ // Split the module into the two halves of the program we want.
+ Module *ToNotOptimize = CloneModule(BD.getProgram());
+ Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize, Funcs);
+
+ // Run the predicate, not that the predicate will delete both input modules.
+ return TestFn(BD, ToOptimize, ToNotOptimize);
+}
+
+/// DisambiguateGlobalSymbols - Mangle symbols to guarantee uniqueness by
+/// modifying predominantly internal symbols rather than external ones.
+///
+static void DisambiguateGlobalSymbols(Module *M) {
+ // Try not to cause collisions by minimizing chances of renaming an
+ // already-external symbol, so take in external globals and functions as-is.
+ // The code should work correctly without disambiguation (assuming the same
+ // mangler is used by the two code generators), but having symbols with the
+ // same name causes warnings to be emitted by the code generator.
+ Mangler Mang(*M);
+ // Agree with the CBE on symbol naming
+ Mang.markCharUnacceptable('.');
+ Mang.setPreserveAsmNames(true);
+ for (Module::global_iterator I = M->global_begin(), E = M->global_end();
+ I != E; ++I)
+ I->setName(Mang.getValueName(I));
+ for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
+ I->setName(Mang.getValueName(I));
+}
+
+/// ExtractLoops - Given a reduced list of functions that still exposed the bug,
+/// check to see if we can extract the loops in the region without obscuring the
+/// bug. If so, it reduces the amount of code identified.
+///
+static bool ExtractLoops(BugDriver &BD,
+ bool (*TestFn)(BugDriver &, Module *, Module *),
+ std::vector<Function*> &MiscompiledFunctions) {
+ bool MadeChange = false;
+ while (1) {
+ if (BugpointIsInterrupted) return MadeChange;
+
+ Module *ToNotOptimize = CloneModule(BD.getProgram());
+ Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize,
+ MiscompiledFunctions);
+ Module *ToOptimizeLoopExtracted = BD.ExtractLoop(ToOptimize);
+ if (!ToOptimizeLoopExtracted) {
+ // If the loop extractor crashed or if there were no extractible loops,
+ // then this chapter of our odyssey is over with.
+ delete ToNotOptimize;
+ delete ToOptimize;
+ return MadeChange;
+ }
+
+ std::cerr << "Extracted a loop from the breaking portion of the program.\n";
+
+ // Bugpoint is intentionally not very trusting of LLVM transformations. In
+ // particular, we're not going to assume that the loop extractor works, so
+ // we're going to test the newly loop extracted program to make sure nothing
+ // has broken. If something broke, then we'll inform the user and stop
+ // extraction.
+ AbstractInterpreter *AI = BD.switchToCBE();
+ if (TestMergedProgram(BD, ToOptimizeLoopExtracted, ToNotOptimize, false)) {
+ BD.switchToInterpreter(AI);
+
+ // Merged program doesn't work anymore!
+ std::cerr << " *** ERROR: Loop extraction broke the program. :("
+ << " Please report a bug!\n";
+ std::cerr << " Continuing on with un-loop-extracted version.\n";
+
+ BD.writeProgramToFile("bugpoint-loop-extract-fail-tno.bc", ToNotOptimize);
+ BD.writeProgramToFile("bugpoint-loop-extract-fail-to.bc", ToOptimize);
+ BD.writeProgramToFile("bugpoint-loop-extract-fail-to-le.bc",
+ ToOptimizeLoopExtracted);
+
+ std::cerr << "Please submit the bugpoint-loop-extract-fail-*.bc files.\n";
+ delete ToOptimize;
+ delete ToNotOptimize;
+ delete ToOptimizeLoopExtracted;
+ return MadeChange;
+ }
+ delete ToOptimize;
+ BD.switchToInterpreter(AI);
+
+ std::cout << " Testing after loop extraction:\n";
+ // Clone modules, the tester function will free them.
+ Module *TOLEBackup = CloneModule(ToOptimizeLoopExtracted);
+ Module *TNOBackup = CloneModule(ToNotOptimize);
+ if (!TestFn(BD, ToOptimizeLoopExtracted, ToNotOptimize)) {
+ std::cout << "*** Loop extraction masked the problem. Undoing.\n";
+ // If the program is not still broken, then loop extraction did something
+ // that masked the error. Stop loop extraction now.
+ delete TOLEBackup;
+ delete TNOBackup;
+ return MadeChange;
+ }
+ ToOptimizeLoopExtracted = TOLEBackup;
+ ToNotOptimize = TNOBackup;
+
+ std::cout << "*** Loop extraction successful!\n";
+
+ std::vector<std::pair<std::string, const FunctionType*> > MisCompFunctions;
+ for (Module::iterator I = ToOptimizeLoopExtracted->begin(),
+ E = ToOptimizeLoopExtracted->end(); I != E; ++I)
+ if (!I->isDeclaration())
+ MisCompFunctions.push_back(std::make_pair(I->getName(),
+ I->getFunctionType()));
+
+ // Okay, great! Now we know that we extracted a loop and that loop
+ // extraction both didn't break the program, and didn't mask the problem.
+ // Replace the current program with the loop extracted version, and try to
+ // extract another loop.
+ std::string ErrorMsg;
+ if (Linker::LinkModules(ToNotOptimize, ToOptimizeLoopExtracted, &ErrorMsg)){
+ std::cerr << BD.getToolName() << ": Error linking modules together:"
+ << ErrorMsg << '\n';
+ exit(1);
+ }
+ delete ToOptimizeLoopExtracted;
+
+ // All of the Function*'s in the MiscompiledFunctions list are in the old
+ // module. Update this list to include all of the functions in the
+ // optimized and loop extracted module.
+ MiscompiledFunctions.clear();
+ for (unsigned i = 0, e = MisCompFunctions.size(); i != e; ++i) {
+ Function *NewF = ToNotOptimize->getFunction(MisCompFunctions[i].first);
+
+ assert(NewF && "Function not found??");
+ assert(NewF->getFunctionType() == MisCompFunctions[i].second &&
+ "found wrong function type?");
+ MiscompiledFunctions.push_back(NewF);
+ }
+
+ BD.setNewProgram(ToNotOptimize);
+ MadeChange = true;
+ }
+}
+
+namespace {
+ class ReduceMiscompiledBlocks : public ListReducer<BasicBlock*> {
+ BugDriver &BD;
+ bool (*TestFn)(BugDriver &, Module *, Module *);
+ std::vector<Function*> FunctionsBeingTested;
+ public:
+ ReduceMiscompiledBlocks(BugDriver &bd,
+ bool (*F)(BugDriver &, Module *, Module *),
+ const std::vector<Function*> &Fns)
+ : BD(bd), TestFn(F), FunctionsBeingTested(Fns) {}
+
+ virtual TestResult doTest(std::vector<BasicBlock*> &Prefix,
+ std::vector<BasicBlock*> &Suffix) {
+ if (!Suffix.empty() && TestFuncs(Suffix))
+ return KeepSuffix;
+ if (TestFuncs(Prefix))
+ return KeepPrefix;
+ return NoFailure;
+ }
+
+ bool TestFuncs(const std::vector<BasicBlock*> &Prefix);
+ };
+}
+
+/// TestFuncs - Extract all blocks for the miscompiled functions except for the
+/// specified blocks. If the problem still exists, return true.
+///
+bool ReduceMiscompiledBlocks::TestFuncs(const std::vector<BasicBlock*> &BBs) {
+ // Test to see if the function is misoptimized if we ONLY run it on the
+ // functions listed in Funcs.
+ std::cout << "Checking to see if the program is misoptimized when all ";
+ if (!BBs.empty()) {
+ std::cout << "but these " << BBs.size() << " blocks are extracted: ";
+ for (unsigned i = 0, e = BBs.size() < 10 ? BBs.size() : 10; i != e; ++i)
+ std::cout << BBs[i]->getName() << " ";
+ if (BBs.size() > 10) std::cout << "...";
+ } else {
+ std::cout << "blocks are extracted.";
+ }
+ std::cout << '\n';
+
+ // Split the module into the two halves of the program we want.
+ Module *ToNotOptimize = CloneModule(BD.getProgram());
+ Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize,
+ FunctionsBeingTested);
+
+ // Try the extraction. If it doesn't work, then the block extractor crashed
+ // or something, in which case bugpoint can't chase down this possibility.
+ if (Module *New = BD.ExtractMappedBlocksFromModule(BBs, ToOptimize)) {
+ delete ToOptimize;
+ // Run the predicate, not that the predicate will delete both input modules.
+ return TestFn(BD, New, ToNotOptimize);
+ }
+ delete ToOptimize;
+ delete ToNotOptimize;
+ return false;
+}
+
+
+/// ExtractBlocks - Given a reduced list of functions that still expose the bug,
+/// extract as many basic blocks from the region as possible without obscuring
+/// the bug.
+///
+static bool ExtractBlocks(BugDriver &BD,
+ bool (*TestFn)(BugDriver &, Module *, Module *),
+ std::vector<Function*> &MiscompiledFunctions) {
+ if (BugpointIsInterrupted) return false;
+
+ std::vector<BasicBlock*> Blocks;
+ for (unsigned i = 0, e = MiscompiledFunctions.size(); i != e; ++i)
+ for (Function::iterator I = MiscompiledFunctions[i]->begin(),
+ E = MiscompiledFunctions[i]->end(); I != E; ++I)
+ Blocks.push_back(I);
+
+ // Use the list reducer to identify blocks that can be extracted without
+ // obscuring the bug. The Blocks list will end up containing blocks that must
+ // be retained from the original program.
+ unsigned OldSize = Blocks.size();
+
+ // Check to see if all blocks are extractible first.
+ if (ReduceMiscompiledBlocks(BD, TestFn,
+ MiscompiledFunctions).TestFuncs(std::vector<BasicBlock*>())) {
+ Blocks.clear();
+ } else {
+ ReduceMiscompiledBlocks(BD, TestFn,MiscompiledFunctions).reduceList(Blocks);
+ if (Blocks.size() == OldSize)
+ return false;
+ }
+
+ Module *ProgClone = CloneModule(BD.getProgram());
+ Module *ToExtract = SplitFunctionsOutOfModule(ProgClone,
+ MiscompiledFunctions);
+ Module *Extracted = BD.ExtractMappedBlocksFromModule(Blocks, ToExtract);
+ if (Extracted == 0) {
+ // Weird, extraction should have worked.
+ std::cerr << "Nondeterministic problem extracting blocks??\n";
+ delete ProgClone;
+ delete ToExtract;
+ return false;
+ }
+
+ // Otherwise, block extraction succeeded. Link the two program fragments back
+ // together.
+ delete ToExtract;
+
+ std::vector<std::pair<std::string, const FunctionType*> > MisCompFunctions;
+ for (Module::iterator I = Extracted->begin(), E = Extracted->end();
+ I != E; ++I)
+ if (!I->isDeclaration())
+ MisCompFunctions.push_back(std::make_pair(I->getName(),
+ I->getFunctionType()));
+
+ std::string ErrorMsg;
+ if (Linker::LinkModules(ProgClone, Extracted, &ErrorMsg)) {
+ std::cerr << BD.getToolName() << ": Error linking modules together:"
+ << ErrorMsg << '\n';
+ exit(1);
+ }
+ delete Extracted;
+
+ // Set the new program and delete the old one.
+ BD.setNewProgram(ProgClone);
+
+ // Update the list of miscompiled functions.
+ MiscompiledFunctions.clear();
+
+ for (unsigned i = 0, e = MisCompFunctions.size(); i != e; ++i) {
+ Function *NewF = ProgClone->getFunction(MisCompFunctions[i].first);
+ assert(NewF && "Function not found??");
+ assert(NewF->getFunctionType() == MisCompFunctions[i].second &&
+ "Function has wrong type??");
+ MiscompiledFunctions.push_back(NewF);
+ }
+
+ return true;
+}
+
+
+/// DebugAMiscompilation - This is a generic driver to narrow down
+/// miscompilations, either in an optimization or a code generator.
+///
+static std::vector<Function*>
+DebugAMiscompilation(BugDriver &BD,
+ bool (*TestFn)(BugDriver &, Module *, Module *)) {
+ // Okay, now that we have reduced the list of passes which are causing the
+ // failure, see if we can pin down which functions are being
+ // miscompiled... first build a list of all of the non-external functions in
+ // the program.
+ std::vector<Function*> MiscompiledFunctions;
+ Module *Prog = BD.getProgram();
+ for (Module::iterator I = Prog->begin(), E = Prog->end(); I != E; ++I)
+ if (!I->isDeclaration())
+ MiscompiledFunctions.push_back(I);
+
+ // Do the reduction...
+ if (!BugpointIsInterrupted)
+ ReduceMiscompilingFunctions(BD, TestFn).reduceList(MiscompiledFunctions);
+
+ std::cout << "\n*** The following function"
+ << (MiscompiledFunctions.size() == 1 ? " is" : "s are")
+ << " being miscompiled: ";
+ PrintFunctionList(MiscompiledFunctions);
+ std::cout << '\n';
+
+ // See if we can rip any loops out of the miscompiled functions and still
+ // trigger the problem.
+
+ if (!BugpointIsInterrupted && !DisableLoopExtraction &&
+ ExtractLoops(BD, TestFn, MiscompiledFunctions)) {
+ // Okay, we extracted some loops and the problem still appears. See if we
+ // can eliminate some of the created functions from being candidates.
+
+ // Loop extraction can introduce functions with the same name (foo_code).
+ // Make sure to disambiguate the symbols so that when the program is split
+ // apart that we can link it back together again.
+ DisambiguateGlobalSymbols(BD.getProgram());
+
+ // Do the reduction...
+ if (!BugpointIsInterrupted)
+ ReduceMiscompilingFunctions(BD, TestFn).reduceList(MiscompiledFunctions);
+
+ std::cout << "\n*** The following function"
+ << (MiscompiledFunctions.size() == 1 ? " is" : "s are")
+ << " being miscompiled: ";
+ PrintFunctionList(MiscompiledFunctions);
+ std::cout << '\n';
+ }
+
+ if (!BugpointIsInterrupted &&
+ ExtractBlocks(BD, TestFn, MiscompiledFunctions)) {
+ // Okay, we extracted some blocks and the problem still appears. See if we
+ // can eliminate some of the created functions from being candidates.
+
+ // Block extraction can introduce functions with the same name (foo_code).
+ // Make sure to disambiguate the symbols so that when the program is split
+ // apart that we can link it back together again.
+ DisambiguateGlobalSymbols(BD.getProgram());
+
+ // Do the reduction...
+ ReduceMiscompilingFunctions(BD, TestFn).reduceList(MiscompiledFunctions);
+
+ std::cout << "\n*** The following function"
+ << (MiscompiledFunctions.size() == 1 ? " is" : "s are")
+ << " being miscompiled: ";
+ PrintFunctionList(MiscompiledFunctions);
+ std::cout << '\n';
+ }
+
+ return MiscompiledFunctions;
+}
+
+/// TestOptimizer - This is the predicate function used to check to see if the
+/// "Test" portion of the program is misoptimized. If so, return true. In any
+/// case, both module arguments are deleted.
+///
+static bool TestOptimizer(BugDriver &BD, Module *Test, Module *Safe) {
+ // Run the optimization passes on ToOptimize, producing a transformed version
+ // of the functions being tested.
+ std::cout << " Optimizing functions being tested: ";
+ Module *Optimized = BD.runPassesOn(Test, BD.getPassesToRun(),
+ /*AutoDebugCrashes*/true);
+ std::cout << "done.\n";
+ delete Test;
+
+ std::cout << " Checking to see if the merged program executes correctly: ";
+ bool Broken = TestMergedProgram(BD, Optimized, Safe, true);
+ std::cout << (Broken ? " nope.\n" : " yup.\n");
+ return Broken;
+}
+
+
+/// debugMiscompilation - This method is used when the passes selected are not
+/// crashing, but the generated output is semantically different from the
+/// input.
+///
+bool BugDriver::debugMiscompilation() {
+ // Make sure something was miscompiled...
+ if (!BugpointIsInterrupted)
+ if (!ReduceMiscompilingPasses(*this).reduceList(PassesToRun)) {
+ std::cerr << "*** Optimized program matches reference output! No problem"
+ << " detected...\nbugpoint can't help you with your problem!\n";
+ return false;
+ }
+
+ std::cout << "\n*** Found miscompiling pass"
+ << (getPassesToRun().size() == 1 ? "" : "es") << ": "
+ << getPassesString(getPassesToRun()) << '\n';
+ EmitProgressBitcode("passinput");
+
+ std::vector<Function*> MiscompiledFunctions =
+ DebugAMiscompilation(*this, TestOptimizer);
+
+ // Output a bunch of bitcode files for the user...
+ std::cout << "Outputting reduced bitcode files which expose the problem:\n";
+ Module *ToNotOptimize = CloneModule(getProgram());
+ Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize,
+ MiscompiledFunctions);
+
+ std::cout << " Non-optimized portion: ";
+ ToNotOptimize = swapProgramIn(ToNotOptimize);
+ EmitProgressBitcode("tonotoptimize", true);
+ setNewProgram(ToNotOptimize); // Delete hacked module.
+
+ std::cout << " Portion that is input to optimizer: ";
+ ToOptimize = swapProgramIn(ToOptimize);
+ EmitProgressBitcode("tooptimize");
+ setNewProgram(ToOptimize); // Delete hacked module.
+
+ return false;
+}
+
+/// CleanupAndPrepareModules - Get the specified modules ready for code
+/// generator testing.
+///
+static void CleanupAndPrepareModules(BugDriver &BD, Module *&Test,
+ Module *Safe) {
+ // Clean up the modules, removing extra cruft that we don't need anymore...
+ Test = BD.performFinalCleanups(Test);
+
+ // If we are executing the JIT, we have several nasty issues to take care of.
+ if (!BD.isExecutingJIT()) return;
+
+ // First, if the main function is in the Safe module, we must add a stub to
+ // the Test module to call into it. Thus, we create a new function `main'
+ // which just calls the old one.
+ if (Function *oldMain = Safe->getFunction("main"))
+ if (!oldMain->isDeclaration()) {
+ // Rename it
+ oldMain->setName("llvm_bugpoint_old_main");
+ // Create a NEW `main' function with same type in the test module.
+ Function *newMain = new Function(oldMain->getFunctionType(),
+ GlobalValue::ExternalLinkage,
+ "main", Test);
+ // Create an `oldmain' prototype in the test module, which will
+ // corresponds to the real main function in the same module.
+ Function *oldMainProto = new Function(oldMain->getFunctionType(),
+ GlobalValue::ExternalLinkage,
+ oldMain->getName(), Test);
+ // Set up and remember the argument list for the main function.
+ std::vector<Value*> args;
+ for (Function::arg_iterator
+ I = newMain->arg_begin(), E = newMain->arg_end(),
+ OI = oldMain->arg_begin(); I != E; ++I, ++OI) {
+ I->setName(OI->getName()); // Copy argument names from oldMain
+ args.push_back(I);
+ }
+
+ // Call the old main function and return its result
+ BasicBlock *BB = new BasicBlock("entry", newMain);
+ CallInst *call = new CallInst(oldMainProto, &args[0], args.size(),
+ "", BB);
+
+ // If the type of old function wasn't void, return value of call
+ new ReturnInst(call, BB);
+ }
+
+ // The second nasty issue we must deal with in the JIT is that the Safe
+ // module cannot directly reference any functions defined in the test
+ // module. Instead, we use a JIT API call to dynamically resolve the
+ // symbol.
+
+ // Add the resolver to the Safe module.
+ // Prototype: void *getPointerToNamedFunction(const char* Name)
+ Constant *resolverFunc =
+ Safe->getOrInsertFunction("getPointerToNamedFunction",
+ PointerType::get(Type::Int8Ty),
+ PointerType::get(Type::Int8Ty), (Type *)0);
+
+ // Use the function we just added to get addresses of functions we need.
+ for (Module::iterator F = Safe->begin(), E = Safe->end(); F != E; ++F) {
+ if (F->isDeclaration() && !F->use_empty() && &*F != resolverFunc &&
+ F->getIntrinsicID() == 0 /* ignore intrinsics */) {
+ Function *TestFn = Test->getFunction(F->getName());
+
+ // Don't forward functions which are external in the test module too.
+ if (TestFn && !TestFn->isDeclaration()) {
+ // 1. Add a string constant with its name to the global file
+ Constant *InitArray = ConstantArray::get(F->getName());
+ GlobalVariable *funcName =
+ new GlobalVariable(InitArray->getType(), true /*isConstant*/,
+ GlobalValue::InternalLinkage, InitArray,
+ F->getName() + "_name", Safe);
+
+ // 2. Use `GetElementPtr *funcName, 0, 0' to convert the string to an
+ // sbyte* so it matches the signature of the resolver function.
+
+ // GetElementPtr *funcName, ulong 0, ulong 0
+ std::vector<Constant*> GEPargs(2,Constant::getNullValue(Type::Int32Ty));
+ Value *GEP = ConstantExpr::getGetElementPtr(funcName, &GEPargs[0], 2);
+ std::vector<Value*> ResolverArgs;
+ ResolverArgs.push_back(GEP);
+
+ // Rewrite uses of F in global initializers, etc. to uses of a wrapper
+ // function that dynamically resolves the calls to F via our JIT API
+ if (!F->use_empty()) {
+ // Create a new global to hold the cached function pointer.
+ Constant *NullPtr = ConstantPointerNull::get(F->getType());
+ GlobalVariable *Cache =
+ new GlobalVariable(F->getType(), false,GlobalValue::InternalLinkage,
+ NullPtr,F->getName()+".fpcache", F->getParent());
+
+ // Construct a new stub function that will re-route calls to F
+ const FunctionType *FuncTy = F->getFunctionType();
+ Function *FuncWrapper = new Function(FuncTy,
+ GlobalValue::InternalLinkage,
+ F->getName() + "_wrapper",
+ F->getParent());
+ BasicBlock *EntryBB = new BasicBlock("entry", FuncWrapper);
+ BasicBlock *DoCallBB = new BasicBlock("usecache", FuncWrapper);
+ BasicBlock *LookupBB = new BasicBlock("lookupfp", FuncWrapper);
+
+ // Check to see if we already looked up the value.
+ Value *CachedVal = new LoadInst(Cache, "fpcache", EntryBB);
+ Value *IsNull = new ICmpInst(ICmpInst::ICMP_EQ, CachedVal,
+ NullPtr, "isNull", EntryBB);
+ new BranchInst(LookupBB, DoCallBB, IsNull, EntryBB);
+
+ // Resolve the call to function F via the JIT API:
+ //
+ // call resolver(GetElementPtr...)
+ CallInst *Resolver = new CallInst(resolverFunc, &ResolverArgs[0],
+ ResolverArgs.size(),
+ "resolver", LookupBB);
+ // cast the result from the resolver to correctly-typed function
+ CastInst *CastedResolver = new BitCastInst(Resolver,
+ PointerType::get(F->getFunctionType()), "resolverCast", LookupBB);
+
+ // Save the value in our cache.
+ new StoreInst(CastedResolver, Cache, LookupBB);
+ new BranchInst(DoCallBB, LookupBB);
+
+ PHINode *FuncPtr = new PHINode(NullPtr->getType(), "fp", DoCallBB);
+ FuncPtr->addIncoming(CastedResolver, LookupBB);
+ FuncPtr->addIncoming(CachedVal, EntryBB);
+
+ // Save the argument list.
+ std::vector<Value*> Args;
+ for (Function::arg_iterator i = FuncWrapper->arg_begin(),
+ e = FuncWrapper->arg_end(); i != e; ++i)
+ Args.push_back(i);
+
+ // Pass on the arguments to the real function, return its result
+ if (F->getReturnType() == Type::VoidTy) {
+ new CallInst(FuncPtr, &Args[0], Args.size(), "", DoCallBB);
+ new ReturnInst(DoCallBB);
+ } else {
+ CallInst *Call = new CallInst(FuncPtr, &Args[0], Args.size(),
+ "retval", DoCallBB);
+ new ReturnInst(Call, DoCallBB);
+ }
+
+ // Use the wrapper function instead of the old function
+ F->replaceAllUsesWith(FuncWrapper);
+ }
+ }
+ }
+ }
+
+ if (verifyModule(*Test) || verifyModule(*Safe)) {
+ std::cerr << "Bugpoint has a bug, which corrupted a module!!\n";
+ abort();
+ }
+}
+
+
+
+/// TestCodeGenerator - This is the predicate function used to check to see if
+/// the "Test" portion of the program is miscompiled by the code generator under
+/// test. If so, return true. In any case, both module arguments are deleted.
+///
+static bool TestCodeGenerator(BugDriver &BD, Module *Test, Module *Safe) {
+ CleanupAndPrepareModules(BD, Test, Safe);
+
+ sys::Path TestModuleBC("bugpoint.test.bc");
+ std::string ErrMsg;
+ if (TestModuleBC.makeUnique(true, &ErrMsg)) {
+ std::cerr << BD.getToolName() << "Error making unique filename: "
+ << ErrMsg << "\n";
+ exit(1);
+ }
+ if (BD.writeProgramToFile(TestModuleBC.toString(), Test)) {
+ std::cerr << "Error writing bitcode to `" << TestModuleBC << "'\nExiting.";
+ exit(1);
+ }
+ delete Test;
+
+ // Make the shared library
+ sys::Path SafeModuleBC("bugpoint.safe.bc");
+ if (SafeModuleBC.makeUnique(true, &ErrMsg)) {
+ std::cerr << BD.getToolName() << "Error making unique filename: "
+ << ErrMsg << "\n";
+ exit(1);
+ }
+
+ if (BD.writeProgramToFile(SafeModuleBC.toString(), Safe)) {
+ std::cerr << "Error writing bitcode to `" << SafeModuleBC << "'\nExiting.";
+ exit(1);
+ }
+ std::string SharedObject = BD.compileSharedObject(SafeModuleBC.toString());
+ delete Safe;
+
+ // Run the code generator on the `Test' code, loading the shared library.
+ // The function returns whether or not the new output differs from reference.
+ int Result = BD.diffProgram(TestModuleBC.toString(), SharedObject, false);
+
+ if (Result)
+ std::cerr << ": still failing!\n";
+ else
+ std::cerr << ": didn't fail.\n";
+ TestModuleBC.eraseFromDisk();
+ SafeModuleBC.eraseFromDisk();
+ sys::Path(SharedObject).eraseFromDisk();
+
+ return Result;
+}
+
+
+/// debugCodeGenerator - debug errors in LLC, LLI, or CBE.
+///
+bool BugDriver::debugCodeGenerator() {
+ if ((void*)cbe == (void*)Interpreter) {
+ std::string Result = executeProgramWithCBE("bugpoint.cbe.out");
+ std::cout << "\n*** The C backend cannot match the reference diff, but it "
+ << "is used as the 'known good'\n code generator, so I can't"
+ << " debug it. Perhaps you have a front-end problem?\n As a"
+ << " sanity check, I left the result of executing the program "
+ << "with the C backend\n in this file for you: '"
+ << Result << "'.\n";
+ return true;
+ }
+
+ DisambiguateGlobalSymbols(Program);
+
+ std::vector<Function*> Funcs = DebugAMiscompilation(*this, TestCodeGenerator);
+
+ // Split the module into the two halves of the program we want.
+ Module *ToNotCodeGen = CloneModule(getProgram());
+ Module *ToCodeGen = SplitFunctionsOutOfModule(ToNotCodeGen, Funcs);
+
+ // Condition the modules
+ CleanupAndPrepareModules(*this, ToCodeGen, ToNotCodeGen);
+
+ sys::Path TestModuleBC("bugpoint.test.bc");
+ std::string ErrMsg;
+ if (TestModuleBC.makeUnique(true, &ErrMsg)) {
+ std::cerr << getToolName() << "Error making unique filename: "
+ << ErrMsg << "\n";
+ exit(1);
+ }
+
+ if (writeProgramToFile(TestModuleBC.toString(), ToCodeGen)) {
+ std::cerr << "Error writing bitcode to `" << TestModuleBC << "'\nExiting.";
+ exit(1);
+ }
+ delete ToCodeGen;
+
+ // Make the shared library
+ sys::Path SafeModuleBC("bugpoint.safe.bc");
+ if (SafeModuleBC.makeUnique(true, &ErrMsg)) {
+ std::cerr << getToolName() << "Error making unique filename: "
+ << ErrMsg << "\n";
+ exit(1);
+ }
+
+ if (writeProgramToFile(SafeModuleBC.toString(), ToNotCodeGen)) {
+ std::cerr << "Error writing bitcode to `" << SafeModuleBC << "'\nExiting.";
+ exit(1);
+ }
+ std::string SharedObject = compileSharedObject(SafeModuleBC.toString());
+ delete ToNotCodeGen;
+
+ std::cout << "You can reproduce the problem with the command line: \n";
+ if (isExecutingJIT()) {
+ std::cout << " lli -load " << SharedObject << " " << TestModuleBC;
+ } else {
+ std::cout << " llc -f " << TestModuleBC << " -o " << TestModuleBC<< ".s\n";
+ std::cout << " gcc " << SharedObject << " " << TestModuleBC
+ << ".s -o " << TestModuleBC << ".exe";
+#if defined (HAVE_LINK_R)
+ std::cout << " -Wl,-R.";
+#endif
+ std::cout << "\n";
+ std::cout << " " << TestModuleBC << ".exe";
+ }
+ for (unsigned i=0, e = InputArgv.size(); i != e; ++i)
+ std::cout << " " << InputArgv[i];
+ std::cout << '\n';
+ std::cout << "The shared object was created with:\n llc -march=c "
+ << SafeModuleBC << " -o temporary.c\n"
+ << " gcc -xc temporary.c -O2 -o " << SharedObject
+#if defined(sparc) || defined(__sparc__) || defined(__sparcv9)
+ << " -G" // Compile a shared library, `-G' for Sparc
+#else
+ << " -shared" // `-shared' for Linux/X86, maybe others
+#endif
+ << " -fno-strict-aliasing\n";
+
+ return false;
+}
diff --git a/tools/bugpoint/OptimizerDriver.cpp b/tools/bugpoint/OptimizerDriver.cpp
new file mode 100644
index 0000000..a3ce42e
--- /dev/null
+++ b/tools/bugpoint/OptimizerDriver.cpp
@@ -0,0 +1,254 @@
+//===- OptimizerDriver.cpp - Allow BugPoint to run passes safely ----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines an interface that allows bugpoint to run various passes
+// without the threat of a buggy pass corrupting bugpoint (of course, bugpoint
+// may have its own bugs, but that's another story...). It achieves this by
+// forking a copy of itself and having the child process do the optimizations.
+// If this client dies, we can always fork a new one. :)
+//
+//===----------------------------------------------------------------------===//
+
+// Note: as a short term hack, the old Unix-specific code and platform-
+// independent code co-exist via conditional compilation until it is verified
+// that the new code works correctly on Unix.
+
+#include "BugDriver.h"
+#include "llvm/Module.h"
+#include "llvm/PassManager.h"
+#include "llvm/Analysis/Verifier.h"
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Support/FileUtilities.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Streams.h"
+#include "llvm/System/Path.h"
+#include "llvm/System/Program.h"
+#include "llvm/Config/alloca.h"
+
+#define DONT_GET_PLUGIN_LOADER_OPTION
+#include "llvm/Support/PluginLoader.h"
+
+#include <fstream>
+using namespace llvm;
+
+
+namespace {
+ // ChildOutput - This option captures the name of the child output file that
+ // is set up by the parent bugpoint process
+ cl::opt<std::string> ChildOutput("child-output", cl::ReallyHidden);
+ cl::opt<bool> UseValgrind("enable-valgrind",
+ cl::desc("Run optimizations through valgrind"));
+}
+
+/// writeProgramToFile - This writes the current "Program" to the named bitcode
+/// file. If an error occurs, true is returned.
+///
+bool BugDriver::writeProgramToFile(const std::string &Filename,
+ Module *M) const {
+ std::ios::openmode io_mode = std::ios::out | std::ios::trunc |
+ std::ios::binary;
+ std::ofstream Out(Filename.c_str(), io_mode);
+ if (!Out.good()) return true;
+
+ WriteBitcodeToFile(M ? M : Program, Out);
+ return false;
+}
+
+
+/// EmitProgressBitcode - This function is used to output the current Program
+/// to a file named "bugpoint-ID.bc".
+///
+void BugDriver::EmitProgressBitcode(const std::string &ID, bool NoFlyer) {
+ // Output the input to the current pass to a bitcode file, emit a message
+ // telling the user how to reproduce it: opt -foo blah.bc
+ //
+ std::string Filename = "bugpoint-" + ID + ".bc";
+ if (writeProgramToFile(Filename)) {
+ cerr << "Error opening file '" << Filename << "' for writing!\n";
+ return;
+ }
+
+ cout << "Emitted bitcode to '" << Filename << "'\n";
+ if (NoFlyer || PassesToRun.empty()) return;
+ cout << "\n*** You can reproduce the problem with: ";
+ cout << "opt " << Filename << " ";
+ cout << getPassesString(PassesToRun) << "\n";
+}
+
+int BugDriver::runPassesAsChild(const std::vector<const PassInfo*> &Passes) {
+
+ std::ios::openmode io_mode = std::ios::out | std::ios::trunc |
+ std::ios::binary;
+ std::ofstream OutFile(ChildOutput.c_str(), io_mode);
+ if (!OutFile.good()) {
+ cerr << "Error opening bitcode file: " << ChildOutput << "\n";
+ return 1;
+ }
+
+ PassManager PM;
+ // Make sure that the appropriate target data is always used...
+ PM.add(new TargetData(Program));
+
+ for (unsigned i = 0, e = Passes.size(); i != e; ++i) {
+ if (Passes[i]->getNormalCtor())
+ PM.add(Passes[i]->getNormalCtor()());
+ else
+ cerr << "Cannot create pass yet: " << Passes[i]->getPassName() << "\n";
+ }
+ // Check that the module is well formed on completion of optimization
+ PM.add(createVerifierPass());
+
+ // Write bitcode out to disk as the last step...
+ PM.add(CreateBitcodeWriterPass(OutFile));
+
+ // Run all queued passes.
+ PM.run(*Program);
+
+ return 0;
+}
+
+/// runPasses - Run the specified passes on Program, outputting a bitcode file
+/// and writing the filename into OutputFile if successful. If the
+/// optimizations fail for some reason (optimizer crashes), return true,
+/// otherwise return false. If DeleteOutput is set to true, the bitcode is
+/// deleted on success, and the filename string is undefined. This prints to
+/// cout a single line message indicating whether compilation was successful or
+/// failed.
+///
+bool BugDriver::runPasses(const std::vector<const PassInfo*> &Passes,
+ std::string &OutputFilename, bool DeleteOutput,
+ bool Quiet) const {
+ // setup the output file name
+ cout << std::flush;
+ sys::Path uniqueFilename("bugpoint-output.bc");
+ std::string ErrMsg;
+ if (uniqueFilename.makeUnique(true, &ErrMsg)) {
+ cerr << getToolName() << ": Error making unique filename: "
+ << ErrMsg << "\n";
+ return(1);
+ }
+ OutputFilename = uniqueFilename.toString();
+
+ // set up the input file name
+ sys::Path inputFilename("bugpoint-input.bc");
+ if (inputFilename.makeUnique(true, &ErrMsg)) {
+ cerr << getToolName() << ": Error making unique filename: "
+ << ErrMsg << "\n";
+ return(1);
+ }
+ std::ios::openmode io_mode = std::ios::out | std::ios::trunc |
+ std::ios::binary;
+ std::ofstream InFile(inputFilename.c_str(), io_mode);
+ if (!InFile.good()) {
+ cerr << "Error opening bitcode file: " << inputFilename << "\n";
+ return(1);
+ }
+ WriteBitcodeToFile(Program, InFile);
+ InFile.close();
+
+ // setup the child process' arguments
+ const char** args = (const char**)
+ alloca(sizeof(const char*) *
+ (Passes.size()+13+2*PluginLoader::getNumPlugins()));
+ int n = 0;
+ sys::Path tool = sys::Program::FindProgramByName(ToolName);
+ if (UseValgrind) {
+ args[n++] = "valgrind";
+ args[n++] = "--error-exitcode=1";
+ args[n++] = "-q";
+ args[n++] = tool.c_str();
+ } else
+ args[n++] = ToolName.c_str();
+
+ args[n++] = "-as-child";
+ args[n++] = "-child-output";
+ args[n++] = OutputFilename.c_str();
+ std::vector<std::string> pass_args;
+ for (unsigned i = 0, e = PluginLoader::getNumPlugins(); i != e; ++i) {
+ pass_args.push_back( std::string("-load"));
+ pass_args.push_back( PluginLoader::getPlugin(i));
+ }
+ for (std::vector<const PassInfo*>::const_iterator I = Passes.begin(),
+ E = Passes.end(); I != E; ++I )
+ pass_args.push_back( std::string("-") + (*I)->getPassArgument() );
+ for (std::vector<std::string>::const_iterator I = pass_args.begin(),
+ E = pass_args.end(); I != E; ++I )
+ args[n++] = I->c_str();
+ args[n++] = inputFilename.c_str();
+ args[n++] = 0;
+
+ sys::Path prog;
+ if (UseValgrind)
+ prog = sys::Program::FindProgramByName("valgrind");
+ else
+ prog = tool;
+ int result = sys::Program::ExecuteAndWait(prog, args, 0, 0,
+ Timeout, MemoryLimit, &ErrMsg);
+
+ // If we are supposed to delete the bitcode file or if the passes crashed,
+ // remove it now. This may fail if the file was never created, but that's ok.
+ if (DeleteOutput || result != 0)
+ sys::Path(OutputFilename).eraseFromDisk();
+
+ // Remove the temporary input file as well
+ inputFilename.eraseFromDisk();
+
+ if (!Quiet) {
+ if (result == 0)
+ cout << "Success!\n";
+ else if (result > 0)
+ cout << "Exited with error code '" << result << "'\n";
+ else if (result < 0) {
+ if (result == -1)
+ cout << "Execute failed: " << ErrMsg << "\n";
+ else
+ cout << "Crashed with signal #" << abs(result) << "\n";
+ }
+ if (result & 0x01000000)
+ cout << "Dumped core\n";
+ }
+
+ // Was the child successful?
+ return result != 0;
+}
+
+
+/// runPassesOn - Carefully run the specified set of pass on the specified
+/// module, returning the transformed module on success, or a null pointer on
+/// failure.
+Module *BugDriver::runPassesOn(Module *M,
+ const std::vector<const PassInfo*> &Passes,
+ bool AutoDebugCrashes) {
+ Module *OldProgram = swapProgramIn(M);
+ std::string BitcodeResult;
+ if (runPasses(Passes, BitcodeResult, false/*delete*/, true/*quiet*/)) {
+ if (AutoDebugCrashes) {
+ cerr << " Error running this sequence of passes"
+ << " on the input program!\n";
+ delete OldProgram;
+ EmitProgressBitcode("pass-error", false);
+ exit(debugOptimizerCrash());
+ }
+ swapProgramIn(OldProgram);
+ return 0;
+ }
+
+ // Restore the current program.
+ swapProgramIn(OldProgram);
+
+ Module *Ret = ParseInputFile(BitcodeResult);
+ if (Ret == 0) {
+ cerr << getToolName() << ": Error reading bitcode file '"
+ << BitcodeResult << "'!\n";
+ exit(1);
+ }
+ sys::Path(BitcodeResult).eraseFromDisk(); // No longer need the file on disk
+ return Ret;
+}
diff --git a/tools/bugpoint/TestPasses.cpp b/tools/bugpoint/TestPasses.cpp
new file mode 100644
index 0000000..6923215
--- /dev/null
+++ b/tools/bugpoint/TestPasses.cpp
@@ -0,0 +1,75 @@
+//===- TestPasses.cpp - "buggy" passes used to test bugpoint --------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains "buggy" passes that are used to test bugpoint, to check
+// that it is narrowing down testcases correctly.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/BasicBlock.h"
+#include "llvm/Constant.h"
+#include "llvm/Instructions.h"
+#include "llvm/Pass.h"
+#include "llvm/Type.h"
+#include "llvm/Support/InstVisitor.h"
+
+using namespace llvm;
+
+namespace {
+ /// CrashOnCalls - This pass is used to test bugpoint. It intentionally
+ /// crashes on any call instructions.
+ class CrashOnCalls : public BasicBlockPass {
+ public:
+ static char ID; // Pass ID, replacement for typeid
+ CrashOnCalls() : BasicBlockPass((intptr_t)&ID) {}
+ private:
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ }
+
+ bool runOnBasicBlock(BasicBlock &BB) {
+ for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I)
+ if (isa<CallInst>(*I))
+ abort();
+
+ return false;
+ }
+ };
+
+ char CrashOnCalls::ID = 0;
+ RegisterPass<CrashOnCalls>
+ X("bugpoint-crashcalls",
+ "BugPoint Test Pass - Intentionally crash on CallInsts");
+}
+
+namespace {
+ /// DeleteCalls - This pass is used to test bugpoint. It intentionally
+ /// deletes some call instructions, "misoptimizing" the program.
+ class DeleteCalls : public BasicBlockPass {
+ public:
+ static char ID; // Pass ID, replacement for typeid
+ DeleteCalls() : BasicBlockPass((intptr_t)&ID) {}
+ private:
+ bool runOnBasicBlock(BasicBlock &BB) {
+ for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I)
+ if (CallInst *CI = dyn_cast<CallInst>(I)) {
+ if (!CI->use_empty())
+ CI->replaceAllUsesWith(Constant::getNullValue(CI->getType()));
+ CI->getParent()->getInstList().erase(CI);
+ break;
+ }
+ return false;
+ }
+ };
+
+ char DeleteCalls::ID = 0;
+ RegisterPass<DeleteCalls>
+ Y("bugpoint-deletecalls",
+ "BugPoint Test Pass - Intentionally 'misoptimize' CallInsts");
+}
diff --git a/tools/bugpoint/ToolRunner.cpp b/tools/bugpoint/ToolRunner.cpp
new file mode 100644
index 0000000..ac9a493
--- /dev/null
+++ b/tools/bugpoint/ToolRunner.cpp
@@ -0,0 +1,626 @@
+//===-- ToolRunner.cpp ----------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the interfaces described in the ToolRunner.h file.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "toolrunner"
+#include "ToolRunner.h"
+#include "llvm/Config/config.h" // for HAVE_LINK_R
+#include "llvm/System/Program.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/FileUtilities.h"
+#include <fstream>
+#include <sstream>
+#include <iostream>
+using namespace llvm;
+
+namespace {
+ cl::opt<std::string>
+ RSHHost("rsh-host",
+ cl::desc("Remote execution (rsh) host"));
+
+ cl::opt<std::string>
+ RSHUser("rsh-user",
+ cl::desc("Remote execution (rsh) user id"));
+}
+
+ToolExecutionError::~ToolExecutionError() throw() { }
+
+/// RunProgramWithTimeout - This function provides an alternate interface to the
+/// sys::Program::ExecuteAndWait interface.
+/// @see sys:Program::ExecuteAndWait
+static int RunProgramWithTimeout(const sys::Path &ProgramPath,
+ const char **Args,
+ const sys::Path &StdInFile,
+ const sys::Path &StdOutFile,
+ const sys::Path &StdErrFile,
+ unsigned NumSeconds = 0,
+ unsigned MemoryLimit = 0) {
+ const sys::Path* redirects[3];
+ redirects[0] = &StdInFile;
+ redirects[1] = &StdOutFile;
+ redirects[2] = &StdErrFile;
+
+ if (0) {
+ std::cerr << "RUN:";
+ for (unsigned i = 0; Args[i]; ++i)
+ std::cerr << " " << Args[i];
+ std::cerr << "\n";
+ }
+
+ return
+ sys::Program::ExecuteAndWait(ProgramPath, Args, 0, redirects,
+ NumSeconds, MemoryLimit);
+}
+
+
+
+static void ProcessFailure(sys::Path ProgPath, const char** Args) {
+ std::ostringstream OS;
+ OS << "\nError running tool:\n ";
+ for (const char **Arg = Args; *Arg; ++Arg)
+ OS << " " << *Arg;
+ OS << "\n";
+
+ // Rerun the compiler, capturing any error messages to print them.
+ sys::Path ErrorFilename("error_messages");
+ std::string ErrMsg;
+ if (ErrorFilename.makeUnique(true, &ErrMsg)) {
+ std::cerr << "Error making unique filename: " << ErrMsg << "\n";
+ exit(1);
+ }
+ RunProgramWithTimeout(ProgPath, Args, sys::Path(""), ErrorFilename,
+ ErrorFilename); // FIXME: check return code ?
+
+ // Print out the error messages generated by GCC if possible...
+ std::ifstream ErrorFile(ErrorFilename.c_str());
+ if (ErrorFile) {
+ std::copy(std::istreambuf_iterator<char>(ErrorFile),
+ std::istreambuf_iterator<char>(),
+ std::ostreambuf_iterator<char>(OS));
+ ErrorFile.close();
+ }
+
+ ErrorFilename.eraseFromDisk();
+ throw ToolExecutionError(OS.str());
+}
+
+//===---------------------------------------------------------------------===//
+// LLI Implementation of AbstractIntepreter interface
+//
+namespace {
+ class LLI : public AbstractInterpreter {
+ std::string LLIPath; // The path to the LLI executable
+ std::vector<std::string> ToolArgs; // Args to pass to LLI
+ public:
+ LLI(const std::string &Path, const std::vector<std::string> *Args)
+ : LLIPath(Path) {
+ ToolArgs.clear ();
+ if (Args) { ToolArgs = *Args; }
+ }
+
+ virtual int ExecuteProgram(const std::string &Bitcode,
+ const std::vector<std::string> &Args,
+ const std::string &InputFile,
+ const std::string &OutputFile,
+ const std::vector<std::string> &GCCArgs,
+ const std::vector<std::string> &SharedLibs =
+ std::vector<std::string>(),
+ unsigned Timeout = 0,
+ unsigned MemoryLimit = 0);
+ };
+}
+
+int LLI::ExecuteProgram(const std::string &Bitcode,
+ const std::vector<std::string> &Args,
+ const std::string &InputFile,
+ const std::string &OutputFile,
+ const std::vector<std::string> &GCCArgs,
+ const std::vector<std::string> &SharedLibs,
+ unsigned Timeout,
+ unsigned MemoryLimit) {
+ if (!SharedLibs.empty())
+ throw ToolExecutionError("LLI currently does not support "
+ "loading shared libraries.");
+
+ if (!GCCArgs.empty())
+ throw ToolExecutionError("LLI currently does not support "
+ "GCC Arguments.");
+ std::vector<const char*> LLIArgs;
+ LLIArgs.push_back(LLIPath.c_str());
+ LLIArgs.push_back("-force-interpreter=true");
+
+ // Add any extra LLI args.
+ for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
+ LLIArgs.push_back(ToolArgs[i].c_str());
+
+ LLIArgs.push_back(Bitcode.c_str());
+ // Add optional parameters to the running program from Argv
+ for (unsigned i=0, e = Args.size(); i != e; ++i)
+ LLIArgs.push_back(Args[i].c_str());
+ LLIArgs.push_back(0);
+
+ std::cout << "<lli>" << std::flush;
+ DEBUG(std::cerr << "\nAbout to run:\t";
+ for (unsigned i=0, e = LLIArgs.size()-1; i != e; ++i)
+ std::cerr << " " << LLIArgs[i];
+ std::cerr << "\n";
+ );
+ return RunProgramWithTimeout(sys::Path(LLIPath), &LLIArgs[0],
+ sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
+ Timeout, MemoryLimit);
+}
+
+// LLI create method - Try to find the LLI executable
+AbstractInterpreter *AbstractInterpreter::createLLI(const std::string &ProgPath,
+ std::string &Message,
+ const std::vector<std::string> *ToolArgs) {
+ std::string LLIPath = FindExecutable("lli", ProgPath).toString();
+ if (!LLIPath.empty()) {
+ Message = "Found lli: " + LLIPath + "\n";
+ return new LLI(LLIPath, ToolArgs);
+ }
+
+ Message = "Cannot find `lli' in executable directory or PATH!\n";
+ return 0;
+}
+
+//===----------------------------------------------------------------------===//
+// LLC Implementation of AbstractIntepreter interface
+//
+GCC::FileType LLC::OutputCode(const std::string &Bitcode,
+ sys::Path &OutputAsmFile) {
+ sys::Path uniqueFile(Bitcode+".llc.s");
+ std::string ErrMsg;
+ if (uniqueFile.makeUnique(true, &ErrMsg)) {
+ std::cerr << "Error making unique filename: " << ErrMsg << "\n";
+ exit(1);
+ }
+ OutputAsmFile = uniqueFile;
+ std::vector<const char *> LLCArgs;
+ LLCArgs.push_back (LLCPath.c_str());
+
+ // Add any extra LLC args.
+ for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
+ LLCArgs.push_back(ToolArgs[i].c_str());
+
+ LLCArgs.push_back ("-o");
+ LLCArgs.push_back (OutputAsmFile.c_str()); // Output to the Asm file
+ LLCArgs.push_back ("-f"); // Overwrite as necessary...
+ LLCArgs.push_back (Bitcode.c_str()); // This is the input bitcode
+ LLCArgs.push_back (0);
+
+ std::cout << "<llc>" << std::flush;
+ DEBUG(std::cerr << "\nAbout to run:\t";
+ for (unsigned i=0, e = LLCArgs.size()-1; i != e; ++i)
+ std::cerr << " " << LLCArgs[i];
+ std::cerr << "\n";
+ );
+ if (RunProgramWithTimeout(sys::Path(LLCPath), &LLCArgs[0],
+ sys::Path(), sys::Path(), sys::Path()))
+ ProcessFailure(sys::Path(LLCPath), &LLCArgs[0]);
+
+ return GCC::AsmFile;
+}
+
+void LLC::compileProgram(const std::string &Bitcode) {
+ sys::Path OutputAsmFile;
+ OutputCode(Bitcode, OutputAsmFile);
+ OutputAsmFile.eraseFromDisk();
+}
+
+int LLC::ExecuteProgram(const std::string &Bitcode,
+ const std::vector<std::string> &Args,
+ const std::string &InputFile,
+ const std::string &OutputFile,
+ const std::vector<std::string> &ArgsForGCC,
+ const std::vector<std::string> &SharedLibs,
+ unsigned Timeout,
+ unsigned MemoryLimit) {
+
+ sys::Path OutputAsmFile;
+ OutputCode(Bitcode, OutputAsmFile);
+ FileRemover OutFileRemover(OutputAsmFile);
+
+ std::vector<std::string> GCCArgs(ArgsForGCC);
+ GCCArgs.insert(GCCArgs.end(),SharedLibs.begin(),SharedLibs.end());
+
+ // Assuming LLC worked, compile the result with GCC and run it.
+ return gcc->ExecuteProgram(OutputAsmFile.toString(), Args, GCC::AsmFile,
+ InputFile, OutputFile, GCCArgs,
+ Timeout, MemoryLimit);
+}
+
+/// createLLC - Try to find the LLC executable
+///
+LLC *AbstractInterpreter::createLLC(const std::string &ProgramPath,
+ std::string &Message,
+ const std::vector<std::string> *Args) {
+ std::string LLCPath = FindExecutable("llc", ProgramPath).toString();
+ if (LLCPath.empty()) {
+ Message = "Cannot find `llc' in executable directory or PATH!\n";
+ return 0;
+ }
+
+ Message = "Found llc: " + LLCPath + "\n";
+ GCC *gcc = GCC::create(ProgramPath, Message);
+ if (!gcc) {
+ std::cerr << Message << "\n";
+ exit(1);
+ }
+ return new LLC(LLCPath, gcc, Args);
+}
+
+//===---------------------------------------------------------------------===//
+// JIT Implementation of AbstractIntepreter interface
+//
+namespace {
+ class JIT : public AbstractInterpreter {
+ std::string LLIPath; // The path to the LLI executable
+ std::vector<std::string> ToolArgs; // Args to pass to LLI
+ public:
+ JIT(const std::string &Path, const std::vector<std::string> *Args)
+ : LLIPath(Path) {
+ ToolArgs.clear ();
+ if (Args) { ToolArgs = *Args; }
+ }
+
+ virtual int ExecuteProgram(const std::string &Bitcode,
+ const std::vector<std::string> &Args,
+ const std::string &InputFile,
+ const std::string &OutputFile,
+ const std::vector<std::string> &GCCArgs =
+ std::vector<std::string>(),
+ const std::vector<std::string> &SharedLibs =
+ std::vector<std::string>(),
+ unsigned Timeout =0,
+ unsigned MemoryLimit =0);
+ };
+}
+
+int JIT::ExecuteProgram(const std::string &Bitcode,
+ const std::vector<std::string> &Args,
+ const std::string &InputFile,
+ const std::string &OutputFile,
+ const std::vector<std::string> &GCCArgs,
+ const std::vector<std::string> &SharedLibs,
+ unsigned Timeout,
+ unsigned MemoryLimit) {
+ if (!GCCArgs.empty())
+ throw ToolExecutionError("JIT does not support GCC Arguments.");
+ // Construct a vector of parameters, incorporating those from the command-line
+ std::vector<const char*> JITArgs;
+ JITArgs.push_back(LLIPath.c_str());
+ JITArgs.push_back("-force-interpreter=false");
+
+ // Add any extra LLI args.
+ for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
+ JITArgs.push_back(ToolArgs[i].c_str());
+
+ for (unsigned i = 0, e = SharedLibs.size(); i != e; ++i) {
+ JITArgs.push_back("-load");
+ JITArgs.push_back(SharedLibs[i].c_str());
+ }
+ JITArgs.push_back(Bitcode.c_str());
+ // Add optional parameters to the running program from Argv
+ for (unsigned i=0, e = Args.size(); i != e; ++i)
+ JITArgs.push_back(Args[i].c_str());
+ JITArgs.push_back(0);
+
+ std::cout << "<jit>" << std::flush;
+ DEBUG(std::cerr << "\nAbout to run:\t";
+ for (unsigned i=0, e = JITArgs.size()-1; i != e; ++i)
+ std::cerr << " " << JITArgs[i];
+ std::cerr << "\n";
+ );
+ DEBUG(std::cerr << "\nSending output to " << OutputFile << "\n");
+ return RunProgramWithTimeout(sys::Path(LLIPath), &JITArgs[0],
+ sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
+ Timeout, MemoryLimit);
+}
+
+/// createJIT - Try to find the LLI executable
+///
+AbstractInterpreter *AbstractInterpreter::createJIT(const std::string &ProgPath,
+ std::string &Message, const std::vector<std::string> *Args) {
+ std::string LLIPath = FindExecutable("lli", ProgPath).toString();
+ if (!LLIPath.empty()) {
+ Message = "Found lli: " + LLIPath + "\n";
+ return new JIT(LLIPath, Args);
+ }
+
+ Message = "Cannot find `lli' in executable directory or PATH!\n";
+ return 0;
+}
+
+GCC::FileType CBE::OutputCode(const std::string &Bitcode,
+ sys::Path &OutputCFile) {
+ sys::Path uniqueFile(Bitcode+".cbe.c");
+ std::string ErrMsg;
+ if (uniqueFile.makeUnique(true, &ErrMsg)) {
+ std::cerr << "Error making unique filename: " << ErrMsg << "\n";
+ exit(1);
+ }
+ OutputCFile = uniqueFile;
+ std::vector<const char *> LLCArgs;
+ LLCArgs.push_back (LLCPath.c_str());
+
+ // Add any extra LLC args.
+ for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
+ LLCArgs.push_back(ToolArgs[i].c_str());
+
+ LLCArgs.push_back ("-o");
+ LLCArgs.push_back (OutputCFile.c_str()); // Output to the C file
+ LLCArgs.push_back ("-march=c"); // Output C language
+ LLCArgs.push_back ("-f"); // Overwrite as necessary...
+ LLCArgs.push_back (Bitcode.c_str()); // This is the input bitcode
+ LLCArgs.push_back (0);
+
+ std::cout << "<cbe>" << std::flush;
+ DEBUG(std::cerr << "\nAbout to run:\t";
+ for (unsigned i=0, e = LLCArgs.size()-1; i != e; ++i)
+ std::cerr << " " << LLCArgs[i];
+ std::cerr << "\n";
+ );
+ if (RunProgramWithTimeout(LLCPath, &LLCArgs[0], sys::Path(), sys::Path(),
+ sys::Path()))
+ ProcessFailure(LLCPath, &LLCArgs[0]);
+ return GCC::CFile;
+}
+
+void CBE::compileProgram(const std::string &Bitcode) {
+ sys::Path OutputCFile;
+ OutputCode(Bitcode, OutputCFile);
+ OutputCFile.eraseFromDisk();
+}
+
+int CBE::ExecuteProgram(const std::string &Bitcode,
+ const std::vector<std::string> &Args,
+ const std::string &InputFile,
+ const std::string &OutputFile,
+ const std::vector<std::string> &ArgsForGCC,
+ const std::vector<std::string> &SharedLibs,
+ unsigned Timeout,
+ unsigned MemoryLimit) {
+ sys::Path OutputCFile;
+ OutputCode(Bitcode, OutputCFile);
+
+ FileRemover CFileRemove(OutputCFile);
+
+ std::vector<std::string> GCCArgs(ArgsForGCC);
+ GCCArgs.insert(GCCArgs.end(),SharedLibs.begin(),SharedLibs.end());
+ return gcc->ExecuteProgram(OutputCFile.toString(), Args, GCC::CFile,
+ InputFile, OutputFile, GCCArgs,
+ Timeout, MemoryLimit);
+}
+
+/// createCBE - Try to find the 'llc' executable
+///
+CBE *AbstractInterpreter::createCBE(const std::string &ProgramPath,
+ std::string &Message,
+ const std::vector<std::string> *Args) {
+ sys::Path LLCPath = FindExecutable("llc", ProgramPath);
+ if (LLCPath.isEmpty()) {
+ Message =
+ "Cannot find `llc' in executable directory or PATH!\n";
+ return 0;
+ }
+
+ Message = "Found llc: " + LLCPath.toString() + "\n";
+ GCC *gcc = GCC::create(ProgramPath, Message);
+ if (!gcc) {
+ std::cerr << Message << "\n";
+ exit(1);
+ }
+ return new CBE(LLCPath, gcc, Args);
+}
+
+//===---------------------------------------------------------------------===//
+// GCC abstraction
+//
+int GCC::ExecuteProgram(const std::string &ProgramFile,
+ const std::vector<std::string> &Args,
+ FileType fileType,
+ const std::string &InputFile,
+ const std::string &OutputFile,
+ const std::vector<std::string> &ArgsForGCC,
+ unsigned Timeout,
+ unsigned MemoryLimit) {
+ std::vector<const char*> GCCArgs;
+
+ GCCArgs.push_back(GCCPath.c_str());
+
+ // Specify -x explicitly in case the extension is wonky
+ GCCArgs.push_back("-x");
+ if (fileType == CFile) {
+ GCCArgs.push_back("c");
+ GCCArgs.push_back("-fno-strict-aliasing");
+ } else {
+ GCCArgs.push_back("assembler");
+#ifdef __APPLE__
+ GCCArgs.push_back("-force_cpusubtype_ALL");
+#endif
+ }
+ GCCArgs.push_back(ProgramFile.c_str()); // Specify the input filename...
+ GCCArgs.push_back("-x");
+ GCCArgs.push_back("none");
+ GCCArgs.push_back("-o");
+ sys::Path OutputBinary (ProgramFile+".gcc.exe");
+ std::string ErrMsg;
+ if (OutputBinary.makeUnique(true, &ErrMsg)) {
+ std::cerr << "Error making unique filename: " << ErrMsg << "\n";
+ exit(1);
+ }
+ GCCArgs.push_back(OutputBinary.c_str()); // Output to the right file...
+
+ // Add any arguments intended for GCC. We locate them here because this is
+ // most likely -L and -l options that need to come before other libraries but
+ // after the source. Other options won't be sensitive to placement on the
+ // command line, so this should be safe.
+ for (unsigned i = 0, e = ArgsForGCC.size(); i != e; ++i)
+ GCCArgs.push_back(ArgsForGCC[i].c_str());
+
+ GCCArgs.push_back("-lm"); // Hard-code the math library...
+ GCCArgs.push_back("-O2"); // Optimize the program a bit...
+#if defined (HAVE_LINK_R)
+ GCCArgs.push_back("-Wl,-R."); // Search this dir for .so files
+#endif
+#ifdef __sparc__
+ GCCArgs.push_back("-mcpu=v9");
+#endif
+ GCCArgs.push_back(0); // NULL terminator
+
+ std::cout << "<gcc>" << std::flush;
+ DEBUG(std::cerr << "\nAbout to run:\t";
+ for (unsigned i=0, e = GCCArgs.size()-1; i != e; ++i)
+ std::cerr << " " << GCCArgs[i];
+ std::cerr << "\n";
+ );
+ if (RunProgramWithTimeout(GCCPath, &GCCArgs[0], sys::Path(), sys::Path(),
+ sys::Path())) {
+ ProcessFailure(GCCPath, &GCCArgs[0]);
+ exit(1);
+ }
+
+ std::vector<const char*> ProgramArgs;
+
+ if (RSHPath.isEmpty())
+ ProgramArgs.push_back(OutputBinary.c_str());
+ else {
+ ProgramArgs.push_back(RSHPath.c_str());
+ ProgramArgs.push_back(RSHHost.c_str());
+ ProgramArgs.push_back("-l");
+ ProgramArgs.push_back(RSHUser.c_str());
+
+ char* env_pwd = getenv("PWD");
+ std::string Exec = "cd ";
+ Exec += env_pwd;
+ Exec += "; ./";
+ Exec += OutputBinary.c_str();
+ ProgramArgs.push_back(Exec.c_str());
+ }
+
+ // Add optional parameters to the running program from Argv
+ for (unsigned i=0, e = Args.size(); i != e; ++i)
+ ProgramArgs.push_back(Args[i].c_str());
+ ProgramArgs.push_back(0); // NULL terminator
+
+ // Now that we have a binary, run it!
+ std::cout << "<program>" << std::flush;
+ DEBUG(std::cerr << "\nAbout to run:\t";
+ for (unsigned i=0, e = ProgramArgs.size()-1; i != e; ++i)
+ std::cerr << " " << ProgramArgs[i];
+ std::cerr << "\n";
+ );
+
+ FileRemover OutputBinaryRemover(OutputBinary);
+
+ if (RSHPath.isEmpty())
+ return RunProgramWithTimeout(OutputBinary, &ProgramArgs[0],
+ sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
+ Timeout, MemoryLimit);
+ else
+ return RunProgramWithTimeout(sys::Path(RSHPath), &ProgramArgs[0],
+ sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
+ Timeout, MemoryLimit);
+}
+
+int GCC::MakeSharedObject(const std::string &InputFile, FileType fileType,
+ std::string &OutputFile,
+ const std::vector<std::string> &ArgsForGCC) {
+ sys::Path uniqueFilename(InputFile+LTDL_SHLIB_EXT);
+ std::string ErrMsg;
+ if (uniqueFilename.makeUnique(true, &ErrMsg)) {
+ std::cerr << "Error making unique filename: " << ErrMsg << "\n";
+ exit(1);
+ }
+ OutputFile = uniqueFilename.toString();
+
+ std::vector<const char*> GCCArgs;
+
+ GCCArgs.push_back(GCCPath.c_str());
+
+
+ // Compile the C/asm file into a shared object
+ GCCArgs.push_back("-x");
+ GCCArgs.push_back(fileType == AsmFile ? "assembler" : "c");
+ GCCArgs.push_back("-fno-strict-aliasing");
+ GCCArgs.push_back(InputFile.c_str()); // Specify the input filename.
+ GCCArgs.push_back("-x");
+ GCCArgs.push_back("none");
+#if defined(sparc) || defined(__sparc__) || defined(__sparcv9)
+ GCCArgs.push_back("-G"); // Compile a shared library, `-G' for Sparc
+#elif defined(__APPLE__)
+ // link all source files into a single module in data segment, rather than
+ // generating blocks. dynamic_lookup requires that you set
+ // MACOSX_DEPLOYMENT_TARGET=10.3 in your env. FIXME: it would be better for
+ // bugpoint to just pass that in the environment of GCC.
+ GCCArgs.push_back("-single_module");
+ GCCArgs.push_back("-dynamiclib"); // `-dynamiclib' for MacOS X/PowerPC
+ GCCArgs.push_back("-undefined");
+ GCCArgs.push_back("dynamic_lookup");
+#else
+ GCCArgs.push_back("-shared"); // `-shared' for Linux/X86, maybe others
+#endif
+
+#if defined(__ia64__) || defined(__alpha__)
+ GCCArgs.push_back("-fPIC"); // Requires shared objs to contain PIC
+#endif
+#ifdef __sparc__
+ GCCArgs.push_back("-mcpu=v9");
+#endif
+ GCCArgs.push_back("-o");
+ GCCArgs.push_back(OutputFile.c_str()); // Output to the right filename.
+ GCCArgs.push_back("-O2"); // Optimize the program a bit.
+
+
+
+ // Add any arguments intended for GCC. We locate them here because this is
+ // most likely -L and -l options that need to come before other libraries but
+ // after the source. Other options won't be sensitive to placement on the
+ // command line, so this should be safe.
+ for (unsigned i = 0, e = ArgsForGCC.size(); i != e; ++i)
+ GCCArgs.push_back(ArgsForGCC[i].c_str());
+ GCCArgs.push_back(0); // NULL terminator
+
+
+
+ std::cout << "<gcc>" << std::flush;
+ DEBUG(std::cerr << "\nAbout to run:\t";
+ for (unsigned i=0, e = GCCArgs.size()-1; i != e; ++i)
+ std::cerr << " " << GCCArgs[i];
+ std::cerr << "\n";
+ );
+ if (RunProgramWithTimeout(GCCPath, &GCCArgs[0], sys::Path(), sys::Path(),
+ sys::Path())) {
+ ProcessFailure(GCCPath, &GCCArgs[0]);
+ return 1;
+ }
+ return 0;
+}
+
+/// create - Try to find the `gcc' executable
+///
+GCC *GCC::create(const std::string &ProgramPath, std::string &Message) {
+ sys::Path GCCPath = FindExecutable("gcc", ProgramPath);
+ if (GCCPath.isEmpty()) {
+ Message = "Cannot find `gcc' in executable directory or PATH!\n";
+ return 0;
+ }
+
+ sys::Path RSHPath;
+ if (!RSHHost.empty())
+ RSHPath = FindExecutable("rsh", ProgramPath);
+
+ Message = "Found gcc: " + GCCPath.toString() + "\n";
+ return new GCC(GCCPath, RSHPath);
+}
diff --git a/tools/bugpoint/ToolRunner.h b/tools/bugpoint/ToolRunner.h
new file mode 100644
index 0000000..5cdd304
--- /dev/null
+++ b/tools/bugpoint/ToolRunner.h
@@ -0,0 +1,214 @@
+//===-- tools/bugpoint/ToolRunner.h -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file exposes an abstraction around a platform C compiler, used to
+// compile C and assembly code. It also exposes an "AbstractIntepreter"
+// interface, which is used to execute code using one of the LLVM execution
+// engines.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef BUGPOINT_TOOLRUNNER_H
+#define BUGPOINT_TOOLRUNNER_H
+
+#include "llvm/Support/SystemUtils.h"
+#include <exception>
+#include <vector>
+
+namespace llvm {
+
+class CBE;
+class LLC;
+
+/// ToolExecutionError - An instance of this class is thrown by the
+/// AbstractInterpreter instances if there is an error running a tool (e.g., LLC
+/// crashes) which prevents execution of the program.
+///
+class ToolExecutionError : std::exception {
+ std::string Message;
+public:
+ explicit ToolExecutionError(const std::string &M) : Message(M) {}
+ virtual ~ToolExecutionError() throw();
+ virtual const char* what() const throw() { return Message.c_str(); }
+};
+
+
+//===---------------------------------------------------------------------===//
+// GCC abstraction
+//
+class GCC {
+ sys::Path GCCPath; // The path to the gcc executable
+ sys::Path RSHPath; // The path to the rsh executable
+ GCC(const sys::Path &gccPath, const sys::Path &rshPath)
+ : GCCPath(gccPath), RSHPath(rshPath) { }
+public:
+ enum FileType { AsmFile, CFile };
+
+ static GCC *create(const std::string &ProgramPath, std::string &Message);
+
+ /// ExecuteProgram - Execute the program specified by "ProgramFile" (which is
+ /// either a .s file, or a .c file, specified by FileType), with the specified
+ /// arguments. Standard input is specified with InputFile, and standard
+ /// Output is captured to the specified OutputFile location. The SharedLibs
+ /// option specifies optional native shared objects that can be loaded into
+ /// the program for execution.
+ ///
+ int ExecuteProgram(const std::string &ProgramFile,
+ const std::vector<std::string> &Args,
+ FileType fileType,
+ const std::string &InputFile,
+ const std::string &OutputFile,
+ const std::vector<std::string> &GCCArgs =
+ std::vector<std::string>(),
+ unsigned Timeout = 0,
+ unsigned MemoryLimit = 0);
+
+ /// MakeSharedObject - This compiles the specified file (which is either a .c
+ /// file or a .s file) into a shared object.
+ ///
+ int MakeSharedObject(const std::string &InputFile, FileType fileType,
+ std::string &OutputFile,
+ const std::vector<std::string> &ArgsForGCC);
+};
+
+
+//===---------------------------------------------------------------------===//
+/// AbstractInterpreter Class - Subclasses of this class are used to execute
+/// LLVM bitcode in a variety of ways. This abstract interface hides this
+/// complexity behind a simple interface.
+///
+class AbstractInterpreter {
+public:
+ static CBE *createCBE(const std::string &ProgramPath, std::string &Message,
+ const std::vector<std::string> *Args = 0);
+ static LLC *createLLC(const std::string &ProgramPath, std::string &Message,
+ const std::vector<std::string> *Args = 0);
+
+ static AbstractInterpreter* createLLI(const std::string &ProgramPath,
+ std::string &Message,
+ const std::vector<std::string> *Args=0);
+
+ static AbstractInterpreter* createJIT(const std::string &ProgramPath,
+ std::string &Message,
+ const std::vector<std::string> *Args=0);
+
+
+ virtual ~AbstractInterpreter() {}
+
+ /// compileProgram - Compile the specified program from bitcode to executable
+ /// code. This does not produce any output, it is only used when debugging
+ /// the code generator. If the code generator fails, an exception should be
+ /// thrown, otherwise, this function will just return.
+ virtual void compileProgram(const std::string &Bitcode) {}
+
+ /// OutputCode - Compile the specified program from bitcode to code
+ /// understood by the GCC driver (either C or asm). If the code generator
+ /// fails, an exception should be thrown, otherwise, this function returns the
+ /// type of code emitted.
+ virtual GCC::FileType OutputCode(const std::string &Bitcode,
+ sys::Path &OutFile) {
+ throw std::string("OutputCode not supported by this AbstractInterpreter!");
+ }
+
+ /// ExecuteProgram - Run the specified bitcode file, emitting output to the
+ /// specified filename. This returns the exit code of the program.
+ ///
+ virtual int ExecuteProgram(const std::string &Bitcode,
+ const std::vector<std::string> &Args,
+ const std::string &InputFile,
+ const std::string &OutputFile,
+ const std::vector<std::string> &GCCArgs =
+ std::vector<std::string>(),
+ const std::vector<std::string> &SharedLibs =
+ std::vector<std::string>(),
+ unsigned Timeout = 0,
+ unsigned MemoryLimit = 0) = 0;
+};
+
+//===---------------------------------------------------------------------===//
+// CBE Implementation of AbstractIntepreter interface
+//
+class CBE : public AbstractInterpreter {
+ sys::Path LLCPath; // The path to the `llc' executable
+ std::vector<std::string> ToolArgs; // Extra args to pass to LLC
+ GCC *gcc;
+public:
+ CBE(const sys::Path &llcPath, GCC *Gcc,
+ const std::vector<std::string> *Args) : LLCPath(llcPath), gcc(Gcc) {
+ ToolArgs.clear ();
+ if (Args) { ToolArgs = *Args; }
+ }
+ ~CBE() { delete gcc; }
+
+ /// compileProgram - Compile the specified program from bitcode to executable
+ /// code. This does not produce any output, it is only used when debugging
+ /// the code generator. If the code generator fails, an exception should be
+ /// thrown, otherwise, this function will just return.
+ virtual void compileProgram(const std::string &Bitcode);
+
+ virtual int ExecuteProgram(const std::string &Bitcode,
+ const std::vector<std::string> &Args,
+ const std::string &InputFile,
+ const std::string &OutputFile,
+ const std::vector<std::string> &GCCArgs =
+ std::vector<std::string>(),
+ const std::vector<std::string> &SharedLibs =
+ std::vector<std::string>(),
+ unsigned Timeout = 0,
+ unsigned MemoryLimit = 0);
+
+ /// OutputCode - Compile the specified program from bitcode to code
+ /// understood by the GCC driver (either C or asm). If the code generator
+ /// fails, an exception should be thrown, otherwise, this function returns the
+ /// type of code emitted.
+ virtual GCC::FileType OutputCode(const std::string &Bitcode,
+ sys::Path &OutFile);
+};
+
+
+//===---------------------------------------------------------------------===//
+// LLC Implementation of AbstractIntepreter interface
+//
+class LLC : public AbstractInterpreter {
+ std::string LLCPath; // The path to the LLC executable
+ std::vector<std::string> ToolArgs; // Extra args to pass to LLC
+ GCC *gcc;
+public:
+ LLC(const std::string &llcPath, GCC *Gcc,
+ const std::vector<std::string> *Args) : LLCPath(llcPath), gcc(Gcc) {
+ ToolArgs.clear ();
+ if (Args) { ToolArgs = *Args; }
+ }
+ ~LLC() { delete gcc; }
+
+ /// compileProgram - Compile the specified program from bitcode to executable
+ /// code. This does not produce any output, it is only used when debugging
+ /// the code generator. If the code generator fails, an exception should be
+ /// thrown, otherwise, this function will just return.
+ virtual void compileProgram(const std::string &Bitcode);
+
+ virtual int ExecuteProgram(const std::string &Bitcode,
+ const std::vector<std::string> &Args,
+ const std::string &InputFile,
+ const std::string &OutputFile,
+ const std::vector<std::string> &GCCArgs =
+ std::vector<std::string>(),
+ const std::vector<std::string> &SharedLibs =
+ std::vector<std::string>(),
+ unsigned Timeout = 0,
+ unsigned MemoryLimit = 0);
+
+ virtual GCC::FileType OutputCode(const std::string &Bitcode,
+ sys::Path &OutFile);
+
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/tools/bugpoint/bugpoint.cpp b/tools/bugpoint/bugpoint.cpp
new file mode 100644
index 0000000..c345143
--- /dev/null
+++ b/tools/bugpoint/bugpoint.cpp
@@ -0,0 +1,94 @@
+//===- bugpoint.cpp - The LLVM Bugpoint utility ---------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This program is an automated compiler debugger tool. It is used to narrow
+// down miscompilations and crash problems to a specific pass in the compiler,
+// and the specific Module or Function input that is causing the problem.
+//
+//===----------------------------------------------------------------------===//
+
+#include "BugDriver.h"
+#include "ToolRunner.h"
+#include "llvm/LinkAllPasses.h"
+#include "llvm/Support/PassNameParser.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/PluginLoader.h"
+#include "llvm/System/Process.h"
+#include "llvm/System/Signals.h"
+#include "llvm/LinkAllVMCore.h"
+#include <iostream>
+using namespace llvm;
+
+// AsChild - Specifies that this invocation of bugpoint is being generated
+// from a parent process. It is not intended to be used by users so the
+// option is hidden.
+static cl::opt<bool>
+AsChild("as-child", cl::desc("Run bugpoint as child process"),
+ cl::ReallyHidden);
+
+static cl::opt<bool>
+FindBugs("find-bugs", cl::desc("Run many different optimization sequences"
+ "on program to find bugs"), cl::init(false));
+
+static cl::list<std::string>
+InputFilenames(cl::Positional, cl::OneOrMore,
+ cl::desc("<input llvm ll/bc files>"));
+
+static cl::opt<unsigned>
+TimeoutValue("timeout", cl::init(300), cl::value_desc("seconds"),
+ cl::desc("Number of seconds program is allowed to run before it "
+ "is killed (default is 300s), 0 disables timeout"));
+
+static cl::opt<unsigned>
+MemoryLimit("mlimit", cl::init(100), cl::value_desc("MBytes"),
+ cl::desc("Maximum amount of memory to use. 0 disables check."));
+
+// The AnalysesList is automatically populated with registered Passes by the
+// PassNameParser.
+//
+static cl::list<const PassInfo*, bool, PassNameParser>
+PassList(cl::desc("Passes available:"), cl::ZeroOrMore);
+
+/// BugpointIsInterrupted - Set to true when the user presses ctrl-c.
+bool llvm::BugpointIsInterrupted = false;
+
+static void BugpointInterruptFunction() {
+ BugpointIsInterrupted = true;
+}
+
+int main(int argc, char **argv) {
+ llvm_shutdown_obj X; // Call llvm_shutdown() on exit.
+ cl::ParseCommandLineOptions(argc, argv,
+ " LLVM automatic testcase reducer. See\nhttp://"
+ "llvm.org/docs/CommandGuide/bugpoint.html"
+ " for more information.\n");
+ sys::PrintStackTraceOnErrorSignal();
+ sys::SetInterruptFunction(BugpointInterruptFunction);
+
+ BugDriver D(argv[0], AsChild, FindBugs, TimeoutValue, MemoryLimit);
+ if (D.addSources(InputFilenames)) return 1;
+ D.addPasses(PassList.begin(), PassList.end());
+
+ // Bugpoint has the ability of generating a plethora of core files, so to
+ // avoid filling up the disk, we prevent it
+ sys::Process::PreventCoreFiles();
+
+ try {
+ return D.run();
+ } catch (ToolExecutionError &TEE) {
+ std::cerr << "Tool execution error: " << TEE.what() << '\n';
+ } catch (const std::string& msg) {
+ std::cerr << argv[0] << ": " << msg << "\n";
+ } catch (...) {
+ std::cerr << "Whoops, an exception leaked out of bugpoint. "
+ << "This is a bug in bugpoint!\n";
+ }
+ return 1;
+}
diff --git a/tools/gccas/Makefile b/tools/gccas/Makefile
new file mode 100644
index 0000000..1dc7ecd
--- /dev/null
+++ b/tools/gccas/Makefile
@@ -0,0 +1,28 @@
+##===- tools/gccas/Makefile --------------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file was developed by Reid Spencer and is distributed under the
+# University of Illinois Open Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+LEVEL = ../..
+
+include $(LEVEL)/Makefile.common
+
+install-local:: $(PROJ_bindir)/gccas
+
+$(PROJ_bindir)/gccas : gccas.sh Makefile
+ $(Echo) Installing gccas shell script.
+ $(Verb) sed "s#@TOOLDIR@#$(PROJ_bindir)#" $< > $@
+ $(Verb) chmod 0755 $@
+
+all-local:: $(ToolDir)/gccas
+
+$(ToolDir)/gccas : gccas.sh Makefile
+ $(Echo) Making $(ToolDir)/gccas shell script.
+ $(Verb) sed "s#@TOOLDIR@#$(ToolDir)#" $< > $@
+ $(Verb) chmod 0755 $@
+
+clean-local::
+ $(Verb)$(RM) -f $(ToolDir)/gccas
diff --git a/tools/gccas/gccas.sh b/tools/gccas/gccas.sh
new file mode 100644
index 0000000..258d960
--- /dev/null
+++ b/tools/gccas/gccas.sh
@@ -0,0 +1,64 @@
+#!/bin/sh
+##===- tools/gccas.sh ------------------------------------------*- bash -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file was developed by Reid Spencer and is distributed under the
+# University of Illinois Open Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+#
+# Synopsis: This shell script is a replacement for the old "gccas" tool that
+# existed in LLVM versions before 2.0. The functionality of gccas has
+# now been moved to opt and llvm-as. This shell script provides
+# backwards compatibility so build environments invoking gccas can
+# still get the net effect of llvm-as/opt by running gccas.
+#
+# Syntax: gccas OPTIONS... [asm file]
+#
+##===----------------------------------------------------------------------===##
+#
+echo "gccas: This tool is deprecated, please use opt" 1>&2
+TOOLDIR=@TOOLDIR@
+OPTOPTS="-std-compile-opts -f"
+ASOPTS=""
+lastwasdasho=0
+for option in "$@" ; do
+ option=`echo "$option" | sed 's/^--/-/'`
+ case "$option" in
+ -disable-opt)
+ OPTOPTS="$OPTOPTS $option"
+ ;;
+ -disable-inlining)
+ OPTOPTS="$OPTOPTS $option"
+ ;;
+ -verify)
+ OPTOPTS="$OPTOPTS -verify-each"
+ ;;
+ -strip-debug)
+ OPTOPTS="$OPTOPTS $option"
+ ;;
+ -o)
+ OPTOPTS="$OPTOPTS -o"
+ lastwasdasho=1
+ ;;
+ -disable-compression)
+ # ignore
+ ;;
+ -traditional-format)
+ # ignore
+ ;;
+ -*)
+ OPTOPTS="$OPTOPTS $option"
+ ;;
+ *)
+ if test $lastwasdasho -eq 1 ; then
+ OPTOPTS="$OPTOPTS $option"
+ lastwasdasho=0
+ else
+ ASOPTS="$ASOPTS $option"
+ fi
+ ;;
+ esac
+done
+${TOOLDIR}/llvm-as $ASOPTS -o - | ${TOOLDIR}/opt $OPTOPTS
diff --git a/tools/gccld/Makefile b/tools/gccld/Makefile
new file mode 100644
index 0000000..f348295
--- /dev/null
+++ b/tools/gccld/Makefile
@@ -0,0 +1,29 @@
+##===- tools/gccld/Makefile --------------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file was developed by the LLVM research group and is distributed under
+# the University of Illinois Open Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../..
+
+include $(LEVEL)/Makefile.common
+
+install-local:: $(PROJ_bindir)/gccld
+
+$(PROJ_bindir)/gccld : gccld.sh Makefile
+ $(Echo) Installing gccld shell script.
+ $(Verb) sed "s#@TOOLDIR@#$(PROJ_bindir)#" $< > $@
+ $(Verb) chmod 0755 $@
+
+all-local:: $(ToolDir)/gccld
+
+$(ToolDir)/gccld : gccld.sh Makefile
+ $(Echo) Making $(ToolDir)/gccld shell script.
+ $(Verb) sed "s#@TOOLDIR@#$(ToolDir)#" $< > $@
+ $(Verb) chmod 0755 $@
+
+clean-local::
+ $(Verb)$(RM) -f $(ToolDir)/gccld
diff --git a/tools/gccld/gccld.sh b/tools/gccld/gccld.sh
new file mode 100644
index 0000000..9ec9305
--- /dev/null
+++ b/tools/gccld/gccld.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+##===- tools/gccld/gccld.sh ------------------------------------*- bash -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file was developed by Reid Spencer and is distributed under the
+# University of Illinois Open Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+#
+# Synopsis: This shell script is a replacement for the old "gccld" tool that
+# existed in LLVM versions before 2.0. The functionality of gccld has
+# now been moved to llvm-ld. This shell script provides backwards
+# compatibility so build environments invoking gccld can still get
+# link (under the covers) with llvm-ld.
+#
+# Syntax: gccld OPTIONS... (see llvm-ld for details)
+#
+##===----------------------------------------------------------------------===##
+#
+echo "gccld: This tool is deprecated, please use llvm-ld" 1>&2
+TOOLDIR=@TOOLDIR@
+$TOOLDIR/llvm-ld "$@"
diff --git a/tools/llc/Makefile b/tools/llc/Makefile
new file mode 100644
index 0000000..aa767ae
--- /dev/null
+++ b/tools/llc/Makefile
@@ -0,0 +1,21 @@
+#===- tools/llc/Makefile -----------------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file was developed by the LLVM research group and is distributed under
+# the University of Illinois Open Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../..
+TOOLNAME = llc
+
+# Include this here so we can get the configuration of the targets
+# that have been configured for construction. We have to do this
+# early so we can set up LINK_COMPONENTS before including Makefile.rules
+include $(LEVEL)/Makefile.config
+
+LINK_COMPONENTS := $(TARGETS_TO_BUILD) bitreader
+
+include $(LLVM_SRC_ROOT)/Makefile.rules
+
diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp
new file mode 100644
index 0000000..b53f59b
--- /dev/null
+++ b/tools/llc/llc.cpp
@@ -0,0 +1,304 @@
+//===-- llc.cpp - Implement the LLVM Native Code Generator ----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is the llc code generator driver. It provides a convenient
+// command-line interface for generating native assembly-language code
+// or C code, given LLVM bitcode.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/CodeGen/FileWriters.h"
+#include "llvm/CodeGen/LinkAllCodegenComponents.h"
+#include "llvm/Target/SubtargetFeature.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetMachineRegistry.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Module.h"
+#include "llvm/ModuleProvider.h"
+#include "llvm/PassManager.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/PluginLoader.h"
+#include "llvm/Support/FileUtilities.h"
+#include "llvm/Analysis/Verifier.h"
+#include "llvm/System/Signals.h"
+#include "llvm/Config/config.h"
+#include "llvm/LinkAllVMCore.h"
+#include <fstream>
+#include <iostream>
+#include <memory>
+using namespace llvm;
+
+// General options for llc. Other pass-specific options are specified
+// within the corresponding llc passes, and target-specific options
+// and back-end code generation options are specified with the target machine.
+//
+static cl::opt<std::string>
+InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-"));
+
+static cl::opt<std::string>
+OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"));
+
+static cl::opt<bool> Force("f", cl::desc("Overwrite output files"));
+
+static cl::opt<bool> Fast("fast",
+ cl::desc("Generate code quickly, potentially sacrificing code quality"));
+
+static cl::opt<std::string>
+TargetTriple("mtriple", cl::desc("Override target triple for module"));
+
+static cl::opt<const TargetMachineRegistry::Entry*, false, TargetNameParser>
+MArch("march", cl::desc("Architecture to generate code for:"));
+
+static cl::opt<std::string>
+MCPU("mcpu",
+ cl::desc("Target a specific cpu type (-mcpu=help for details)"),
+ cl::value_desc("cpu-name"),
+ cl::init(""));
+
+static cl::list<std::string>
+MAttrs("mattr",
+ cl::CommaSeparated,
+ cl::desc("Target specific attributes (-mattr=help for details)"),
+ cl::value_desc("a1,+a2,-a3,..."));
+
+cl::opt<TargetMachine::CodeGenFileType>
+FileType("filetype", cl::init(TargetMachine::AssemblyFile),
+ cl::desc("Choose a file type (not all types are supported by all targets):"),
+ cl::values(
+ clEnumValN(TargetMachine::AssemblyFile, "asm",
+ " Emit an assembly ('.s') file"),
+ clEnumValN(TargetMachine::ObjectFile, "obj",
+ " Emit a native object ('.o') file [experimental]"),
+ clEnumValN(TargetMachine::DynamicLibrary, "dynlib",
+ " Emit a native dynamic library ('.so') file"
+ " [experimental]"),
+ clEnumValEnd));
+
+cl::opt<bool> NoVerify("disable-verify", cl::Hidden,
+ cl::desc("Do not verify input module"));
+
+
+// GetFileNameRoot - Helper function to get the basename of a filename.
+static inline std::string
+GetFileNameRoot(const std::string &InputFilename) {
+ std::string IFN = InputFilename;
+ std::string outputFilename;
+ int Len = IFN.length();
+ if ((Len > 2) &&
+ IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') {
+ outputFilename = std::string(IFN.begin(), IFN.end()-3); // s/.bc/.s/
+ } else {
+ outputFilename = IFN;
+ }
+ return outputFilename;
+}
+
+static std::ostream *GetOutputStream(const char *ProgName) {
+ if (OutputFilename != "") {
+ if (OutputFilename == "-")
+ return &std::cout;
+
+ // Specified an output filename?
+ if (!Force && std::ifstream(OutputFilename.c_str())) {
+ // If force is not specified, make sure not to overwrite a file!
+ std::cerr << ProgName << ": error opening '" << OutputFilename
+ << "': file exists!\n"
+ << "Use -f command line argument to force output\n";
+ return 0;
+ }
+ // Make sure that the Out file gets unlinked from the disk if we get a
+ // SIGINT
+ sys::RemoveFileOnSignal(sys::Path(OutputFilename));
+
+ return new std::ofstream(OutputFilename.c_str());
+ }
+
+ if (InputFilename == "-") {
+ OutputFilename = "-";
+ return &std::cout;
+ }
+
+ OutputFilename = GetFileNameRoot(InputFilename);
+
+ switch (FileType) {
+ case TargetMachine::AssemblyFile:
+ if (MArch->Name[0] != 'c' || MArch->Name[1] != 0) // not CBE
+ OutputFilename += ".s";
+ else
+ OutputFilename += ".cbe.c";
+ break;
+ case TargetMachine::ObjectFile:
+ OutputFilename += ".o";
+ break;
+ case TargetMachine::DynamicLibrary:
+ OutputFilename += LTDL_SHLIB_EXT;
+ break;
+ }
+
+ if (!Force && std::ifstream(OutputFilename.c_str())) {
+ // If force is not specified, make sure not to overwrite a file!
+ std::cerr << ProgName << ": error opening '" << OutputFilename
+ << "': file exists!\n"
+ << "Use -f command line argument to force output\n";
+ return 0;
+ }
+
+ // Make sure that the Out file gets unlinked from the disk if we get a
+ // SIGINT
+ sys::RemoveFileOnSignal(sys::Path(OutputFilename));
+
+ std::ostream *Out = new std::ofstream(OutputFilename.c_str());
+ if (!Out->good()) {
+ std::cerr << ProgName << ": error opening " << OutputFilename << "!\n";
+ delete Out;
+ return 0;
+ }
+
+ return Out;
+}
+
+// main - Entry point for the llc compiler.
+//
+int main(int argc, char **argv) {
+ llvm_shutdown_obj X; // Call llvm_shutdown() on exit.
+ cl::ParseCommandLineOptions(argc, argv, " llvm system compiler\n");
+ sys::PrintStackTraceOnErrorSignal();
+
+ // Load the module to be compiled...
+ std::string ErrorMessage;
+ std::auto_ptr<Module> M;
+
+ std::auto_ptr<MemoryBuffer> Buffer(
+ MemoryBuffer::getFileOrSTDIN(InputFilename, &ErrorMessage));
+ if (Buffer.get())
+ M.reset(ParseBitcodeFile(Buffer.get(), &ErrorMessage));
+ if (M.get() == 0) {
+ std::cerr << argv[0] << ": bitcode didn't read correctly.\n";
+ std::cerr << "Reason: " << ErrorMessage << "\n";
+ return 1;
+ }
+ Module &mod = *M.get();
+
+ // If we are supposed to override the target triple, do so now.
+ if (!TargetTriple.empty())
+ mod.setTargetTriple(TargetTriple);
+
+ // Allocate target machine. First, check whether the user has
+ // explicitly specified an architecture to compile for.
+ if (MArch == 0) {
+ std::string Err;
+ MArch = TargetMachineRegistry::getClosestStaticTargetForModule(mod, Err);
+ if (MArch == 0) {
+ std::cerr << argv[0] << ": error auto-selecting target for module '"
+ << Err << "'. Please use the -march option to explicitly "
+ << "pick a target.\n";
+ return 1;
+ }
+ }
+
+ // Package up features to be passed to target/subtarget
+ std::string FeaturesStr;
+ if (MCPU.size() || MAttrs.size()) {
+ SubtargetFeatures Features;
+ Features.setCPU(MCPU);
+ for (unsigned i = 0; i != MAttrs.size(); ++i)
+ Features.AddFeature(MAttrs[i]);
+ FeaturesStr = Features.getString();
+ }
+
+ std::auto_ptr<TargetMachine> target(MArch->CtorFn(mod, FeaturesStr));
+ assert(target.get() && "Could not allocate target machine!");
+ TargetMachine &Target = *target.get();
+
+ // Figure out where we are going to send the output...
+ std::ostream *Out = GetOutputStream(argv[0]);
+ if (Out == 0) return 1;
+
+ // If this target requires addPassesToEmitWholeFile, do it now. This is
+ // used by strange things like the C backend.
+ if (Target.WantsWholeFile()) {
+ PassManager PM;
+ PM.add(new TargetData(*Target.getTargetData()));
+ if (!NoVerify)
+ PM.add(createVerifierPass());
+
+ // Ask the target to add backend passes as necessary.
+ if (Target.addPassesToEmitWholeFile(PM, *Out, FileType, Fast)) {
+ std::cerr << argv[0] << ": target does not support generation of this"
+ << " file type!\n";
+ if (Out != &std::cout) delete Out;
+ // And the Out file is empty and useless, so remove it now.
+ sys::Path(OutputFilename).eraseFromDisk();
+ return 1;
+ }
+ PM.run(mod);
+ } else {
+ // Build up all of the passes that we want to do to the module.
+ FunctionPassManager Passes(new ExistingModuleProvider(M.get()));
+ Passes.add(new TargetData(*Target.getTargetData()));
+
+#ifndef NDEBUG
+ if (!NoVerify)
+ Passes.add(createVerifierPass());
+#endif
+
+ // Ask the target to add backend passes as necessary.
+ MachineCodeEmitter *MCE = 0;
+
+ switch (Target.addPassesToEmitFile(Passes, *Out, FileType, Fast)) {
+ default:
+ assert(0 && "Invalid file model!");
+ return 1;
+ case FileModel::Error:
+ std::cerr << argv[0] << ": target does not support generation of this"
+ << " file type!\n";
+ if (Out != &std::cout) delete Out;
+ // And the Out file is empty and useless, so remove it now.
+ sys::Path(OutputFilename).eraseFromDisk();
+ return 1;
+ case FileModel::AsmFile:
+ break;
+ case FileModel::MachOFile:
+ MCE = AddMachOWriter(Passes, *Out, Target);
+ break;
+ case FileModel::ElfFile:
+ MCE = AddELFWriter(Passes, *Out, Target);
+ break;
+ }
+
+ if (Target.addPassesToEmitFileFinish(Passes, MCE, Fast)) {
+ std::cerr << argv[0] << ": target does not support generation of this"
+ << " file type!\n";
+ if (Out != &std::cout) delete Out;
+ // And the Out file is empty and useless, so remove it now.
+ sys::Path(OutputFilename).eraseFromDisk();
+ return 1;
+ }
+
+ Passes.doInitialization();
+
+ // Run our queue of passes all at once now, efficiently.
+ // TODO: this could lazily stream functions out of the module.
+ for (Module::iterator I = mod.begin(), E = mod.end(); I != E; ++I)
+ if (!I->isDeclaration())
+ Passes.run(*I);
+
+ Passes.doFinalization();
+ }
+
+ // Delete the ostream if it's not a stdout stream
+ if (Out != &std::cout) delete Out;
+
+ return 0;
+}
diff --git a/tools/lli/Makefile b/tools/lli/Makefile
new file mode 100644
index 0000000..d443b15
--- /dev/null
+++ b/tools/lli/Makefile
@@ -0,0 +1,15 @@
+##===- tools/lli/Makefile ------------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file was developed by the LLVM research group and is distributed under
+# the University of Illinois Open Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL := ../..
+TOOLNAME := lli
+LINK_COMPONENTS := jit interpreter native bitreader selectiondag
+
+# Enable JIT support
+include $(LEVEL)/Makefile.common
diff --git a/tools/lli/lli.cpp b/tools/lli/lli.cpp
new file mode 100644
index 0000000..3ce2807
--- /dev/null
+++ b/tools/lli/lli.cpp
@@ -0,0 +1,160 @@
+//===- lli.cpp - LLVM Interpreter / Dynamic compiler ----------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This utility provides a simple wrapper around the LLVM Execution Engines,
+// which allow the direct execution of LLVM programs through a Just-In-Time
+// compiler, or through an intepreter if no JIT is available for this platform.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Module.h"
+#include "llvm/ModuleProvider.h"
+#include "llvm/Type.h"
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/CodeGen/LinkAllCodegenComponents.h"
+#include "llvm/ExecutionEngine/JIT.h"
+#include "llvm/ExecutionEngine/Interpreter.h"
+#include "llvm/ExecutionEngine/GenericValue.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/PluginLoader.h"
+#include "llvm/System/Process.h"
+#include "llvm/System/Signals.h"
+#include <iostream>
+#include <cerrno>
+using namespace llvm;
+
+namespace {
+ cl::opt<std::string>
+ InputFile(cl::desc("<input bitcode>"), cl::Positional, cl::init("-"));
+
+ cl::list<std::string>
+ InputArgv(cl::ConsumeAfter, cl::desc("<program arguments>..."));
+
+ cl::opt<bool> ForceInterpreter("force-interpreter",
+ cl::desc("Force interpretation: disable JIT"),
+ cl::init(false));
+ cl::opt<std::string>
+ TargetTriple("mtriple", cl::desc("Override target triple for module"));
+
+ cl::opt<std::string>
+ FakeArgv0("fake-argv0",
+ cl::desc("Override the 'argv[0]' value passed into the executing"
+ " program"), cl::value_desc("executable"));
+
+ cl::opt<bool>
+ DisableCoreFiles("disable-core-files", cl::Hidden,
+ cl::desc("Disable emission of core files if possible"));
+}
+
+static ExecutionEngine *EE = 0;
+
+static void do_shutdown() {
+ delete EE;
+ llvm_shutdown();
+}
+
+//===----------------------------------------------------------------------===//
+// main Driver function
+//
+int main(int argc, char **argv, char * const *envp) {
+ atexit(do_shutdown); // Call llvm_shutdown() on exit.
+ cl::ParseCommandLineOptions(argc, argv,
+ " llvm interpreter & dynamic compiler\n");
+ sys::PrintStackTraceOnErrorSignal();
+
+ // If the user doesn't want core files, disable them.
+ if (DisableCoreFiles)
+ sys::Process::PreventCoreFiles();
+
+ // Load the bitcode...
+ std::string ErrorMsg;
+ ModuleProvider *MP = 0;
+ if (MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFile,&ErrorMsg)){
+ MP = getBitcodeModuleProvider(Buffer, &ErrorMsg);
+ if (!MP) delete Buffer;
+ }
+
+ if (!MP) {
+ std::cerr << argv[0] << ": error loading program '" << InputFile << "': "
+ << ErrorMsg << "\n";
+ exit(1);
+ }
+
+ // Get the module as the MP could go away once EE takes over.
+ Module *Mod = MP->getModule();
+
+ // If we are supposed to override the target triple, do so now.
+ if (!TargetTriple.empty())
+ Mod->setTargetTriple(TargetTriple);
+
+ EE = ExecutionEngine::create(MP, ForceInterpreter, &ErrorMsg);
+ if (!EE && !ErrorMsg.empty()) {
+ std::cerr << argv[0] << ":error creating EE: " << ErrorMsg << "\n";
+ exit(1);
+ }
+
+ // If the user specifically requested an argv[0] to pass into the program,
+ // do it now.
+ if (!FakeArgv0.empty()) {
+ InputFile = FakeArgv0;
+ } else {
+ // Otherwise, if there is a .bc suffix on the executable strip it off, it
+ // might confuse the program.
+ if (InputFile.rfind(".bc") == InputFile.length() - 3)
+ InputFile.erase(InputFile.length() - 3);
+ }
+
+ // Add the module's name to the start of the vector of arguments to main().
+ InputArgv.insert(InputArgv.begin(), InputFile);
+
+ // Call the main function from M as if its signature were:
+ // int main (int argc, char **argv, const char **envp)
+ // using the contents of Args to determine argc & argv, and the contents of
+ // EnvVars to determine envp.
+ //
+ Function *Fn = Mod->getFunction("main");
+ if (!Fn) {
+ std::cerr << "'main' function not found in module.\n";
+ return -1;
+ }
+
+ // If the program doesn't explicitly call exit, we will need the Exit
+ // function later on to make an explicit call, so get the function now.
+ Constant *Exit = Mod->getOrInsertFunction("exit", Type::VoidTy,
+ Type::Int32Ty, NULL);
+
+ // Reset errno to zero on entry to main.
+ errno = 0;
+
+ // Run static constructors.
+ EE->runStaticConstructorsDestructors(false);
+
+ // Run main.
+ int Result = EE->runFunctionAsMain(Fn, InputArgv, envp);
+
+ // Run static destructors.
+ EE->runStaticConstructorsDestructors(true);
+
+ // If the program didn't call exit explicitly, we should call it now.
+ // This ensures that any atexit handlers get called correctly.
+ if (Function *ExitF = dyn_cast<Function>(Exit)) {
+ std::vector<GenericValue> Args;
+ GenericValue ResultGV;
+ ResultGV.IntVal = APInt(32, Result);
+ Args.push_back(ResultGV);
+ EE->runFunction(ExitF, Args);
+ std::cerr << "ERROR: exit(" << Result << ") returned!\n";
+ abort();
+ } else {
+ std::cerr << "ERROR: exit defined with wrong prototype!\n";
+ abort();
+ }
+}
diff --git a/tools/llvm-ar/Makefile b/tools/llvm-ar/Makefile
new file mode 100644
index 0000000..8936a49
--- /dev/null
+++ b/tools/llvm-ar/Makefile
@@ -0,0 +1,22 @@
+##===- tools/llvm-ar/Makefile ------------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file was developed by the LLVM research group and is distributed under
+# the University of Illinois Open Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+LEVEL = ../..
+
+TOOLNAME = llvm-ar
+LINK_COMPONENTS = archive
+REQUIRES_EH := 1
+
+include $(LEVEL)/Makefile.common
+
+check-local::
+ $(Echo) Checking llvm-ar
+ $(Verb) $(ToolDir)/llvm-ar zRrS nada.a .
+ $(Verb) $(ToolDir)/llvm-ar tv nada.a | \
+ grep Debug/llvm-ar.d >/dev/null 2>&1
+ $(Verb) $(RM) -f nada.a
diff --git a/tools/llvm-ar/llvm-ar.cpp b/tools/llvm-ar/llvm-ar.cpp
new file mode 100644
index 0000000..1d3ede6
--- /dev/null
+++ b/tools/llvm-ar/llvm-ar.cpp
@@ -0,0 +1,773 @@
+//===-- llvm-ar.cpp - LLVM archive librarian utility ----------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Builds up (relatively) standard unix archive files (.a) containing LLVM
+// bitcode or other files.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Module.h"
+#include "llvm/Bitcode/Archive.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/System/Signals.h"
+#include <iostream>
+#include <algorithm>
+#include <iomanip>
+#include <memory>
+using namespace llvm;
+
+// Option for compatibility with ASIX, not used but must allow it to be present.
+static cl::opt<bool>
+X32Option ("X32_64", cl::Hidden,
+ cl::desc("Ignored option for compatibility with AIX"));
+
+// llvm-ar operation code and modifier flags. This must come first.
+static cl::opt<std::string>
+Options(cl::Positional, cl::Required, cl::desc("{operation}[modifiers]..."));
+
+// llvm-ar remaining positional arguments.
+static cl::list<std::string>
+RestOfArgs(cl::Positional, cl::OneOrMore,
+ cl::desc("[relpos] [count] <archive-file> [members]..."));
+
+// MoreHelp - Provide additional help output explaining the operations and
+// modifiers of llvm-ar. This object instructs the CommandLine library
+// to print the text of the constructor when the --help option is given.
+static cl::extrahelp MoreHelp(
+ "\nOPERATIONS:\n"
+ " d[NsS] - delete file(s) from the archive\n"
+ " m[abiSs] - move file(s) in the archive\n"
+ " p[kN] - print file(s) found in the archive\n"
+ " q[ufsS] - quick append file(s) to the archive\n"
+ " r[abfiuzRsS] - replace or insert file(s) into the archive\n"
+ " t - display contents of archive\n"
+ " x[No] - extract file(s) from the archive\n"
+ "\nMODIFIERS (operation specific):\n"
+ " [a] - put file(s) after [relpos]\n"
+ " [b] - put file(s) before [relpos] (same as [i])\n"
+ " [f] - truncate inserted file names\n"
+ " [i] - put file(s) before [relpos] (same as [b])\n"
+ " [k] - always print bitcode files (default is to skip them)\n"
+ " [N] - use instance [count] of name\n"
+ " [o] - preserve original dates\n"
+ " [P] - use full path names when matching\n"
+ " [R] - recurse through directories when inserting\n"
+ " [s] - create an archive index (cf. ranlib)\n"
+ " [S] - do not build a symbol table\n"
+ " [u] - update only files newer than archive contents\n"
+ " [z] - compress files before inserting/extracting\n"
+ "\nMODIFIERS (generic):\n"
+ " [c] - do not warn if the library had to be created\n"
+ " [v] - be verbose about actions taken\n"
+ " [V] - be *really* verbose about actions taken\n"
+);
+
+// This enumeration delineates the kinds of operations on an archive
+// that are permitted.
+enum ArchiveOperation {
+ NoOperation, ///< An operation hasn't been specified
+ Print, ///< Print the contents of the archive
+ Delete, ///< Delete the specified members
+ Move, ///< Move members to end or as given by {a,b,i} modifiers
+ QuickAppend, ///< Quickly append to end of archive
+ ReplaceOrInsert, ///< Replace or Insert members
+ DisplayTable, ///< Display the table of contents
+ Extract ///< Extract files back to file system
+};
+
+// Modifiers to follow operation to vary behavior
+bool AddAfter = false; ///< 'a' modifier
+bool AddBefore = false; ///< 'b' modifier
+bool Create = false; ///< 'c' modifier
+bool TruncateNames = false; ///< 'f' modifier
+bool InsertBefore = false; ///< 'i' modifier
+bool DontSkipBitcode = false; ///< 'k' modifier
+bool UseCount = false; ///< 'N' modifier
+bool OriginalDates = false; ///< 'o' modifier
+bool FullPath = false; ///< 'P' modifier
+bool RecurseDirectories = false; ///< 'R' modifier
+bool SymTable = true; ///< 's' & 'S' modifiers
+bool OnlyUpdate = false; ///< 'u' modifier
+bool Verbose = false; ///< 'v' modifier
+bool ReallyVerbose = false; ///< 'V' modifier
+bool Compression = false; ///< 'z' modifier
+
+// Relative Positional Argument (for insert/move). This variable holds
+// the name of the archive member to which the 'a', 'b' or 'i' modifier
+// refers. Only one of 'a', 'b' or 'i' can be specified so we only need
+// one variable.
+std::string RelPos;
+
+// Select which of multiple entries in the archive with the same name should be
+// used (specified with -N) for the delete and extract operations.
+int Count = 1;
+
+// This variable holds the name of the archive file as given on the
+// command line.
+std::string ArchiveName;
+
+// This variable holds the list of member files to proecess, as given
+// on the command line.
+std::vector<std::string> Members;
+
+// This variable holds the (possibly expanded) list of path objects that
+// correspond to files we will
+std::set<sys::Path> Paths;
+
+// The Archive object to which all the editing operations will be sent.
+Archive* TheArchive = 0;
+
+// getRelPos - Extract the member filename from the command line for
+// the [relpos] argument associated with a, b, and i modifiers
+void getRelPos() {
+ if(RestOfArgs.size() > 0) {
+ RelPos = RestOfArgs[0];
+ RestOfArgs.erase(RestOfArgs.begin());
+ }
+ else
+ throw "Expected [relpos] for a, b, or i modifier";
+}
+
+// getCount - Extract the [count] argument associated with the N modifier
+// from the command line and check its value.
+void getCount() {
+ if(RestOfArgs.size() > 0) {
+ Count = atoi(RestOfArgs[0].c_str());
+ RestOfArgs.erase(RestOfArgs.begin());
+ }
+ else
+ throw "Expected [count] value with N modifier";
+
+ // Non-positive counts are not allowed
+ if (Count < 1)
+ throw "Invalid [count] value (not a positive integer)";
+}
+
+// getArchive - Get the archive file name from the command line
+void getArchive() {
+ if(RestOfArgs.size() > 0) {
+ ArchiveName = RestOfArgs[0];
+ RestOfArgs.erase(RestOfArgs.begin());
+ }
+ else
+ throw "An archive name must be specified.";
+}
+
+// getMembers - Copy over remaining items in RestOfArgs to our Members vector
+// This is just for clarity.
+void getMembers() {
+ if(RestOfArgs.size() > 0)
+ Members = std::vector<std::string>(RestOfArgs);
+}
+
+// parseCommandLine - Parse the command line options as presented and return the
+// operation specified. Process all modifiers and check to make sure that
+// constraints on modifier/operation pairs have not been violated.
+ArchiveOperation parseCommandLine() {
+
+ // Keep track of number of operations. We can only specify one
+ // per execution.
+ unsigned NumOperations = 0;
+
+ // Keep track of the number of positional modifiers (a,b,i). Only
+ // one can be specified.
+ unsigned NumPositional = 0;
+
+ // Keep track of which operation was requested
+ ArchiveOperation Operation = NoOperation;
+
+ for(unsigned i=0; i<Options.size(); ++i) {
+ switch(Options[i]) {
+ case 'd': ++NumOperations; Operation = Delete; break;
+ case 'm': ++NumOperations; Operation = Move ; break;
+ case 'p': ++NumOperations; Operation = Print; break;
+ case 'r': ++NumOperations; Operation = ReplaceOrInsert; break;
+ case 't': ++NumOperations; Operation = DisplayTable; break;
+ case 'x': ++NumOperations; Operation = Extract; break;
+ case 'c': Create = true; break;
+ case 'f': TruncateNames = true; break;
+ case 'k': DontSkipBitcode = true; break;
+ case 'l': /* accepted but unused */ break;
+ case 'o': OriginalDates = true; break;
+ case 'P': FullPath = true; break;
+ case 'R': RecurseDirectories = true; break;
+ case 's': SymTable = true; break;
+ case 'S': SymTable = false; break;
+ case 'u': OnlyUpdate = true; break;
+ case 'v': Verbose = true; break;
+ case 'V': Verbose = ReallyVerbose = true; break;
+ case 'z': Compression = true; break;
+ case 'a':
+ getRelPos();
+ AddAfter = true;
+ NumPositional++;
+ break;
+ case 'b':
+ getRelPos();
+ AddBefore = true;
+ NumPositional++;
+ break;
+ case 'i':
+ getRelPos();
+ InsertBefore = true;
+ NumPositional++;
+ break;
+ case 'N':
+ getCount();
+ UseCount = true;
+ break;
+ default:
+ cl::PrintHelpMessage();
+ }
+ }
+
+ // At this point, the next thing on the command line must be
+ // the archive name.
+ getArchive();
+
+ // Everything on the command line at this point is a member.
+ getMembers();
+
+ // Perform various checks on the operation/modifier specification
+ // to make sure we are dealing with a legal request.
+ if (NumOperations == 0)
+ throw "You must specify at least one of the operations";
+ if (NumOperations > 1)
+ throw "Only one operation may be specified";
+ if (NumPositional > 1)
+ throw "You may only specify one of a, b, and i modifiers";
+ if (AddAfter || AddBefore || InsertBefore)
+ if (Operation != Move && Operation != ReplaceOrInsert)
+ throw "The 'a', 'b' and 'i' modifiers can only be specified with "
+ "the 'm' or 'r' operations";
+ if (RecurseDirectories && Operation != ReplaceOrInsert)
+ throw "The 'R' modifiers is only applicabe to the 'r' operation";
+ if (OriginalDates && Operation != Extract)
+ throw "The 'o' modifier is only applicable to the 'x' operation";
+ if (TruncateNames && Operation!=QuickAppend && Operation!=ReplaceOrInsert)
+ throw "The 'f' modifier is only applicable to the 'q' and 'r' operations";
+ if (OnlyUpdate && Operation != ReplaceOrInsert)
+ throw "The 'u' modifier is only applicable to the 'r' operation";
+ if (Compression && Operation!=ReplaceOrInsert && Operation!=Extract)
+ throw "The 'z' modifier is only applicable to the 'r' and 'x' operations";
+ if (Count > 1 && Members.size() > 1)
+ throw "Only one member name may be specified with the 'N' modifier";
+
+ // Return the parsed operation to the caller
+ return Operation;
+}
+
+// recurseDirectories - Implements the "R" modifier. This function scans through
+// the Paths vector (built by buildPaths, below) and replaces any directories it
+// finds with all the files in that directory (recursively). It uses the
+// sys::Path::getDirectoryContent method to perform the actual directory scans.
+bool
+recurseDirectories(const sys::Path& path,
+ std::set<sys::Path>& result, std::string* ErrMsg) {
+ result.clear();
+ if (RecurseDirectories) {
+ std::set<sys::Path> content;
+ if (path.getDirectoryContents(content, ErrMsg))
+ return true;
+
+ for (std::set<sys::Path>::iterator I = content.begin(), E = content.end();
+ I != E; ++I) {
+ // Make sure it exists and is a directory
+ sys::PathWithStatus PwS(*I);
+ const sys::FileStatus *Status = PwS.getFileStatus(false, ErrMsg);
+ if (!Status)
+ return true;
+ if (Status->isDir) {
+ std::set<sys::Path> moreResults;
+ if (recurseDirectories(*I, moreResults, ErrMsg))
+ return true;
+ result.insert(moreResults.begin(), moreResults.end());
+ } else {
+ result.insert(*I);
+ }
+ }
+ }
+ return false;
+}
+
+// buildPaths - Convert the strings in the Members vector to sys::Path objects
+// and make sure they are valid and exist exist. This check is only needed for
+// the operations that add/replace files to the archive ('q' and 'r')
+bool buildPaths(bool checkExistence, std::string* ErrMsg) {
+ for (unsigned i = 0; i < Members.size(); i++) {
+ sys::Path aPath;
+ if (!aPath.set(Members[i]))
+ throw std::string("File member name invalid: ") + Members[i];
+ if (checkExistence) {
+ if (!aPath.exists())
+ throw std::string("File does not exist: ") + Members[i];
+ std::string Err;
+ sys::PathWithStatus PwS(aPath);
+ const sys::FileStatus *si = PwS.getFileStatus(false, &Err);
+ if (!si)
+ throw Err;
+ if (si->isDir) {
+ std::set<sys::Path> dirpaths;
+ if (recurseDirectories(aPath, dirpaths, ErrMsg))
+ return true;
+ Paths.insert(dirpaths.begin(),dirpaths.end());
+ } else {
+ Paths.insert(aPath);
+ }
+ } else {
+ Paths.insert(aPath);
+ }
+ }
+ return false;
+}
+
+// printSymbolTable - print out the archive's symbol table.
+void printSymbolTable() {
+ std::cout << "\nArchive Symbol Table:\n";
+ const Archive::SymTabType& symtab = TheArchive->getSymbolTable();
+ for (Archive::SymTabType::const_iterator I=symtab.begin(), E=symtab.end();
+ I != E; ++I ) {
+ unsigned offset = TheArchive->getFirstFileOffset() + I->second;
+ std::cout << " " << std::setw(9) << offset << "\t" << I->first <<"\n";
+ }
+}
+
+// doPrint - Implements the 'p' operation. This function traverses the archive
+// looking for members that match the path list. It is careful to uncompress
+// things that should be and to skip bitcode files unless the 'k' modifier was
+// given.
+bool doPrint(std::string* ErrMsg) {
+ if (buildPaths(false, ErrMsg))
+ return true;
+ unsigned countDown = Count;
+ for (Archive::iterator I = TheArchive->begin(), E = TheArchive->end();
+ I != E; ++I ) {
+ if (Paths.empty() ||
+ (std::find(Paths.begin(), Paths.end(), I->getPath()) != Paths.end())) {
+ if (countDown == 1) {
+ const char* data = reinterpret_cast<const char*>(I->getData());
+
+ // Skip things that don't make sense to print
+ if (I->isLLVMSymbolTable() || I->isSVR4SymbolTable() ||
+ I->isBSD4SymbolTable() || (!DontSkipBitcode && I->isBitcode()))
+ continue;
+
+ if (Verbose)
+ std::cout << "Printing " << I->getPath().toString() << "\n";
+
+ unsigned len = I->getSize();
+ std::cout.write(data, len);
+ } else {
+ countDown--;
+ }
+ }
+ }
+ return false;
+}
+
+// putMode - utility function for printing out the file mode when the 't'
+// operation is in verbose mode.
+void
+printMode(unsigned mode) {
+ if (mode & 004)
+ std::cout << "r";
+ else
+ std::cout << "-";
+ if (mode & 002)
+ std::cout << "w";
+ else
+ std::cout << "-";
+ if (mode & 001)
+ std::cout << "x";
+ else
+ std::cout << "-";
+}
+
+// doDisplayTable - Implement the 't' operation. This function prints out just
+// the file names of each of the members. However, if verbose mode is requested
+// ('v' modifier) then the file type, permission mode, user, group, size, and
+// modification time are also printed.
+bool
+doDisplayTable(std::string* ErrMsg) {
+ if (buildPaths(false, ErrMsg))
+ return true;
+ for (Archive::iterator I = TheArchive->begin(), E = TheArchive->end();
+ I != E; ++I ) {
+ if (Paths.empty() ||
+ (std::find(Paths.begin(), Paths.end(), I->getPath()) != Paths.end())) {
+ if (Verbose) {
+ // FIXME: Output should be this format:
+ // Zrw-r--r-- 500/ 500 525 Nov 8 17:42 2004 Makefile
+ if (I->isBitcode())
+ std::cout << "b";
+ else if (I->isCompressed())
+ std::cout << "Z";
+ else
+ std::cout << " ";
+ unsigned mode = I->getMode();
+ printMode((mode >> 6) & 007);
+ printMode((mode >> 3) & 007);
+ printMode(mode & 007);
+ std::cout << " " << std::setw(4) << I->getUser();
+ std::cout << "/" << std::setw(4) << I->getGroup();
+ std::cout << " " << std::setw(8) << I->getSize();
+ std::cout << " " << std::setw(20) <<
+ I->getModTime().toString().substr(4);
+ std::cout << " " << I->getPath().toString() << "\n";
+ } else {
+ std::cout << I->getPath().toString() << "\n";
+ }
+ }
+ }
+ if (ReallyVerbose)
+ printSymbolTable();
+ return false;
+}
+
+// doExtract - Implement the 'x' operation. This function extracts files back to
+// the file system, making sure to uncompress any that were compressed
+bool
+doExtract(std::string* ErrMsg) {
+ if (buildPaths(false, ErrMsg))
+ return true;
+ for (Archive::iterator I = TheArchive->begin(), E = TheArchive->end();
+ I != E; ++I ) {
+ if (Paths.empty() ||
+ (std::find(Paths.begin(), Paths.end(), I->getPath()) != Paths.end())) {
+
+ // Make sure the intervening directories are created
+ if (I->hasPath()) {
+ sys::Path dirs(I->getPath());
+ dirs.eraseComponent();
+ if (dirs.createDirectoryOnDisk(/*create_parents=*/true, ErrMsg))
+ return true;
+ }
+
+ // Open up a file stream for writing
+ std::ios::openmode io_mode = std::ios::out | std::ios::trunc |
+ std::ios::binary;
+ std::ofstream file(I->getPath().c_str(), io_mode);
+
+ // Get the data and its length
+ const char* data = reinterpret_cast<const char*>(I->getData());
+ unsigned len = I->getSize();
+
+ // Write the data.
+ file.write(data,len);
+ file.close();
+
+ // If we're supposed to retain the original modification times, etc. do so
+ // now.
+ if (OriginalDates)
+ I->getPath().setStatusInfoOnDisk(I->getFileStatus());
+ }
+ }
+ return false;
+}
+
+// doDelete - Implement the delete operation. This function deletes zero or more
+// members from the archive. Note that if the count is specified, there should
+// be no more than one path in the Paths list or else this algorithm breaks.
+// That check is enforced in parseCommandLine (above).
+bool
+doDelete(std::string* ErrMsg) {
+ if (buildPaths(false, ErrMsg))
+ return true;
+ if (Paths.empty())
+ return false;
+ unsigned countDown = Count;
+ for (Archive::iterator I = TheArchive->begin(), E = TheArchive->end();
+ I != E; ) {
+ if (std::find(Paths.begin(), Paths.end(), I->getPath()) != Paths.end()) {
+ if (countDown == 1) {
+ Archive::iterator J = I;
+ ++I;
+ TheArchive->erase(J);
+ } else
+ countDown--;
+ } else {
+ ++I;
+ }
+ }
+
+ // We're done editting, reconstruct the archive.
+ if (TheArchive->writeToDisk(SymTable,TruncateNames,Compression,ErrMsg))
+ return true;
+ if (ReallyVerbose)
+ printSymbolTable();
+ return false;
+}
+
+// doMore - Implement the move operation. This function re-arranges just the
+// order of the archive members so that when the archive is written the move
+// of the members is accomplished. Note the use of the RelPos variable to
+// determine where the items should be moved to.
+bool
+doMove(std::string* ErrMsg) {
+ if (buildPaths(false, ErrMsg))
+ return true;
+
+ // By default and convention the place to move members to is the end of the
+ // archive.
+ Archive::iterator moveto_spot = TheArchive->end();
+
+ // However, if the relative positioning modifiers were used, we need to scan
+ // the archive to find the member in question. If we don't find it, its no
+ // crime, we just move to the end.
+ if (AddBefore || InsertBefore || AddAfter) {
+ for (Archive::iterator I = TheArchive->begin(), E= TheArchive->end();
+ I != E; ++I ) {
+ if (RelPos == I->getPath().toString()) {
+ if (AddAfter) {
+ moveto_spot = I;
+ moveto_spot++;
+ } else {
+ moveto_spot = I;
+ }
+ break;
+ }
+ }
+ }
+
+ // Keep a list of the paths remaining to be moved
+ std::set<sys::Path> remaining(Paths);
+
+ // Scan the archive again, this time looking for the members to move to the
+ // moveto_spot.
+ for (Archive::iterator I = TheArchive->begin(), E= TheArchive->end();
+ I != E && !remaining.empty(); ++I ) {
+ std::set<sys::Path>::iterator found =
+ std::find(remaining.begin(),remaining.end(),I->getPath());
+ if (found != remaining.end()) {
+ if (I != moveto_spot)
+ TheArchive->splice(moveto_spot,*TheArchive,I);
+ remaining.erase(found);
+ }
+ }
+
+ // We're done editting, reconstruct the archive.
+ if (TheArchive->writeToDisk(SymTable,TruncateNames,Compression,ErrMsg))
+ return true;
+ if (ReallyVerbose)
+ printSymbolTable();
+ return false;
+}
+
+// doQuickAppend - Implements the 'q' operation. This function just
+// indiscriminantly adds the members to the archive and rebuilds it.
+bool
+doQuickAppend(std::string* ErrMsg) {
+ // Get the list of paths to append.
+ if (buildPaths(true, ErrMsg))
+ return true;
+ if (Paths.empty())
+ return false;
+
+ // Append them quickly.
+ for (std::set<sys::Path>::iterator PI = Paths.begin(), PE = Paths.end();
+ PI != PE; ++PI) {
+ if (TheArchive->addFileBefore(*PI,TheArchive->end(),ErrMsg))
+ return true;
+ }
+
+ // We're done editting, reconstruct the archive.
+ if (TheArchive->writeToDisk(SymTable,TruncateNames,Compression,ErrMsg))
+ return true;
+ if (ReallyVerbose)
+ printSymbolTable();
+ return false;
+}
+
+// doReplaceOrInsert - Implements the 'r' operation. This function will replace
+// any existing files or insert new ones into the archive.
+bool
+doReplaceOrInsert(std::string* ErrMsg) {
+
+ // Build the list of files to be added/replaced.
+ if (buildPaths(true, ErrMsg))
+ return true;
+ if (Paths.empty())
+ return false;
+
+ // Keep track of the paths that remain to be inserted.
+ std::set<sys::Path> remaining(Paths);
+
+ // Default the insertion spot to the end of the archive
+ Archive::iterator insert_spot = TheArchive->end();
+
+ // Iterate over the archive contents
+ for (Archive::iterator I = TheArchive->begin(), E = TheArchive->end();
+ I != E && !remaining.empty(); ++I ) {
+
+ // Determine if this archive member matches one of the paths we're trying
+ // to replace.
+
+ std::set<sys::Path>::iterator found = remaining.end();
+ for (std::set<sys::Path>::iterator RI = remaining.begin(),
+ RE = remaining.end(); RI != RE; ++RI ) {
+ std::string compare(RI->toString());
+ if (TruncateNames && compare.length() > 15) {
+ const char* nm = compare.c_str();
+ unsigned len = compare.length();
+ size_t slashpos = compare.rfind('/');
+ if (slashpos != std::string::npos) {
+ nm += slashpos + 1;
+ len -= slashpos +1;
+ }
+ if (len > 15)
+ len = 15;
+ compare.assign(nm,len);
+ }
+ if (compare == I->getPath().toString()) {
+ found = RI;
+ break;
+ }
+ }
+
+ if (found != remaining.end()) {
+ std::string Err;
+ sys::PathWithStatus PwS(*found);
+ const sys::FileStatus *si = PwS.getFileStatus(false, &Err);
+ if (!si)
+ return true;
+ if (si->isDir) {
+ if (OnlyUpdate) {
+ // Replace the item only if it is newer.
+ if (si->modTime > I->getModTime())
+ if (I->replaceWith(*found, ErrMsg))
+ return true;
+ } else {
+ // Replace the item regardless of time stamp
+ if (I->replaceWith(*found, ErrMsg))
+ return true;
+ }
+ } else {
+ // We purposefully ignore directories.
+ }
+
+ // Remove it from our "to do" list
+ remaining.erase(found);
+ }
+
+ // Determine if this is the place where we should insert
+ if ((AddBefore || InsertBefore) && (RelPos == I->getPath().toString()))
+ insert_spot = I;
+ else if (AddAfter && (RelPos == I->getPath().toString())) {
+ insert_spot = I;
+ insert_spot++;
+ }
+ }
+
+ // If we didn't replace all the members, some will remain and need to be
+ // inserted at the previously computed insert-spot.
+ if (!remaining.empty()) {
+ for (std::set<sys::Path>::iterator PI = remaining.begin(),
+ PE = remaining.end(); PI != PE; ++PI) {
+ if (TheArchive->addFileBefore(*PI,insert_spot, ErrMsg))
+ return true;
+ }
+ }
+
+ // We're done editting, reconstruct the archive.
+ if (TheArchive->writeToDisk(SymTable,TruncateNames,Compression,ErrMsg))
+ return true;
+ if (ReallyVerbose)
+ printSymbolTable();
+ return false;
+}
+
+// main - main program for llvm-ar .. see comments in the code
+int main(int argc, char **argv) {
+ llvm_shutdown_obj X; // Call llvm_shutdown() on exit.
+
+ // Have the command line options parsed and handle things
+ // like --help and --version.
+ cl::ParseCommandLineOptions(argc, argv,
+ " LLVM Archiver (llvm-ar)\n\n"
+ " This program archives bitcode files into single libraries\n"
+ );
+
+ // Print a stack trace if we signal out.
+ sys::PrintStackTraceOnErrorSignal();
+
+ int exitCode = 0;
+
+ // Make sure we don't exit with "unhandled exception".
+ try {
+ // Do our own parsing of the command line because the CommandLine utility
+ // can't handle the grouped positional parameters without a dash.
+ ArchiveOperation Operation = parseCommandLine();
+
+ // Check the path name of the archive
+ sys::Path ArchivePath;
+ if (!ArchivePath.set(ArchiveName))
+ throw std::string("Archive name invalid: ") + ArchiveName;
+
+ // Create or open the archive object.
+ if (!ArchivePath.exists()) {
+ // Produce a warning if we should and we're creating the archive
+ if (!Create)
+ std::cerr << argv[0] << ": creating " << ArchivePath.toString() << "\n";
+ TheArchive = Archive::CreateEmpty(ArchivePath);
+ } else {
+ std::string Error;
+ TheArchive = Archive::OpenAndLoad(ArchivePath, &Error);
+ if (TheArchive == 0) {
+ std::cerr << argv[0] << ": error loading '" << ArchivePath << "': "
+ << Error << "!\n";
+ return 1;
+ }
+ }
+
+ // Make sure we're not fooling ourselves.
+ assert(TheArchive && "Unable to instantiate the archive");
+
+ // Make sure we clean up the archive even on failure.
+ std::auto_ptr<Archive> AutoArchive(TheArchive);
+
+ // Perform the operation
+ std::string ErrMsg;
+ bool haveError = false;
+ switch (Operation) {
+ case Print: haveError = doPrint(&ErrMsg); break;
+ case Delete: haveError = doDelete(&ErrMsg); break;
+ case Move: haveError = doMove(&ErrMsg); break;
+ case QuickAppend: haveError = doQuickAppend(&ErrMsg); break;
+ case ReplaceOrInsert: haveError = doReplaceOrInsert(&ErrMsg); break;
+ case DisplayTable: haveError = doDisplayTable(&ErrMsg); break;
+ case Extract: haveError = doExtract(&ErrMsg); break;
+ case NoOperation:
+ std::cerr << argv[0] << ": No operation was selected.\n";
+ break;
+ }
+ if (haveError) {
+ std::cerr << argv[0] << ": " << ErrMsg << "\n";
+ return 1;
+ }
+ } catch (const char*msg) {
+ // These errors are usage errors, thrown only by the various checks in the
+ // code above.
+ std::cerr << argv[0] << ": " << msg << "\n\n";
+ cl::PrintHelpMessage();
+ exitCode = 1;
+ } catch (const std::string& msg) {
+ // These errors are thrown by LLVM libraries (e.g. lib System) and represent
+ // a more serious error so we bump the exitCode and don't print the usage.
+ std::cerr << argv[0] << ": " << msg << "\n";
+ exitCode = 2;
+ } catch (...) {
+ // This really shouldn't happen, but just in case ....
+ std::cerr << argv[0] << ": An unexpected unknown exception occurred.\n";
+ exitCode = 3;
+ }
+
+ // Return result code back to operating system.
+ return exitCode;
+}
diff --git a/tools/llvm-as/Makefile b/tools/llvm-as/Makefile
new file mode 100644
index 0000000..c86b900
--- /dev/null
+++ b/tools/llvm-as/Makefile
@@ -0,0 +1,15 @@
+##===- tools/llvm-as/Makefile ------------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file was developed by the LLVM research group and is distributed under
+# the University of Illinois Open Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../..
+TOOLNAME = llvm-as
+LINK_COMPONENTS := asmparser bitwriter
+REQUIRES_EH := 1
+
+include $(LEVEL)/Makefile.common
diff --git a/tools/llvm-as/llvm-as.cpp b/tools/llvm-as/llvm-as.cpp
new file mode 100644
index 0000000..41b6846
--- /dev/null
+++ b/tools/llvm-as/llvm-as.cpp
@@ -0,0 +1,141 @@
+//===--- llvm-as.cpp - The low-level LLVM assembler -----------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This utility may be invoked in the following manner:
+// llvm-as --help - Output information about command line switches
+// llvm-as [options] - Read LLVM asm from stdin, write bitcode to stdout
+// llvm-as [options] x.ll - Read LLVM asm from the x.ll file, write bitcode
+// to the x.bc file.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Module.h"
+#include "llvm/Assembly/Parser.h"
+#include "llvm/Analysis/Verifier.h"
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/Streams.h"
+#include "llvm/Support/SystemUtils.h"
+#include "llvm/System/Signals.h"
+#include <fstream>
+#include <iostream>
+#include <memory>
+using namespace llvm;
+
+static cl::opt<std::string>
+InputFilename(cl::Positional, cl::desc("<input .llvm file>"), cl::init("-"));
+
+static cl::opt<std::string>
+OutputFilename("o", cl::desc("Override output filename"),
+ cl::value_desc("filename"));
+
+static cl::opt<bool>
+Force("f", cl::desc("Overwrite output files"));
+
+static cl::opt<bool>
+DumpAsm("d", cl::desc("Print assembly as parsed"), cl::Hidden);
+
+static cl::opt<bool>
+DisableVerify("disable-verify", cl::Hidden,
+ cl::desc("Do not run verifier on input LLVM (dangerous!)"));
+
+int main(int argc, char **argv) {
+ llvm_shutdown_obj X; // Call llvm_shutdown() on exit.
+ cl::ParseCommandLineOptions(argc, argv, " llvm .ll -> .bc assembler\n");
+ sys::PrintStackTraceOnErrorSignal();
+
+ int exitCode = 0;
+ std::ostream *Out = 0;
+ try {
+ // Parse the file now...
+ ParseError Err;
+ std::auto_ptr<Module> M(ParseAssemblyFile(InputFilename,&Err));
+ if (M.get() == 0) {
+ cerr << argv[0] << ": " << Err.getMessage() << "\n";
+ return 1;
+ }
+
+ if (!DisableVerify) {
+ std::string Err;
+ if (verifyModule(*M.get(), ReturnStatusAction, &Err)) {
+ cerr << argv[0]
+ << ": assembly parsed, but does not verify as correct!\n";
+ cerr << Err;
+ return 1;
+ }
+ }
+
+ if (DumpAsm) cerr << "Here's the assembly:\n" << *M.get();
+
+ if (OutputFilename != "") { // Specified an output filename?
+ if (OutputFilename != "-") { // Not stdout?
+ if (!Force && std::ifstream(OutputFilename.c_str())) {
+ // If force is not specified, make sure not to overwrite a file!
+ cerr << argv[0] << ": error opening '" << OutputFilename
+ << "': file exists!\n"
+ << "Use -f command line argument to force output\n";
+ return 1;
+ }
+ Out = new std::ofstream(OutputFilename.c_str(), std::ios::out |
+ std::ios::trunc | std::ios::binary);
+ } else { // Specified stdout
+ // FIXME: cout is not binary!
+ Out = &std::cout;
+ }
+ } else {
+ if (InputFilename == "-") {
+ OutputFilename = "-";
+ Out = &std::cout;
+ } else {
+ std::string IFN = InputFilename;
+ int Len = IFN.length();
+ if (IFN[Len-3] == '.' && IFN[Len-2] == 'l' && IFN[Len-1] == 'l') {
+ // Source ends in .ll
+ OutputFilename = std::string(IFN.begin(), IFN.end()-3);
+ } else {
+ OutputFilename = IFN; // Append a .bc to it
+ }
+ OutputFilename += ".bc";
+
+ if (!Force && std::ifstream(OutputFilename.c_str())) {
+ // If force is not specified, make sure not to overwrite a file!
+ cerr << argv[0] << ": error opening '" << OutputFilename
+ << "': file exists!\n"
+ << "Use -f command line argument to force output\n";
+ return 1;
+ }
+
+ Out = new std::ofstream(OutputFilename.c_str(), std::ios::out |
+ std::ios::trunc | std::ios::binary);
+ // Make sure that the Out file gets unlinked from the disk if we get a
+ // SIGINT
+ sys::RemoveFileOnSignal(sys::Path(OutputFilename));
+ }
+ }
+
+ if (!Out->good()) {
+ cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
+ return 1;
+ }
+
+ if (Force || !CheckBitcodeOutputToConsole(Out,true))
+ WriteBitcodeToFile(M.get(), *Out);
+ } catch (const std::string& msg) {
+ cerr << argv[0] << ": " << msg << "\n";
+ exitCode = 1;
+ } catch (...) {
+ cerr << argv[0] << ": Unexpected unknown exception occurred.\n";
+ exitCode = 1;
+ }
+
+ if (Out != &std::cout) delete Out;
+ return exitCode;
+}
+
diff --git a/tools/llvm-bcanalyzer/Makefile b/tools/llvm-bcanalyzer/Makefile
new file mode 100644
index 0000000..b5747cf
--- /dev/null
+++ b/tools/llvm-bcanalyzer/Makefile
@@ -0,0 +1,15 @@
+##===- tools/llvm-bcanalyzer/Makefile ----------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file was developed by Reid Spencer and is distributed under the
+# University of Illinois Open Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+LEVEL = ../..
+
+TOOLNAME = llvm-bcanalyzer
+LINK_COMPONENTS := bitreader
+REQUIRES_EH := 1
+
+include $(LEVEL)/Makefile.common
diff --git a/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp b/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
new file mode 100644
index 0000000..126a2ed
--- /dev/null
+++ b/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
@@ -0,0 +1,504 @@
+//===-- llvm-bcanalyzer.cpp - Bitcode Analyzer --------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This tool may be invoked in the following manner:
+// llvm-bcanalyzer [options] - Read LLVM bitcode from stdin
+// llvm-bcanalyzer [options] x.bc - Read LLVM bitcode from the x.bc file
+//
+// Options:
+// --help - Output information about command line switches
+// --dump - Dump low-level bitcode structure in readable format
+//
+// This tool provides analytical information about a bitcode file. It is
+// intended as an aid to developers of bitcode reading and writing software. It
+// produces on std::out a summary of the bitcode file that shows various
+// statistics about the contents of the file. By default this information is
+// detailed and contains information about individual bitcode blocks and the
+// functions in the module.
+// The tool is also able to print a bitcode file in a straight forward text
+// format that shows the containment and relationships of the information in
+// the bitcode file (-dump option).
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/Verifier.h"
+#include "llvm/Bitcode/BitstreamReader.h"
+#include "llvm/Bitcode/LLVMBitCodes.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/System/Signals.h"
+#include <map>
+#include <fstream>
+#include <iostream>
+#include <algorithm>
+using namespace llvm;
+
+static cl::opt<std::string>
+ InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-"));
+
+static cl::opt<std::string>
+ OutputFilename("-o", cl::init("-"), cl::desc("<output file>"));
+
+static cl::opt<bool> Dump("dump", cl::desc("Dump low level bitcode trace"));
+
+//===----------------------------------------------------------------------===//
+// Bitcode specific analysis.
+//===----------------------------------------------------------------------===//
+
+static cl::opt<bool> NoHistogram("disable-histogram",
+ cl::desc("Do not print per-code histogram"));
+
+static cl::opt<bool>
+NonSymbolic("non-symbolic",
+ cl::desc("Emit numberic info in dump even if"
+ " symbolic info is available"));
+
+/// CurStreamType - If we can sniff the flavor of this stream, we can produce
+/// better dump info.
+static enum {
+ UnknownBitstream,
+ LLVMIRBitstream
+} CurStreamType;
+
+
+/// GetBlockName - Return a symbolic block name if known, otherwise return
+/// null.
+static const char *GetBlockName(unsigned BlockID) {
+ // Standard blocks for all bitcode files.
+ if (BlockID < bitc::FIRST_APPLICATION_BLOCKID) {
+ if (BlockID == bitc::BLOCKINFO_BLOCK_ID)
+ return "BLOCKINFO_BLOCK";
+ return 0;
+ }
+
+ if (CurStreamType != LLVMIRBitstream) return 0;
+
+ switch (BlockID) {
+ default: return 0;
+ case bitc::MODULE_BLOCK_ID: return "MODULE_BLOCK";
+ case bitc::PARAMATTR_BLOCK_ID: return "PARAMATTR_BLOCK";
+ case bitc::TYPE_BLOCK_ID: return "TYPE_BLOCK";
+ case bitc::CONSTANTS_BLOCK_ID: return "CONSTANTS_BLOCK";
+ case bitc::FUNCTION_BLOCK_ID: return "FUNCTION_BLOCK";
+ case bitc::TYPE_SYMTAB_BLOCK_ID: return "TYPE_SYMTAB";
+ case bitc::VALUE_SYMTAB_BLOCK_ID: return "VALUE_SYMTAB";
+ }
+}
+
+/// GetCodeName - Return a symbolic code name if known, otherwise return
+/// null.
+static const char *GetCodeName(unsigned CodeID, unsigned BlockID) {
+ // Standard blocks for all bitcode files.
+ if (BlockID < bitc::FIRST_APPLICATION_BLOCKID) {
+ if (BlockID == bitc::BLOCKINFO_BLOCK_ID) {
+ switch (CodeID) {
+ default: return 0;
+ case bitc::MODULE_CODE_VERSION: return "VERSION";
+ }
+ }
+ return 0;
+ }
+
+ if (CurStreamType != LLVMIRBitstream) return 0;
+
+ switch (BlockID) {
+ default: return 0;
+ case bitc::MODULE_BLOCK_ID:
+ switch (CodeID) {
+ default: return 0;
+ case bitc::MODULE_CODE_VERSION: return "VERSION";
+ case bitc::MODULE_CODE_TRIPLE: return "TRIPLE";
+ case bitc::MODULE_CODE_DATALAYOUT: return "DATALAYOUT";
+ case bitc::MODULE_CODE_ASM: return "ASM";
+ case bitc::MODULE_CODE_SECTIONNAME: return "SECTIONNAME";
+ case bitc::MODULE_CODE_DEPLIB: return "DEPLIB";
+ case bitc::MODULE_CODE_GLOBALVAR: return "GLOBALVAR";
+ case bitc::MODULE_CODE_FUNCTION: return "FUNCTION";
+ case bitc::MODULE_CODE_ALIAS: return "ALIAS";
+ case bitc::MODULE_CODE_PURGEVALS: return "PURGEVALS";
+ }
+ case bitc::PARAMATTR_BLOCK_ID:
+ switch (CodeID) {
+ default: return 0;
+ case bitc::PARAMATTR_CODE_ENTRY: return "ENTRY";
+ }
+ case bitc::TYPE_BLOCK_ID:
+ switch (CodeID) {
+ default: return 0;
+ case bitc::TYPE_CODE_NUMENTRY: return "NUMENTRY";
+ case bitc::TYPE_CODE_VOID: return "VOID";
+ case bitc::TYPE_CODE_FLOAT: return "FLOAT";
+ case bitc::TYPE_CODE_DOUBLE: return "DOUBLE";
+ case bitc::TYPE_CODE_LABEL: return "LABEL";
+ case bitc::TYPE_CODE_OPAQUE: return "OPAQUE";
+ case bitc::TYPE_CODE_INTEGER: return "INTEGER";
+ case bitc::TYPE_CODE_POINTER: return "POINTER";
+ case bitc::TYPE_CODE_FUNCTION: return "FUNCTION";
+ case bitc::TYPE_CODE_STRUCT: return "STRUCT";
+ case bitc::TYPE_CODE_ARRAY: return "ARRAY";
+ case bitc::TYPE_CODE_VECTOR: return "VECTOR";
+ }
+
+ case bitc::CONSTANTS_BLOCK_ID:
+ switch (CodeID) {
+ default: return 0;
+ case bitc::CST_CODE_SETTYPE: return "SETTYPE";
+ case bitc::CST_CODE_NULL: return "NULL";
+ case bitc::CST_CODE_UNDEF: return "UNDEF";
+ case bitc::CST_CODE_INTEGER: return "INTEGER";
+ case bitc::CST_CODE_WIDE_INTEGER: return "WIDE_INTEGER";
+ case bitc::CST_CODE_FLOAT: return "FLOAT";
+ case bitc::CST_CODE_AGGREGATE: return "AGGREGATE";
+ case bitc::CST_CODE_STRING: return "STRING";
+ case bitc::CST_CODE_CSTRING: return "CSTRING";
+ case bitc::CST_CODE_CE_BINOP: return "CE_BINOP";
+ case bitc::CST_CODE_CE_CAST: return "CE_CAST";
+ case bitc::CST_CODE_CE_GEP: return "CE_GEP";
+ case bitc::CST_CODE_CE_SELECT: return "CE_SELECT";
+ case bitc::CST_CODE_CE_EXTRACTELT: return "CE_EXTRACTELT";
+ case bitc::CST_CODE_CE_INSERTELT: return "CE_INSERTELT";
+ case bitc::CST_CODE_CE_SHUFFLEVEC: return "CE_SHUFFLEVEC";
+ case bitc::CST_CODE_CE_CMP: return "CE_CMP";
+ case bitc::CST_CODE_INLINEASM: return "INLINEASM";
+ }
+ case bitc::FUNCTION_BLOCK_ID:
+ switch (CodeID) {
+ default: return 0;
+ case bitc::FUNC_CODE_DECLAREBLOCKS: return "DECLAREBLOCKS";
+
+ case bitc::FUNC_CODE_INST_BINOP: return "INST_BINOP";
+ case bitc::FUNC_CODE_INST_CAST: return "INST_CAST";
+ case bitc::FUNC_CODE_INST_GEP: return "INST_GEP";
+ case bitc::FUNC_CODE_INST_SELECT: return "INST_SELECT";
+ case bitc::FUNC_CODE_INST_EXTRACTELT: return "INST_EXTRACTELT";
+ case bitc::FUNC_CODE_INST_INSERTELT: return "INST_INSERTELT";
+ case bitc::FUNC_CODE_INST_SHUFFLEVEC: return "INST_SHUFFLEVEC";
+ case bitc::FUNC_CODE_INST_CMP: return "INST_CMP";
+
+ case bitc::FUNC_CODE_INST_RET: return "INST_RET";
+ case bitc::FUNC_CODE_INST_BR: return "INST_BR";
+ case bitc::FUNC_CODE_INST_SWITCH: return "INST_SWITCH";
+ case bitc::FUNC_CODE_INST_INVOKE: return "INST_INVOKE";
+ case bitc::FUNC_CODE_INST_UNWIND: return "INST_UNWIND";
+ case bitc::FUNC_CODE_INST_UNREACHABLE: return "INST_UNREACHABLE";
+
+ case bitc::FUNC_CODE_INST_PHI: return "INST_PHI";
+ case bitc::FUNC_CODE_INST_MALLOC: return "INST_MALLOC";
+ case bitc::FUNC_CODE_INST_FREE: return "INST_FREE";
+ case bitc::FUNC_CODE_INST_ALLOCA: return "INST_ALLOCA";
+ case bitc::FUNC_CODE_INST_LOAD: return "INST_LOAD";
+ case bitc::FUNC_CODE_INST_STORE: return "INST_STORE";
+ case bitc::FUNC_CODE_INST_CALL: return "INST_CALL";
+ case bitc::FUNC_CODE_INST_VAARG: return "INST_VAARG";
+ }
+ case bitc::TYPE_SYMTAB_BLOCK_ID:
+ switch (CodeID) {
+ default: return 0;
+ case bitc::TST_CODE_ENTRY: return "ENTRY";
+ }
+ case bitc::VALUE_SYMTAB_BLOCK_ID:
+ switch (CodeID) {
+ default: return 0;
+ case bitc::VST_CODE_ENTRY: return "ENTRY";
+ case bitc::VST_CODE_BBENTRY: return "BBENTRY";
+ }
+ }
+}
+
+
+struct PerBlockIDStats {
+ /// NumInstances - This the number of times this block ID has been seen.
+ unsigned NumInstances;
+
+ /// NumBits - The total size in bits of all of these blocks.
+ uint64_t NumBits;
+
+ /// NumSubBlocks - The total number of blocks these blocks contain.
+ unsigned NumSubBlocks;
+
+ /// NumAbbrevs - The total number of abbreviations.
+ unsigned NumAbbrevs;
+
+ /// NumRecords - The total number of records these blocks contain, and the
+ /// number that are abbreviated.
+ unsigned NumRecords, NumAbbreviatedRecords;
+
+ /// CodeFreq - Keep track of the number of times we see each code.
+ std::vector<unsigned> CodeFreq;
+
+ PerBlockIDStats()
+ : NumInstances(0), NumBits(0),
+ NumSubBlocks(0), NumAbbrevs(0), NumRecords(0), NumAbbreviatedRecords(0) {}
+};
+
+static std::map<unsigned, PerBlockIDStats> BlockIDStats;
+
+
+
+/// Error - All bitcode analysis errors go through this function, making this a
+/// good place to breakpoint if debugging.
+static bool Error(const std::string &Err) {
+ std::cerr << Err << "\n";
+ return true;
+}
+
+/// ParseBlock - Read a block, updating statistics, etc.
+static bool ParseBlock(BitstreamReader &Stream, unsigned IndentLevel) {
+ std::string Indent(IndentLevel*2, ' ');
+ uint64_t BlockBitStart = Stream.GetCurrentBitNo();
+ unsigned BlockID = Stream.ReadSubBlockID();
+
+ // Get the statistics for this BlockID.
+ PerBlockIDStats &BlockStats = BlockIDStats[BlockID];
+
+ BlockStats.NumInstances++;
+
+ // BLOCKINFO is a special part of the stream.
+ if (BlockID == bitc::BLOCKINFO_BLOCK_ID) {
+ if (Dump) std::cerr << Indent << "<BLOCKINFO_BLOCK/>\n";
+ if (Stream.ReadBlockInfoBlock())
+ return Error("Malformed BlockInfoBlock");
+ uint64_t BlockBitEnd = Stream.GetCurrentBitNo();
+ BlockStats.NumBits += BlockBitEnd-BlockBitStart;
+ return false;
+ }
+
+ unsigned NumWords = 0;
+ if (Stream.EnterSubBlock(BlockID, &NumWords))
+ return Error("Malformed block record");
+
+ const char *BlockName = 0;
+ if (Dump) {
+ std::cerr << Indent << "<";
+ if ((BlockName = GetBlockName(BlockID)))
+ std::cerr << BlockName;
+ else
+ std::cerr << "UnknownBlock" << BlockID;
+
+ if (NonSymbolic && BlockName)
+ std::cerr << " BlockID=" << BlockID;
+
+ std::cerr << " NumWords=" << NumWords
+ << " BlockCodeSize=" << Stream.GetAbbrevIDWidth() << ">\n";
+ }
+
+ SmallVector<uint64_t, 64> Record;
+
+ // Read all the records for this block.
+ while (1) {
+ if (Stream.AtEndOfStream())
+ return Error("Premature end of bitstream");
+
+ // Read the code for this record.
+ unsigned AbbrevID = Stream.ReadCode();
+ switch (AbbrevID) {
+ case bitc::END_BLOCK: {
+ if (Stream.ReadBlockEnd())
+ return Error("Error at end of block");
+ uint64_t BlockBitEnd = Stream.GetCurrentBitNo();
+ BlockStats.NumBits += BlockBitEnd-BlockBitStart;
+ if (Dump) {
+ std::cerr << Indent << "</";
+ if (BlockName)
+ std::cerr << BlockName << ">\n";
+ else
+ std::cerr << "UnknownBlock" << BlockID << ">\n";
+ }
+ return false;
+ }
+ case bitc::ENTER_SUBBLOCK: {
+ uint64_t SubBlockBitStart = Stream.GetCurrentBitNo();
+ if (ParseBlock(Stream, IndentLevel+1))
+ return true;
+ ++BlockStats.NumSubBlocks;
+ uint64_t SubBlockBitEnd = Stream.GetCurrentBitNo();
+
+ // Don't include subblock sizes in the size of this block.
+ BlockBitStart += SubBlockBitEnd-SubBlockBitStart;
+ break;
+ }
+ case bitc::DEFINE_ABBREV:
+ Stream.ReadAbbrevRecord();
+ ++BlockStats.NumAbbrevs;
+ break;
+ default:
+ ++BlockStats.NumRecords;
+ if (AbbrevID != bitc::UNABBREV_RECORD)
+ ++BlockStats.NumAbbreviatedRecords;
+
+ Record.clear();
+ unsigned Code = Stream.ReadRecord(AbbrevID, Record);
+
+ // Increment the # occurrences of this code.
+ if (BlockStats.CodeFreq.size() <= Code)
+ BlockStats.CodeFreq.resize(Code+1);
+ BlockStats.CodeFreq[Code]++;
+
+ if (Dump) {
+ std::cerr << Indent << " <";
+ if (const char *CodeName = GetCodeName(Code, BlockID))
+ std::cerr << CodeName;
+ else
+ std::cerr << "UnknownCode" << Code;
+ if (NonSymbolic && GetCodeName(Code, BlockID))
+ std::cerr << " codeid=" << Code;
+ if (AbbrevID != bitc::UNABBREV_RECORD)
+ std::cerr << " abbrevid=" << AbbrevID;
+
+ for (unsigned i = 0, e = Record.size(); i != e; ++i)
+ std::cerr << " op" << i << "=" << (int64_t)Record[i];
+
+ std::cerr << "/>\n";
+ }
+
+ break;
+ }
+ }
+}
+
+static void PrintSize(double Bits) {
+ std::cerr << Bits << "b/" << Bits/8 << "B/" << Bits/32 << "W";
+}
+
+
+/// AnalyzeBitcode - Analyze the bitcode file specified by InputFilename.
+static int AnalyzeBitcode() {
+ // Read the input file.
+ MemoryBuffer *Buffer;
+ if (InputFilename == "-")
+ Buffer = MemoryBuffer::getSTDIN();
+ else
+ Buffer = MemoryBuffer::getFile(&InputFilename[0], InputFilename.size());
+
+ if (Buffer == 0)
+ return Error("Error reading '" + InputFilename + "'.");
+
+ if (Buffer->getBufferSize() & 3)
+ return Error("Bitcode stream should be a multiple of 4 bytes in length");
+
+ unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart();
+ BitstreamReader Stream(BufPtr, BufPtr+Buffer->getBufferSize());
+
+
+ // Read the stream signature.
+ char Signature[6];
+ Signature[0] = Stream.Read(8);
+ Signature[1] = Stream.Read(8);
+ Signature[2] = Stream.Read(4);
+ Signature[3] = Stream.Read(4);
+ Signature[4] = Stream.Read(4);
+ Signature[5] = Stream.Read(4);
+
+ // Autodetect the file contents, if it is one we know.
+ CurStreamType = UnknownBitstream;
+ if (Signature[0] == 'B' && Signature[1] == 'C' &&
+ Signature[2] == 0x0 && Signature[3] == 0xC &&
+ Signature[4] == 0xE && Signature[5] == 0xD)
+ CurStreamType = LLVMIRBitstream;
+
+ unsigned NumTopBlocks = 0;
+
+ // Parse the top-level structure. We only allow blocks at the top-level.
+ while (!Stream.AtEndOfStream()) {
+ unsigned Code = Stream.ReadCode();
+ if (Code != bitc::ENTER_SUBBLOCK)
+ return Error("Invalid record at top-level");
+
+ if (ParseBlock(Stream, 0))
+ return true;
+ ++NumTopBlocks;
+ }
+
+ if (Dump) std::cerr << "\n\n";
+
+ uint64_t BufferSizeBits = Buffer->getBufferSize()*8;
+ // Print a summary of the read file.
+ std::cerr << "Summary of " << InputFilename << ":\n";
+ std::cerr << " Total size: ";
+ PrintSize(BufferSizeBits);
+ std::cerr << "\n";
+ std::cerr << " Stream type: ";
+ switch (CurStreamType) {
+ default: assert(0 && "Unknown bitstream type");
+ case UnknownBitstream: std::cerr << "unknown\n"; break;
+ case LLVMIRBitstream: std::cerr << "LLVM IR\n"; break;
+ }
+ std::cerr << " # Toplevel Blocks: " << NumTopBlocks << "\n";
+ std::cerr << "\n";
+
+ // Emit per-block stats.
+ std::cerr << "Per-block Summary:\n";
+ for (std::map<unsigned, PerBlockIDStats>::iterator I = BlockIDStats.begin(),
+ E = BlockIDStats.end(); I != E; ++I) {
+ std::cerr << " Block ID #" << I->first;
+ if (const char *BlockName = GetBlockName(I->first))
+ std::cerr << " (" << BlockName << ")";
+ std::cerr << ":\n";
+
+ const PerBlockIDStats &Stats = I->second;
+ std::cerr << " Num Instances: " << Stats.NumInstances << "\n";
+ std::cerr << " Total Size: ";
+ PrintSize(Stats.NumBits);
+ std::cerr << "\n";
+ std::cerr << " % of file: "
+ << Stats.NumBits/(double)BufferSizeBits*100 << "\n";
+ if (Stats.NumInstances > 1) {
+ std::cerr << " Average Size: ";
+ PrintSize(Stats.NumBits/(double)Stats.NumInstances);
+ std::cerr << "\n";
+ std::cerr << " Tot/Avg SubBlocks: " << Stats.NumSubBlocks << "/"
+ << Stats.NumSubBlocks/(double)Stats.NumInstances << "\n";
+ std::cerr << " Tot/Avg Abbrevs: " << Stats.NumAbbrevs << "/"
+ << Stats.NumAbbrevs/(double)Stats.NumInstances << "\n";
+ std::cerr << " Tot/Avg Records: " << Stats.NumRecords << "/"
+ << Stats.NumRecords/(double)Stats.NumInstances << "\n";
+ } else {
+ std::cerr << " Num SubBlocks: " << Stats.NumSubBlocks << "\n";
+ std::cerr << " Num Abbrevs: " << Stats.NumAbbrevs << "\n";
+ std::cerr << " Num Records: " << Stats.NumRecords << "\n";
+ }
+ if (Stats.NumRecords)
+ std::cerr << " % Abbrev Recs: " << (Stats.NumAbbreviatedRecords/
+ (double)Stats.NumRecords)*100 << "\n";
+ std::cerr << "\n";
+
+ // Print a histogram of the codes we see.
+ if (!NoHistogram && !Stats.CodeFreq.empty()) {
+ std::vector<std::pair<unsigned, unsigned> > FreqPairs; // <freq,code>
+ for (unsigned i = 0, e = Stats.CodeFreq.size(); i != e; ++i)
+ if (unsigned Freq = Stats.CodeFreq[i])
+ FreqPairs.push_back(std::make_pair(Freq, i));
+ std::stable_sort(FreqPairs.begin(), FreqPairs.end());
+ std::reverse(FreqPairs.begin(), FreqPairs.end());
+
+ std::cerr << "\tCode Histogram:\n";
+ for (unsigned i = 0, e = FreqPairs.size(); i != e; ++i) {
+ std::cerr << "\t\t" << FreqPairs[i].first << "\t";
+ if (const char *CodeName = GetCodeName(FreqPairs[i].second, I->first))
+ std::cerr << CodeName << "\n";
+ else
+ std::cerr << "UnknownCode" << FreqPairs[i].second << "\n";
+ }
+ std::cerr << "\n";
+
+ }
+ }
+ return 0;
+}
+
+
+int main(int argc, char **argv) {
+ llvm_shutdown_obj X; // Call llvm_shutdown() on exit.
+ cl::ParseCommandLineOptions(argc, argv, " llvm-bcanalyzer file analyzer\n");
+
+ sys::PrintStackTraceOnErrorSignal();
+
+ return AnalyzeBitcode();
+}
diff --git a/tools/llvm-config/Makefile b/tools/llvm-config/Makefile
new file mode 100644
index 0000000..20bd01a
--- /dev/null
+++ b/tools/llvm-config/Makefile
@@ -0,0 +1,87 @@
+##===- tools/llvm-config/Makefile --------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file was developed by Reid Spencer and Eric Kidd and is distributed under
+# the University of Illinois Open Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../..
+
+EXTRA_DIST = LibDeps.txt FinalLibDeps.txt llvm-config.in.in find-cycles.pl
+REQUIRES_EH := 1
+
+include $(LEVEL)/Makefile.common
+
+# If we don't have Perl, we can't generate the library dependencies upon which
+# llvm-config depends. Therefore, only if we detect perl will we do anything
+# useful.
+ifeq ($(HAVE_PERL),1)
+
+# Combine preprocessor flags (except for -I) and CXX flags.
+SUB_CPPFLAGS = ${CPP.BaseFlags}
+SUB_CFLAGS = ${CPP.BaseFlags} ${C.Flags}
+SUB_CXXFLAGS = ${CPP.BaseFlags} ${CXX.Flags}
+
+# This is blank for now. We need to be careful about adding stuff here:
+# LDFLAGS tend not to be portable, and we don't currently require the
+# user to use libtool when linking against LLVM.
+SUB_LDFLAGS =
+
+FinalLibDeps = $(PROJ_OBJ_DIR)/FinalLibDeps.txt
+LibDeps = $(PROJ_OBJ_DIR)/LibDeps.txt
+LibDepsTemp = $(PROJ_OBJ_DIR)/LibDeps.txt.tmp
+GenLibDeps = $(PROJ_SRC_ROOT)/utils/GenLibDeps.pl
+
+$(LibDepsTemp): $(GenLibDeps) $(LibDir) $(wildcard $(LibDir)/*.a $(LibDir)/*.o)
+ $(Echo) "Regenerating LibDeps.txt.tmp"
+ $(Verb) $(PERL) $(GenLibDeps) -flat $(LibDir) $(NM_PATH) > $(LibDepsTemp)
+
+$(LibDeps): $(LibDepsTemp)
+ $(Verb) $(CMP) -s $@ $< || ( $(CP) $< $@ && \
+ $(EchoCmd) Updated LibDeps.txt because dependencies changed )
+
+# Find all the cyclic dependencies between various LLVM libraries, so we
+# don't have to process them at runtime.
+$(FinalLibDeps): find-cycles.pl $(LibDeps)
+ $(Echo) "Checking for cyclic dependencies between LLVM libraries."
+ $(Verb) $(PERL) $< < $(LibDeps) > $@ || rm -f $@
+
+# Rerun our configure substitutions as needed.
+ConfigInIn = $(PROJ_SRC_DIR)/llvm-config.in.in
+llvm-config.in: $(ConfigInIn) $(ConfigStatusScript)
+ $(Verb) cd $(PROJ_OBJ_ROOT) ; \
+ $(ConfigStatusScript) tools/llvm-config/llvm-config.in
+
+# Build our final script.
+$(ToolDir)/llvm-config: llvm-config.in $(FinalLibDeps)
+ $(Echo) "Building llvm-config script."
+ $(Verb) $(ECHO) 's,@LLVM_CPPFLAGS@,$(SUB_CPPFLAGS),' > temp.sed
+ $(Verb) $(ECHO) 's,@LLVM_CFLAGS@,$(SUB_CFLAGS),' >> temp.sed
+ $(Verb) $(ECHO) 's,@LLVM_CXXFLAGS@,$(SUB_CXXFLAGS),' >> temp.sed
+ $(Verb) $(ECHO) 's,@LLVM_LDFLAGS@,$(SUB_LDFLAGS),' >> temp.sed
+ $(Verb) $(ECHO) 's,@LLVM_BUILDMODE@,$(BuildMode),' >> temp.sed
+ $(Verb) $(SED) -f temp.sed < $< > $@
+ $(Verb) $(RM) temp.sed
+ $(Verb) cat $(FinalLibDeps) >> $@
+ $(Verb) chmod +x $@
+
+else
+# We don't have perl, just generate a dummy llvm-config
+$(ToolDir)/llvm-config:
+ $(Echo) "Building place holder llvm-config script."
+ $(Verb) $(ECHO) 'echo llvm-config: Perl not found so llvm-config could not be generated' >> $@
+ $(Verb) chmod +x $@
+
+endif
+# Hook into the standard Makefile rules.
+all-local:: $(ToolDir)/llvm-config
+clean-local::
+ $(Verb) $(RM) -f $(ToolDir)/llvm-config llvm-config.in $(FinalLibDeps) \
+ $(LibDeps) GenLibDeps.out
+install-local:: all-local
+ $(Echo) Installing llvm-config
+ $(Verb) $(MKDIR) $(PROJ_bindir)
+ $(Verb) $(ScriptInstall) $(ToolDir)/llvm-config $(PROJ_bindir)
+
diff --git a/tools/llvm-config/find-cycles.pl b/tools/llvm-config/find-cycles.pl
new file mode 100755
index 0000000..8156abd
--- /dev/null
+++ b/tools/llvm-config/find-cycles.pl
@@ -0,0 +1,165 @@
+#!/usr/bin/perl
+#
+# Program: find-cycles.pl
+#
+# Synopsis: Given a list of possibly cyclic dependencies, merge all the
+# cycles. This makes it possible to topologically sort the
+# dependencies between different parts of LLVM.
+#
+# Syntax: find-cycles.pl < LibDeps.txt > FinalLibDeps.txt
+#
+# Input: cycmem1: cycmem2 dep1 dep2
+# cycmem2: cycmem1 dep3 dep4
+# boring: dep4
+#
+# Output: cycmem1 cycmem2: dep1 dep2 dep3 dep4
+# boring: dep4
+#
+# This file was written by Eric Kidd, and is placed into the public domain.
+#
+
+use 5.006;
+use strict;
+use warnings;
+
+my %DEPS;
+my @CYCLES;
+sub find_all_cycles;
+
+# Read our dependency information.
+while (<>) {
+ chomp;
+ my ($module, $dependency_str) = /^\s*([^:]+):\s*(.*)\s*$/;
+ die "Malformed data: $_" unless defined $dependency_str;
+ my @dependencies = split(/ /, $dependency_str);
+ $DEPS{$module} = \@dependencies;
+}
+
+# Partition our raw dependencies into sets of cyclically-connected nodes.
+find_all_cycles();
+
+# Print out the finished cycles, with their dependencies.
+my @output;
+my $cycles_found = 0;
+foreach my $cycle (@CYCLES) {
+ my @modules = sort keys %{$cycle};
+
+ # Merge the dependencies of all modules in this cycle.
+ my %dependencies;
+ foreach my $module (@modules) {
+ @dependencies{@{$DEPS{$module}}} = 1;
+ }
+
+ # Prune the known cyclic dependencies.
+ foreach my $module (@modules) {
+ delete $dependencies{$module};
+ }
+
+ # Warn about possible linker problems.
+ my @archives = grep(/\.a$/, @modules);
+ if (@archives > 1) {
+ $cycles_found = $cycles_found + 1;
+ print STDERR "find-cycles.pl: Circular dependency between *.a files:\n";
+ print STDERR "find-cycles.pl: ", join(' ', @archives), "\n";
+ push @modules, @archives; # WORKAROUND: Duplicate *.a files. Ick.
+ }
+
+ # Add to our output. (@modules is already as sorted as we need it to be.)
+ push @output, (join(' ', @modules) . ': ' .
+ join(' ', sort keys %dependencies) . "\n");
+}
+print sort @output;
+
+exit $cycles_found;
+
+#==========================================================================
+# Depedency Cycle Support
+#==========================================================================
+# For now, we have cycles in our dependency graph. Ideally, each cycle
+# would be collapsed down to a single *.a file, saving us all this work.
+#
+# To understand this code, you'll need a working knowledge of Perl 5,
+# and possibly some quality time with 'man perlref'.
+
+my %SEEN;
+my %CYCLES;
+sub find_cycles ($@);
+sub found_cycles ($@);
+
+sub find_all_cycles {
+ # Find all multi-item cycles.
+ my @modules = sort keys %DEPS;
+ foreach my $module (@modules) { find_cycles($module); }
+
+ # Build fake one-item "cycles" for the remaining modules, so we can
+ # treat them uniformly.
+ foreach my $module (@modules) {
+ unless (defined $CYCLES{$module}) {
+ my %cycle = ($module, 1);
+ $CYCLES{$module} = \%cycle;
+ }
+ }
+
+ # Find all our unique cycles. We have to do this the hard way because
+ # we apparently can't store hash references as hash keys without making
+ # 'strict refs' sad.
+ my %seen;
+ foreach my $cycle (values %CYCLES) {
+ unless ($seen{$cycle}) {
+ $seen{$cycle} = 1;
+ push @CYCLES, $cycle;
+ }
+ }
+}
+
+# Walk through our graph depth-first (keeping a trail in @path), and report
+# any cycles we find.
+sub find_cycles ($@) {
+ my ($module, @path) = @_;
+ if (str_in_list($module, @path)) {
+ found_cycle($module, @path);
+ } else {
+ return if defined $SEEN{$module};
+ $SEEN{$module} = 1;
+ foreach my $dep (@{$DEPS{$module}}) {
+ find_cycles($dep, @path, $module);
+ }
+ }
+}
+
+# Give a cycle, attempt to merge it with pre-existing cycle data.
+sub found_cycle ($@) {
+ my ($module, @path) = @_;
+
+ # Pop any modules which aren't part of our cycle.
+ while ($path[0] ne $module) { shift @path; }
+ #print join("->", @path, $module) . "\n";
+
+ # Collect the modules in our cycle into a hash.
+ my %cycle;
+ foreach my $item (@path) {
+ $cycle{$item} = 1;
+ if (defined $CYCLES{$item}) {
+ # Looks like we intersect with an existing cycle, so merge
+ # all those in, too.
+ foreach my $old_item (keys %{$CYCLES{$item}}) {
+ $cycle{$old_item} = 1;
+ }
+ }
+ }
+
+ # Update our global cycle table.
+ my $cycle_ref = \%cycle;
+ foreach my $item (keys %cycle) {
+ $CYCLES{$item} = $cycle_ref;
+ }
+ #print join(":", sort keys %cycle) . "\n";
+}
+
+sub str_in_list ($@) {
+ my ($str, @list) = @_;
+ foreach my $item (@list) {
+ return 1 if ($item eq $str);
+ }
+ return 0;
+}
diff --git a/tools/llvm-config/llvm-config.in.in b/tools/llvm-config/llvm-config.in.in
new file mode 100644
index 0000000..f5368d3
--- /dev/null
+++ b/tools/llvm-config/llvm-config.in.in
@@ -0,0 +1,445 @@
+#!@PERL@
+##===- tools/llvm-config ---------------------------------------*- perl -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file was developed by Eric Kidd and is distributed under
+# the University of Illinois Open Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+#
+# Synopsis: Prints out compiler options needed to build against an installed
+# copy of LLVM.
+#
+# Syntax: llvm-config OPTIONS... [COMPONENTS...]
+#
+##===----------------------------------------------------------------------===##
+
+use 5.006;
+use strict;
+use warnings;
+
+#---- begin autoconf values ----
+my $PACKAGE_NAME = q{@PACKAGE_NAME@};
+my $VERSION = q{@PACKAGE_VERSION@};
+my $PREFIX = q{@LLVM_PREFIX@};
+my $LLVM_CONFIGTIME = q{@LLVM_CONFIGTIME@};
+my $LLVM_SRC_ROOT = q{@abs_top_srcdir@};
+my $LLVM_OBJ_ROOT = q{@abs_top_builddir@};
+my $LLVM_ON_WIN32 = q{@LLVM_ON_WIN32@};
+my $LLVM_ON_UNIX = q{@LLVM_ON_UNIX@};
+my $LLVMGCCDIR = q{@LLVMGCCDIR@};
+my $LLVMGCC = q{@LLVMGCC@};
+my $LLVMGXX = q{@LLVMGXX@};
+my $LLVMGCC_VERSION = q{@LLVMGCC_VERSION@};
+my $LLVMGCC_MAJVERS = q{@LLVMGCC_MAJVERS@};
+my $ENDIAN = q{@ENDIAN@};
+my $SHLIBEXT = q{@SHLIBEXT@};
+my $EXEEXT = q{@EXEEXT@};
+my $OS = q{@OS@};
+my $ARCH = lc(q{@ARCH@});
+my $TARGET_TRIPLE = q{@target@};
+my $TARGETS_TO_BUILD = q{@TARGETS_TO_BUILD@};
+my $TARGET_HAS_JIT = q{@TARGET_HAS_JIT@};
+my @TARGETS_BUILT = map { lc($_) } qw{@TARGETS_TO_BUILD@};
+#---- end autoconf values ----
+
+# Must pretend x86_64 architecture is really x86, otherwise the native backend
+# won't get linked in.
+$ARCH = "x86" if $ARCH eq "x86_64";
+
+#---- begin Makefile values ----
+my $CPPFLAGS = q{@LLVM_CPPFLAGS@};
+my $CFLAGS = q{@LLVM_CFLAGS@};
+my $CXXFLAGS = q{@LLVM_CXXFLAGS@};
+my $LDFLAGS = q{@LLVM_LDFLAGS@};
+my $SYSTEM_LIBS = q{@LIBS@};
+my $LLVM_BUILDMODE = q{@LLVM_BUILDMODE@};
+#---- end Makefile values ----
+
+# Figure out where llvm-config is being run from. Primarily, we care if it has
+# been installed, or is running from the build directory, which changes the
+# locations of some files.
+
+# Convert the current executable name into its directory (e.g. ".").
+my ($RUN_DIR) = ($0 =~ /^(.*)\/.*$/);
+
+# Turn the directory into an absolute directory on the file system, also pop up
+# from "bin" into the build or prefix dir.
+my $ABS_RUN_DIR = `cd $RUN_DIR/..; pwd`;
+chomp($ABS_RUN_DIR);
+
+# Compute the absolute object directory build, e.g. "foo/llvm/Debug".
+my $ABS_OBJ_ROOT = "$LLVM_OBJ_ROOT/$LLVM_BUILDMODE";
+$ABS_OBJ_ROOT = `cd $ABS_OBJ_ROOT; pwd` if (-d $ABS_OBJ_ROOT);
+chomp($ABS_OBJ_ROOT);
+
+my $INCLUDEDIR = "$ABS_RUN_DIR/include";
+my $LIBDIR = "$ABS_RUN_DIR/lib";
+my $BINDIR = "$ABS_RUN_DIR/bin";
+if ($ABS_RUN_DIR eq $ABS_OBJ_ROOT) {
+ # If we are running out of the build directory, the include dir is in the
+ # srcdir.
+ $INCLUDEDIR = "$LLVM_SRC_ROOT/include";
+} else {
+ # If installed, ignore the prefix the tree was configured with, use the
+ # current prefix.
+ $PREFIX = $ABS_RUN_DIR;
+}
+
+sub usage;
+sub fix_library_names (@);
+sub fix_library_files (@);
+sub expand_dependencies (@);
+sub name_map_entries;
+
+# Parse our command-line arguments.
+usage if @ARGV == 0;
+my @components;
+my $has_opt = 0;
+my $want_libs = 0;
+my $want_libnames = 0;
+my $want_libfiles = 0;
+my $want_components = 0;
+foreach my $arg (@ARGV) {
+ if ($arg =~ /^-/) {
+ if ($arg eq "--version") {
+ $has_opt = 1; print "$VERSION\n";
+ } elsif ($arg eq "--prefix") {
+ $has_opt = 1; print "$PREFIX\n";
+ } elsif ($arg eq "--bindir") {
+ $has_opt = 1; print "$BINDIR\n";
+ } elsif ($arg eq "--includedir") {
+ $has_opt = 1; print "$INCLUDEDIR\n";
+ } elsif ($arg eq "--libdir") {
+ $has_opt = 1; print "$LIBDIR\n";
+ } elsif ($arg eq "--cppflags") {
+ $has_opt = 1; print "-I$INCLUDEDIR $CPPFLAGS\n";
+ } elsif ($arg eq "--cflags") {
+ $has_opt = 1; print "-I$INCLUDEDIR $CFLAGS\n";
+ } elsif ($arg eq "--cxxflags") {
+ $has_opt = 1; print "-I$INCLUDEDIR $CXXFLAGS\n";
+ } elsif ($arg eq "--ldflags") {
+ $has_opt = 1; print "-L$LIBDIR $LDFLAGS $SYSTEM_LIBS\n";
+ } elsif ($arg eq "--libs") {
+ $has_opt = 1; $want_libs = 1;
+ } elsif ($arg eq "--libnames") {
+ $has_opt = 1; $want_libnames = 1;
+ } elsif ($arg eq "--libfiles") {
+ $has_opt = 1; $want_libfiles = 1;
+ } elsif ($arg eq "--components") {
+ $has_opt = 1; print join(' ', name_map_entries), "\n";
+ } elsif ($arg eq "--targets-built") {
+ $has_opt = 1; print join(' ', @TARGETS_BUILT), "\n";
+ } elsif ($arg eq "--host-target") {
+ $has_opt = 1; print "$TARGET_TRIPLE\n";
+ } elsif ($arg eq "--build-mode") {
+ $has_opt = 1; print "$LLVM_BUILDMODE\n";
+ } elsif ($arg eq "--obj-root") {
+ $has_opt = 1; print `cd $LLVM_OBJ_ROOT/; pwd`;
+ } elsif ($arg eq "--src-root") {
+ $has_opt = 1; print `cd $LLVM_SRC_ROOT/; pwd`;
+ } else {
+ usage();
+ }
+ } else {
+ push @components, $arg;
+ }
+}
+
+# If no options were specified, fail.
+usage unless $has_opt;
+
+# If no components were specified, default to 'all'.
+if (@components == 0) {
+ push @components, 'all';
+}
+
+# Force component names to lower case.
+@components = map lc, @components;
+
+# Handle any arguments which require building our dependency graph.
+if ($want_libs || $want_libnames || $want_libfiles) {
+ my @libs = expand_dependencies(@components);
+ print join(' ', fix_library_names(@libs)), "\n" if ($want_libs);
+ print join(' ', @libs), "\n" if ($want_libnames);
+ print join(' ', fix_library_files(@libs)), "\n" if ($want_libfiles);
+}
+
+exit 0;
+
+#==========================================================================
+# Support Routines
+#==========================================================================
+
+sub usage {
+ print STDERR <<__EOD__;
+Usage: llvm-config <OPTION>... [<COMPONENT>...]
+
+Get various configuration information needed to compile programs which use
+LLVM. Typically called from 'configure' scripts. Examples:
+ llvm-config --cxxflags
+ llvm-config --ldflags
+ llvm-config --libs engine bcreader scalaropts
+
+Options:
+ --version Print LLVM version.
+ --prefix Print the installation prefix.
+ --src-root Print the source root LLVM was built from.
+ --obj-root Print the object root used to build LLVM.
+ --bindir Directory containing LLVM executables.
+ --includedir Directory containing LLVM headers.
+ --libdir Directory containing LLVM libraries.
+ --cppflags C preprocessor flags for files that include LLVM headers.
+ --cflags C compiler flags for files that include LLVM headers.
+ --cxxflags C++ compiler flags for files that include LLVM headers.
+ --ldflags Print Linker flags.
+ --libs Libraries needed to link against LLVM components.
+ --libnames Bare library names for in-tree builds.
+ --libfiles Fully qualified library filenames for makefile depends.
+ --components List of all possible components.
+ --targets-built List of all targets currently built.
+ --host-target Target triple used to configure LLVM.
+ --build-mode Print build mode of LLVM tree (e.g. Debug or Release).
+Typical components:
+ all All LLVM libraries (default).
+ backend Either a native backend or the C backend.
+ engine Either a native JIT or a bytecode interpreter.
+__EOD__
+ exit(1);
+}
+
+# Use -lfoo instead of libfoo.a whenever possible, and add directories to
+# files which can't be found using -L.
+sub fix_library_names (@) {
+ my @libs = @_;
+ my @result;
+ foreach my $lib (@libs) {
+ # Transform the bare library name appropriately.
+ my ($basename) = ($lib =~ /^lib([^.]*)\.a/);
+ if (defined $basename) {
+ push @result, "-l$basename";
+ } else {
+ push @result, "$LIBDIR/$lib";
+ }
+ }
+ return @result;
+}
+
+# Turn the list of libraries into a list of files.
+sub fix_library_files(@) {
+ my @libs = @_;
+ my @result;
+ foreach my $lib (@libs) {
+ # Transform the bare library name into a filename.
+ push @result, "$LIBDIR/$lib";
+ }
+ return @result;
+}
+
+#==========================================================================
+# Library Dependency Analysis
+#==========================================================================
+# Given a few human-readable library names, find all their dependencies
+# and sort them into an order which the linker will like. If we packed
+# our libraries into fewer archives, we could make the linker do much
+# of this work for us.
+#
+# Libraries have two different types of names in this code: Human-friendly
+# "component" names entered on the command-line, and the raw file names
+# we use internally (and ultimately pass to the linker).
+#
+# To understand this code, you'll need a working knowledge of Perl 5,
+# and possibly some quality time with 'man perlref'.
+
+sub load_dependencies;
+sub build_name_map;
+sub have_native_backend;
+sub find_best_engine;
+sub expand_names (@);
+sub find_all_required_sets (@);
+sub find_all_required_sets_helper ($$@);
+
+# Each "set" contains one or more libraries which must be included as a
+# group (due to cyclic dependencies). Sets are represented as a Perl array
+# reference pointing to a list of internal library names.
+my @SETS;
+
+# Various mapping tables.
+my %LIB_TO_SET_MAP; # Maps internal library names to their sets.
+my %SET_DEPS; # Maps sets to a list of libraries they depend on.
+my %NAME_MAP; # Maps human-entered names to internal names.
+
+# Have our dependencies been loaded yet?
+my $DEPENDENCIES_LOADED = 0;
+
+# Given a list of human-friendly component names, translate them into a
+# complete set of linker arguments.
+sub expand_dependencies (@) {
+ my @libs = @_;
+ load_dependencies;
+ my @required_sets = find_all_required_sets(expand_names(@libs));
+ my @sorted_sets = topologically_sort_sets(@required_sets);
+
+ # Expand the library sets into libraries.
+ my @result;
+ foreach my $set (@sorted_sets) { push @result, @{$set}; }
+ return @result;
+}
+
+# Load in the raw dependency data stored at the end of this file.
+sub load_dependencies {
+ return if $DEPENDENCIES_LOADED;
+ $DEPENDENCIES_LOADED = 1;
+ while (<DATA>) {
+ # Parse our line.
+ my ($libs, $deps) = /^\s*([^:]+):\s*(.*)\s*$/;
+ die "Malformed dependency data" unless defined $deps;
+ my @libs = split(' ', $libs);
+ my @deps = split(' ', $deps);
+
+ # Record our dependency data.
+ my $set = \@libs;
+ push @SETS, $set;
+ foreach my $lib (@libs) { $LIB_TO_SET_MAP{$lib} = $set; }
+ $SET_DEPS{$set} = \@deps;
+ }
+ build_name_map;
+}
+
+# Build a map converting human-friendly component names into internal
+# library names.
+sub build_name_map {
+ # Add entries for all the actual libraries.
+ foreach my $set (@SETS) {
+ foreach my $lib (sort @$set) {
+ my $short_name = $lib;
+ $short_name =~ s/^(lib)?LLVM([^.]*)\..*$/$2/;
+ $short_name =~ tr/A-Z/a-z/;
+ $NAME_MAP{$short_name} = [$lib];
+ }
+ }
+
+ # Add virtual entries.
+ $NAME_MAP{'native'} = have_native_backend() ? [$ARCH] : [];
+ $NAME_MAP{'backend'} = have_native_backend() ? ['native'] : ['cbackend'];
+ $NAME_MAP{'engine'} = find_best_engine;
+ $NAME_MAP{'all'} = [name_map_entries]; # Must be last.
+}
+
+# Return true if we have a native backend to use.
+sub have_native_backend {
+ my %BUILT;
+ foreach my $target (@TARGETS_BUILT) { $BUILT{$target} = 1; }
+ return defined $NAME_MAP{$ARCH} && defined $BUILT{$ARCH};
+}
+
+# Find a working subclass of ExecutionEngine for this platform.
+sub find_best_engine {
+ if (have_native_backend && $TARGET_HAS_JIT) {
+ return ['jit', 'native'];
+ } else {
+ return ['interpreter'];
+ }
+}
+
+# Get all the human-friendly component names.
+sub name_map_entries {
+ load_dependencies;
+ return sort keys %NAME_MAP;
+}
+
+# Map human-readable names to internal library names.
+sub expand_names (@) {
+ my @names = @_;
+ my @result;
+ foreach my $name (@names) {
+ if (defined $LIB_TO_SET_MAP{$name}) {
+ # We've hit bottom: An actual library name.
+ push @result, $name;
+ } elsif (defined $NAME_MAP{$name}) {
+ # We've found a short name to expand.
+ push @result, expand_names(@{$NAME_MAP{$name}});
+ } else {
+ print STDERR "llvm-config: unknown component name: $name\n";
+ exit(1);
+ }
+ }
+ return @result;
+}
+
+# Given a list of internal library names, return all sets of libraries which
+# will need to be included by the linker (in no particular order).
+sub find_all_required_sets (@) {
+ my @libs = @_;
+ my %sets_added;
+ my @result;
+ find_all_required_sets_helper(\%sets_added, \@result, @libs);
+ return @result;
+}
+
+# Recursive closures are pretty broken in Perl, so we're going to separate
+# this function from find_all_required_sets and pass in the state we need
+# manually, as references. Yes, this is fairly unpleasant.
+sub find_all_required_sets_helper ($$@) {
+ my ($sets_added, $result, @libs) = @_;
+ foreach my $lib (@libs) {
+ my $set = $LIB_TO_SET_MAP{$lib};
+ next if defined $$sets_added{$set};
+ $$sets_added{$set} = 1;
+ push @$result, $set;
+ find_all_required_sets_helper($sets_added, $result, @{$SET_DEPS{$set}});
+ }
+}
+
+# Print a list of sets, with a label. Used for debugging.
+sub print_sets ($@) {
+ my ($label, @sets) = @_;
+ my @output;
+ foreach my $set (@sets) { push @output, join(',', @$set); }
+ print "$label: ", join(';', @output), "\n";
+}
+
+# Returns true if $lib is a key in $added.
+sub has_lib_been_added ($$) {
+ my ($added, $lib) = @_;
+ return defined $$added{$LIB_TO_SET_MAP{$lib}};
+}
+
+# Returns true if all the dependencies of $set appear in $added.
+sub have_all_deps_been_added ($$) {
+ my ($added, $set) = @_;
+ #print_sets(" Checking", $set);
+ #print_sets(" Wants", $SET_DEPS{$set});
+ foreach my $lib (@{$SET_DEPS{$set}}) {
+ return 0 unless has_lib_been_added($added, $lib);
+ }
+ return 1;
+}
+
+# Given a list of sets, topologically sort them using dependencies.
+sub topologically_sort_sets (@) {
+ my @sets = @_;
+ my %added;
+ my @result;
+ SCAN: while (@sets) { # We'll delete items from @sets as we go.
+ #print_sets("So far", reverse(@result));
+ #print_sets("Remaining", @sets);
+ for (my $i = 0; $i < @sets; ++$i) {
+ my $set = $sets[$i];
+ if (have_all_deps_been_added(\%added, $set)) {
+ push @result, $set;
+ $added{$set} = 1;
+ #print "Removing $i.\n";
+ splice(@sets, $i, 1);
+ next SCAN; # Restart our scan.
+ }
+ }
+ die "Can't find a library with no dependencies";
+ }
+ return reverse(@result);
+}
+
+# Our library dependency data will be added after the '__END__' token, and will
+# be read through the magic <DATA> filehandle.
+__END__
diff --git a/tools/llvm-db/CLICommand.h b/tools/llvm-db/CLICommand.h
new file mode 100644
index 0000000..0b60e05
--- /dev/null
+++ b/tools/llvm-db/CLICommand.h
@@ -0,0 +1,111 @@
+//===- CLICommand.h - Classes used to represent commands --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a small class hierarchy used to represent the various types
+// of commands in the CLI debugger front-end.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLICOMMAND_H
+#define CLICOMMAND_H
+
+#include <string>
+#include <vector>
+#include <cassert>
+
+namespace llvm {
+ class CLIDebugger;
+
+ /// CLICommand - Base class of the hierarchy, used to provide the abstract
+ /// interface common to all commands.
+ ///
+ class CLICommand {
+ /// ShortHelp, LongHelp - The short and long helps strings printed for the
+ /// command. The ShortHelp string should be a single line of text without a
+ /// newline. The LongHelp string should be a full description with
+ /// terminating newline.
+ std::string ShortHelp, LongHelp;
+
+ /// RefCount - This contains the number of entries in the CLIDebugger
+ /// CommandTable that points to this command.
+ unsigned RefCount;
+
+ /// OptionNames - This contains a list of names for the option. Keeping
+ /// track of this is done just to make the help output more helpful.
+ ///
+ std::vector<std::string> OptionNames;
+ public:
+ CLICommand(const std::string &SH, const std::string &LH)
+ : ShortHelp(SH), LongHelp(LH), RefCount(0) {}
+
+ virtual ~CLICommand() {}
+
+ /// addRef/dropRef - Implement a simple reference counting scheme to make
+ /// sure we delete commands that are no longer used.
+ void addRef() { ++RefCount; }
+ void dropRef() {
+ if (--RefCount == 0) delete this;
+ }
+
+ /// getPrimaryOptionName - Return the first name the option was added under.
+ /// This is the name we report for the option in the help output.
+ std::string getPrimaryOptionName() const {
+ return OptionNames.empty() ? "" : OptionNames[0];
+ }
+
+ /// getOptionName - Return all of the names the option is registered as.
+ ///
+ const std::vector<std::string> &getOptionNames() const {
+ return OptionNames;
+ }
+
+ /// addOptionName - Add a name that this option is known as.
+ ///
+ void addOptionName(const std::string &Name) {
+ OptionNames.push_back(Name);
+ }
+
+ /// removeOptionName - Eliminate one of the names for this option.
+ ///
+ void removeOptionName(const std::string &Name) {
+ unsigned i = 0;
+ for (; OptionNames[i] != Name; ++i)
+ assert(i+1 < OptionNames.size() && "Didn't find option name!");
+ OptionNames.erase(OptionNames.begin()+i);
+ }
+
+
+ /// getShortHelp - Return the short help string for this command.
+ ///
+ const std::string &getShortHelp() { return ShortHelp; }
+
+ /// getLongHelp - Return the long help string for this command, if it
+ /// exists.
+ const std::string &getLongHelp() { return LongHelp; }
+
+ virtual void runCommand(CLIDebugger &D, std::string &Arguments) = 0;
+ };
+
+ /// BuiltinCLICommand - This class represents commands that are built directly
+ /// into the debugger.
+ class BuiltinCLICommand : public CLICommand {
+ // Impl - Pointer to the method that implements the command
+ void (CLIDebugger::*Impl)(std::string&);
+ public:
+ BuiltinCLICommand(const std::string &ShortHelp, const std::string &LongHelp,
+ void (CLIDebugger::*impl)(std::string&))
+ : CLICommand(ShortHelp, LongHelp), Impl(impl) {}
+
+ void runCommand(CLIDebugger &D, std::string &Arguments) {
+ (D.*Impl)(Arguments);
+ }
+ };
+}
+
+#endif
diff --git a/tools/llvm-db/CLIDebugger.cpp b/tools/llvm-db/CLIDebugger.cpp
new file mode 100644
index 0000000..e7ab75c
--- /dev/null
+++ b/tools/llvm-db/CLIDebugger.cpp
@@ -0,0 +1,308 @@
+//===-- CLIDebugger.cpp - Command Line Interface to the Debugger ----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the main implementation of the Command Line Interface to
+// the debugger.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CLIDebugger.h"
+#include "CLICommand.h"
+#include "llvm/Debugger/SourceFile.h"
+#include "llvm/ADT/StringExtras.h"
+#include <iostream>
+using namespace llvm;
+
+/// CLIDebugger constructor - This initializes the debugger to its default
+/// state, and initializes the command table.
+///
+CLIDebugger::CLIDebugger()
+ : TheProgramInfo(0), TheRuntimeInfo(0), Prompt("(llvm-db) "), ListSize(10) {
+ // Initialize instance variables
+ CurrentFile = 0;
+ LineListedStart = 1;
+ LineListedEnd = 1;
+ LastCurrentFrame = 0;
+ CurrentLanguage = 0;
+
+ CLICommand *C;
+ //===--------------------------------------------------------------------===//
+ // Program startup and shutdown options
+ //
+ addCommand("file", new BuiltinCLICommand(
+ "Use specified file as the program to be debugged",
+ "The debugger looks in the current directory and the program $PATH for the"
+ " specified LLVM program. It then unloads the currently loaded program and"
+ " loads the specified program.\n",
+ &CLIDebugger::fileCommand));
+
+ addCommand("create", new BuiltinCLICommand(
+ "Start the program, halting its execution in main",
+ "This command creates an instance of the current program, but stops"
+ "\nexecution immediately.\n",
+ &CLIDebugger::createCommand));
+
+ addCommand("kill", new BuiltinCLICommand(
+ "Kills the execution of the current program being debugged", "",
+ &CLIDebugger::killCommand));
+
+ addCommand("quit", new BuiltinCLICommand(
+ "Exit the debugger", "",
+ &CLIDebugger::quitCommand));
+
+ //===--------------------------------------------------------------------===//
+ // Program execution commands
+ //
+ addCommand("run", C = new BuiltinCLICommand(
+ "Start the program running from the beginning", "",
+ &CLIDebugger::runCommand));
+ addCommand("r", C);
+
+ addCommand("cont", C = new BuiltinCLICommand(
+ "Continue program being debugged until the next stop point", "",
+ &CLIDebugger::contCommand));
+ addCommand("c", C); addCommand("fg", C);
+
+ addCommand("step", C = new BuiltinCLICommand(
+ "Step program until it reaches a new source line", "",
+ &CLIDebugger::stepCommand));
+ addCommand("s", C);
+
+ addCommand("next", C = new BuiltinCLICommand(
+ "Step program until it reaches a new source line, stepping over calls", "",
+ &CLIDebugger::nextCommand));
+ addCommand("n", C);
+
+ addCommand("finish", new BuiltinCLICommand(
+ "Execute until the selected stack frame returns",
+ "Upon return, the value returned is printed and put in the value history.\n",
+ &CLIDebugger::finishCommand));
+
+ //===--------------------------------------------------------------------===//
+ // Stack frame commands
+ //
+ addCommand("backtrace", C = new BuiltinCLICommand(
+ "Print backtrace of all stack frames, or innermost COUNT frames",
+ "FIXME: describe. Takes 'n', '-n' or 'full'\n",
+ &CLIDebugger::backtraceCommand));
+ addCommand("bt", C);
+
+ addCommand("up", new BuiltinCLICommand(
+ "Select and print stack frame that called this one",
+ "An argument says how many frames up to go.\n",
+ &CLIDebugger::upCommand));
+
+ addCommand("down", new BuiltinCLICommand(
+ "Select and print stack frame called by this one",
+ "An argument says how many frames down go.\n",
+ &CLIDebugger::downCommand));
+
+ addCommand("frame", C = new BuiltinCLICommand(
+ "Select and print a stack frame",
+ "With no argument, print the selected stack frame. (See also 'info frame').\n"
+ "An argument specifies the frame to select.\n",
+ &CLIDebugger::frameCommand));
+ addCommand("f", C);
+
+ //===--------------------------------------------------------------------===//
+ // Breakpoint related commands
+ //
+ addCommand("break", C = new BuiltinCLICommand(
+ "Set breakpoint at specified line or function",
+ "FIXME: describe.\n",
+ &CLIDebugger::breakCommand));
+ addCommand("b", C);
+
+
+ //===--------------------------------------------------------------------===//
+ // Miscellaneous commands
+ //
+ addCommand("info", new BuiltinCLICommand(
+ "Generic command for showing things about the program being debugged",
+ "info functions: display information about functions in the program.\ninfo"
+ " source : display information about the current source file.\ninfo source"
+ "s : Display source file names for the program\ninfo target : print status"
+ " of inferior process\n",
+ &CLIDebugger::infoCommand));
+
+ addCommand("list", C = new BuiltinCLICommand(
+ "List specified function or line",
+ "FIXME: document\n",
+ &CLIDebugger::listCommand));
+ addCommand("l", C);
+
+ addCommand("set", new BuiltinCLICommand(
+ "Change program or debugger variable",
+ "FIXME: document\n",
+ &CLIDebugger::setCommand));
+
+ addCommand("show", new BuiltinCLICommand(
+ "Generic command for showing things about the debugger",
+ "FIXME: document\n",
+ &CLIDebugger::showCommand));
+
+ addCommand("help", C = new BuiltinCLICommand(
+ "Prints information about available commands", "",
+ &CLIDebugger::helpCommand));
+ addCommand("h", C);
+}
+
+
+/// addCommand - Add a command to the CommandTable, potentially displacing a
+/// preexisting command.
+void CLIDebugger::addCommand(const std::string &Option, CLICommand *Cmd) {
+ assert(Cmd && "Cannot set a null command!");
+ CLICommand *&CS = CommandTable[Option];
+ if (CS == Cmd) return; // noop
+
+ // If we already have a command, decrement the command's reference count.
+ if (CS) {
+ CS->removeOptionName(Option);
+ CS->dropRef();
+ }
+ CS = Cmd;
+
+ // Remember that we are using this command.
+ Cmd->addRef();
+ Cmd->addOptionName(Option);
+}
+
+static bool isValidPrefix(const std::string &Prefix, const std::string &Option){
+ return Prefix.size() <= Option.size() &&
+ Prefix == std::string(Option.begin(), Option.begin()+Prefix.size());
+}
+
+/// getCommand - This looks up the specified command using a fuzzy match.
+/// If the string exactly matches a command or is an unambiguous prefix of a
+/// command, it returns the command. Otherwise it throws an exception
+/// indicating the possible ambiguous choices.
+CLICommand *CLIDebugger::getCommand(const std::string &Command) {
+
+ // Look up the command in the table.
+ std::map<std::string, CLICommand*>::iterator CI =
+ CommandTable.lower_bound(Command);
+
+ if (Command == "") {
+ throw "Null command should not get here!";
+ } else if (CI == CommandTable.end() ||
+ !isValidPrefix(Command, CI->first)) {
+ // If this command has no relation to anything in the command table,
+ // print the error message.
+ throw "Unknown command: '" + Command +
+ "'. Use 'help' for list of commands.";
+ } else if (CI->first == Command) {
+ // We have an exact match on the command
+ return CI->second;
+ } else {
+ // Otherwise, we have a prefix match. Check to see if this is
+ // unambiguous, and if so, run it.
+ std::map<std::string, CLICommand*>::iterator CI2 = CI;
+
+ // If the next command is a valid completion of this one, we are
+ // ambiguous.
+ if (++CI2 != CommandTable.end() && isValidPrefix(Command, CI2->first)) {
+ std::string ErrorMsg =
+ "Ambiguous command '" + Command + "'. Options: " + CI->first;
+ for (++CI; CI != CommandTable.end() &&
+ isValidPrefix(Command, CI->first); ++CI)
+ ErrorMsg += ", " + CI->first;
+ throw ErrorMsg;
+ } else {
+ // It's an unambiguous prefix of a command, use it.
+ return CI->second;
+ }
+ }
+}
+
+
+/// run - Start the debugger, returning when the user exits the debugger. This
+/// starts the main event loop of the CLI debugger.
+///
+int CLIDebugger::run() {
+ std::string Command;
+ std::cout << Prompt;
+
+ // Keep track of the last command issued, so that we can reissue it if the
+ // user hits enter as the command.
+ CLICommand *LastCommand = 0;
+ std::string LastArgs;
+
+ // Continue reading commands until the end of file.
+ while (getline(std::cin, Command)) {
+ std::string Arguments = Command;
+
+ // Split off the command from the arguments to the command.
+ Command = getToken(Arguments, " \t\n\v\f\r\\/;.*&");
+
+ try {
+ CLICommand *CurCommand;
+
+ if (Command == "") {
+ CurCommand = LastCommand;
+ Arguments = LastArgs;
+ } else {
+ CurCommand = getCommand(Command);
+ }
+
+ // Save the command we are running in case the user wants us to repeat it
+ // next time.
+ LastCommand = CurCommand;
+ LastArgs = Arguments;
+
+ // Finally, execute the command.
+ if (CurCommand)
+ CurCommand->runCommand(*this, Arguments);
+
+ } catch (int RetVal) {
+ // The quit command exits the command loop by throwing an integer return
+ // code.
+ return RetVal;
+ } catch (const std::string &Error) {
+ std::cout << "Error: " << Error << "\n";
+ } catch (const char *Error) {
+ std::cout << "Error: " << Error << "\n";
+ } catch (const NonErrorException &E) {
+ std::cout << E.getMessage() << "\n";
+ } catch (...) {
+ std::cout << "ERROR: Debugger caught unexpected exception!\n";
+ // Attempt to continue.
+ }
+
+ // Write the prompt to get the next bit of user input
+ std::cout << Prompt;
+ }
+
+ return 0;
+}
+
+
+/// askYesNo - Ask the user a question, and demand a yes/no response. If
+/// the user says yes, return true.
+///
+bool CLIDebugger::askYesNo(const std::string &Message) const {
+ std::string Answer;
+ std::cout << Message << " (y or n) " << std::flush;
+ while (getline(std::cin, Answer)) {
+ std::string Val = getToken(Answer);
+ if (getToken(Answer).empty()) {
+ if (Val == "yes" || Val == "y" || Val == "YES" || Val == "Y" ||
+ Val == "Yes")
+ return true;
+ if (Val == "no" || Val == "n" || Val == "NO" || Val == "N" ||
+ Val == "No")
+ return false;
+ }
+
+ std::cout << "Please answer y or n.\n" << Message << " (y or n) "
+ << std::flush;
+ }
+
+ // Ran out of input?
+ return false;
+}
diff --git a/tools/llvm-db/CLIDebugger.h b/tools/llvm-db/CLIDebugger.h
new file mode 100644
index 0000000..0f16c4f
--- /dev/null
+++ b/tools/llvm-db/CLIDebugger.h
@@ -0,0 +1,205 @@
+//===- CLIDebugger.h - LLVM Command Line Interface Debugger -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the CLIDebugger class, which implements a command line
+// interface to the LLVM Debugger library.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLIDEBUGGER_H
+#define CLIDEBUGGER_H
+
+#include "llvm/Debugger/Debugger.h"
+#include <map>
+
+namespace llvm {
+ class CLICommand;
+ class SourceFile;
+ class SourceLanguage;
+ class ProgramInfo;
+ class RuntimeInfo;
+
+ /// CLIDebugger - This class implements the command line interface for the
+ /// LLVM debugger.
+ class CLIDebugger {
+ /// Dbg - The low-level LLVM debugger object that we use to do our dirty
+ /// work.
+ Debugger Dbg;
+
+ /// CommandTable - This table contains a mapping from command names to the
+ /// CLICommand object that implements the command.
+ std::map<std::string, CLICommand*> CommandTable;
+
+ //===------------------------------------------------------------------===//
+ // Data related to the program that is currently loaded. Note that the Dbg
+ // variable also captures some information about the loaded program. This
+ // pointer is non-null iff Dbg.isProgramLoaded() is true.
+ //
+ ProgramInfo *TheProgramInfo;
+
+ //===------------------------------------------------------------------===//
+ // Data related to the program that is currently executing, but has stopped.
+ // Note that the Dbg variable also captures some information about the
+ // loaded program. This pointer is non-null iff Dbg.isProgramRunning() is
+ // true.
+ //
+ RuntimeInfo *TheRuntimeInfo;
+
+ /// LastCurrentFrame - This variable holds the Frame ID of the top-level
+ /// stack frame from the last time that the program was executed. We keep
+ /// this because we only want to print the source location when the current
+ /// function changes.
+ void *LastCurrentFrame;
+
+ //===------------------------------------------------------------------===//
+ // Data directly exposed through the debugger prompt
+ //
+ std::string Prompt; // set prompt, show prompt
+ unsigned ListSize; // set listsize, show listsize
+
+ //===------------------------------------------------------------------===//
+ // Data to support user interaction
+ //
+
+ /// CurrentFile - The current source file we are inspecting, or null if
+ /// none.
+ const SourceFile *CurrentFile;
+ unsigned LineListedStart, LineListedEnd;
+
+ /// CurrentLanguage - This contains the source language in use, if one is
+ /// explicitly set by the user. If this is null (the default), the language
+ /// is automatically determined from the current stack frame.
+ ///
+ const SourceLanguage *CurrentLanguage;
+
+ public:
+ CLIDebugger();
+
+ /// getDebugger - Return the current LLVM debugger implementation being
+ /// used.
+ Debugger &getDebugger() { return Dbg; }
+
+ /// run - Start the debugger, returning when the user exits the debugger.
+ /// This starts the main event loop of the CLI debugger.
+ ///
+ int run();
+
+ /// addCommand - Add a command to the CommandTable, potentially displacing a
+ /// preexisting command.
+ void addCommand(const std::string &Option, CLICommand *Cmd);
+
+ /// addSourceDirectory - Add a directory to search when looking for the
+ /// source code of the program.
+ void addSourceDirectory(const std::string &Dir) {
+ // FIXME: implement
+ }
+
+ /// getCurrentLanguage - Return the current source language that the user is
+ /// playing around with. This is aquired from the current stack frame of a
+ /// running program if one exists, but this value can be explicitly set by
+ /// the user as well.
+ const SourceLanguage &getCurrentLanguage() const;
+
+ /// getProgramInfo - Return a reference to the ProgramInfo object for the
+ /// currently loaded program. If there is no program loaded, throw an
+ /// exception.
+ ProgramInfo &getProgramInfo() const {
+ if (TheProgramInfo == 0)
+ throw "No program is loaded.";
+ return *TheProgramInfo;
+ }
+
+ /// getRuntimeInfo - Return a reference to the current RuntimeInfo object.
+ /// If there is no program running, throw an exception.
+ RuntimeInfo &getRuntimeInfo() const {
+ if (TheRuntimeInfo == 0)
+ throw "No program is running.";
+ return *TheRuntimeInfo;
+ }
+
+ private: // Internal implementation methods
+
+ /// getCommand - This looks up the specified command using a fuzzy match.
+ /// If the string exactly matches a command or is an unambiguous prefix of a
+ /// command, it returns the command. Otherwise it throws an exception
+ /// indicating the possible ambiguous choices.
+ CLICommand *getCommand(const std::string &Command);
+
+ /// askYesNo - Ask the user a question, and demand a yes/no response. If
+ /// the user says yes, return true.
+ bool askYesNo(const std::string &Message) const;
+
+ /// printProgramLocation - Given a loaded and created child process that has
+ /// stopped, print its current source location.
+ void printProgramLocation(bool PrintLocation = true);
+
+ /// eliminateRunInfo - We are about to run the program. Forget any state
+ /// about how the program used to be stopped.
+ void eliminateRunInfo();
+
+ /// programStoppedSuccessfully - This method updates internal data
+ /// structures to reflect the fact that the program just executed a while,
+ /// and has successfully stopped.
+ void programStoppedSuccessfully();
+
+ public: /// Builtin debugger commands, invokable by the user
+ // Program startup and shutdown options
+ void fileCommand(std::string &Options); // file
+ void createCommand(std::string &Options); // create
+ void killCommand(std::string &Options); // kill
+ void quitCommand(std::string &Options); // quit
+
+ // Program execution commands
+ void runCommand(std::string &Options); // run|r
+ void contCommand(std::string &Options); // cont|c|fg
+ void stepCommand(std::string &Options); // step|s [count]
+ void nextCommand(std::string &Options); // next|n [count]
+ void finishCommand(std::string &Options); // finish
+
+ // Stack frame commands
+ void backtraceCommand(std::string &Options); // backtrace|bt [count]
+ void upCommand(std::string &Options); // up
+ void downCommand(std::string &Options); // down
+ void frameCommand(std::string &Options); // frame
+
+
+ // Breakpoint related commands
+ void breakCommand(std::string &Options); // break|b <id>
+
+ // Miscellaneous commands
+ void infoCommand(std::string &Options); // info
+ void listCommand(std::string &Options); // list
+ void setCommand(std::string &Options); // set
+ void showCommand(std::string &Options); // show
+ void helpCommand(std::string &Options); // help
+
+ private:
+ /// startProgramRunning - If the program has been updated, reload it, then
+ /// start executing the program.
+ void startProgramRunning();
+
+ /// printSourceLine - Print the specified line of the current source file.
+ /// If the specified line is invalid (the source file could not be loaded or
+ /// the line number is out of range), don't print anything, but return true.
+ bool printSourceLine(unsigned LineNo);
+
+ /// parseLineSpec - Parses a line specifier, for use by the 'list' command.
+ /// If SourceFile is returned as a void pointer, then it was not specified.
+ /// If the line specifier is invalid, an exception is thrown.
+ void parseLineSpec(std::string &LineSpec, const SourceFile *&SourceFile,
+ unsigned &LineNo);
+
+ /// parseProgramOptions - This method parses the Options string and loads it
+ /// as options to be passed to the program. This is used by the run command
+ /// and by 'set args'.
+ void parseProgramOptions(std::string &Options);
+ };
+}
+
+#endif
diff --git a/tools/llvm-db/Commands.cpp b/tools/llvm-db/Commands.cpp
new file mode 100644
index 0000000..a3d14b0
--- /dev/null
+++ b/tools/llvm-db/Commands.cpp
@@ -0,0 +1,863 @@
+//===-- Commands.cpp - Implement various commands for the CLI -------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements many builtin user commands.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CLIDebugger.h"
+#include "CLICommand.h"
+#include "llvm/Debugger/ProgramInfo.h"
+#include "llvm/Debugger/RuntimeInfo.h"
+#include "llvm/Debugger/SourceLanguage.h"
+#include "llvm/Debugger/SourceFile.h"
+#include "llvm/Debugger/InferiorProcess.h"
+#include "llvm/Support/FileUtilities.h"
+#include "llvm/ADT/StringExtras.h"
+#include <iostream>
+using namespace llvm;
+
+/// getCurrentLanguage - Return the current source language that the user is
+/// playing around with. This is aquired from the current stack frame of a
+/// running program if one exists, but this value can be explicitly set by the
+/// user as well.
+const SourceLanguage &CLIDebugger::getCurrentLanguage() const {
+ // If the user explicitly switched languages with 'set language', use what
+ // they asked for.
+ if (CurrentLanguage) {
+ return *CurrentLanguage;
+ } else if (Dbg.isProgramRunning()) {
+ // Otherwise, if the program is running, infer the current language from it.
+ const GlobalVariable *FuncDesc =
+ getRuntimeInfo().getCurrentFrame().getFunctionDesc();
+ return getProgramInfo().getFunction(FuncDesc).getSourceFile().getLanguage();
+ } else {
+ // Otherwise, default to C like GDB apparently does.
+ return SourceLanguage::getCFamilyInstance();
+ }
+}
+
+/// startProgramRunning - If the program has been updated, reload it, then
+/// start executing the program.
+void CLIDebugger::startProgramRunning() {
+ eliminateRunInfo();
+
+ // If the program has been modified, reload it!
+ sys::PathWithStatus Program(Dbg.getProgramPath());
+ std::string Err;
+ const sys::FileStatus *Status = Program.getFileStatus(false, &Err);
+ if (!Status)
+ throw Err;
+ if (TheProgramInfo->getProgramTimeStamp() != Status->getTimestamp()) {
+ std::cout << "'" << Program << "' has changed; re-reading program.\n";
+
+ // Unload an existing program. This kills the program if necessary.
+ Dbg.unloadProgram();
+ delete TheProgramInfo;
+ TheProgramInfo = 0;
+ CurrentFile = 0;
+
+ Dbg.loadProgram(Program.toString());
+ TheProgramInfo = new ProgramInfo(Dbg.getProgram());
+ }
+
+ std::cout << "Starting program: " << Dbg.getProgramPath() << "\n";
+ Dbg.createProgram();
+
+ // There was no current frame.
+ LastCurrentFrame = 0;
+}
+
+/// printSourceLine - Print the specified line of the current source file.
+/// If the specified line is invalid (the source file could not be loaded or
+/// the line number is out of range), don't print anything, but return true.
+bool CLIDebugger::printSourceLine(unsigned LineNo) {
+ assert(CurrentFile && "There is no current source file to print!");
+ const char *LineStart, *LineEnd;
+ CurrentFile->getSourceLine(LineNo-1, LineStart, LineEnd);
+ if (LineStart == 0) return true;
+ std::cout << LineNo;
+
+ // If this is the line the program is currently stopped at, print a marker.
+ if (Dbg.isProgramRunning()) {
+ unsigned CurLineNo, CurColNo;
+ const SourceFileInfo *CurSFI;
+ getRuntimeInfo().getCurrentFrame().getSourceLocation(CurLineNo, CurColNo,
+ CurSFI);
+
+ if (CurLineNo == LineNo && CurrentFile == &CurSFI->getSourceText())
+ std::cout << " ->";
+ }
+
+ std::cout << "\t" << std::string(LineStart, LineEnd) << "\n";
+ return false;
+}
+
+/// printProgramLocation - Print a line of the place where the current stack
+/// frame has stopped and the source line it is on.
+///
+void CLIDebugger::printProgramLocation(bool PrintLocation) {
+ assert(Dbg.isProgramLoaded() && Dbg.isProgramRunning() &&
+ "Error program is not loaded and running!");
+
+ // Figure out where the program stopped...
+ StackFrame &SF = getRuntimeInfo().getCurrentFrame();
+ unsigned LineNo, ColNo;
+ const SourceFileInfo *FileDesc;
+ SF.getSourceLocation(LineNo, ColNo, FileDesc);
+
+ // If requested, print out some program information about WHERE we are.
+ if (PrintLocation) {
+ // FIXME: print the current function arguments
+ if (const GlobalVariable *FuncDesc = SF.getFunctionDesc())
+ std::cout << getProgramInfo().getFunction(FuncDesc).getSymbolicName();
+ else
+ std::cout << "<unknown function>";
+
+ CurrentFile = &FileDesc->getSourceText();
+
+ std::cout << " at " << CurrentFile->getFilename() << ":" << LineNo;
+ if (ColNo) std::cout << ":" << ColNo;
+ std::cout << "\n";
+ }
+
+ if (printSourceLine(LineNo))
+ std::cout << "<could not load source file>\n";
+ else {
+ LineListedStart = LineNo-ListSize/2+1;
+ if ((int)LineListedStart < 1) LineListedStart = 1;
+ LineListedEnd = LineListedStart+1;
+ }
+}
+
+/// eliminateRunInfo - We are about to run the program. Forget any state
+/// about how the program used to be stopped.
+void CLIDebugger::eliminateRunInfo() {
+ delete TheRuntimeInfo;
+ TheRuntimeInfo = 0;
+}
+
+/// programStoppedSuccessfully - This method updates internal data
+/// structures to reflect the fact that the program just executed a while,
+/// and has successfully stopped.
+void CLIDebugger::programStoppedSuccessfully() {
+ assert(TheRuntimeInfo==0 && "Someone forgot to release the old RuntimeInfo!");
+
+ TheRuntimeInfo = new RuntimeInfo(TheProgramInfo, Dbg.getRunningProcess());
+
+ // FIXME: if there are any breakpoints at the current location, print them as
+ // well.
+
+ // Since the program as successfully stopped, print its location.
+ void *CurrentFrame = getRuntimeInfo().getCurrentFrame().getFrameID();
+ printProgramLocation(CurrentFrame != LastCurrentFrame);
+ LastCurrentFrame = CurrentFrame;
+}
+
+
+
+/// getUnsignedIntegerOption - Get an unsigned integer number from the Val
+/// string. Check to make sure that the string contains an unsigned integer
+/// token, and if not, throw an exception. If isOnlyOption is set, also throw
+/// an exception if there is extra junk at the end of the string.
+static unsigned getUnsignedIntegerOption(const char *Msg, std::string &Val,
+ bool isOnlyOption = true) {
+ std::string Tok = getToken(Val);
+ if (Tok.empty() || (isOnlyOption && !getToken(Val).empty()))
+ throw std::string(Msg) + " expects an unsigned integer argument.";
+
+ char *EndPtr;
+ unsigned Result = strtoul(Tok.c_str(), &EndPtr, 0);
+ if (EndPtr != Tok.c_str()+Tok.size())
+ throw std::string(Msg) + " expects an unsigned integer argument.";
+
+ return Result;
+}
+
+/// getOptionalUnsignedIntegerOption - This method is just like
+/// getUnsignedIntegerOption, but if the argument value is not specified, a
+/// default is returned instead of causing an error.
+static unsigned
+getOptionalUnsignedIntegerOption(const char *Msg, unsigned Default,
+ std::string &Val, bool isOnlyOption = true) {
+ // Check to see if the value was specified...
+ std::string TokVal = getToken(Val);
+ if (TokVal.empty()) return Default;
+
+ // If it was specified, add it back to the value we are parsing...
+ Val = TokVal+Val;
+
+ // And parse normally.
+ return getUnsignedIntegerOption(Msg, Val, isOnlyOption);
+}
+
+
+/// parseProgramOptions - This method parses the Options string and loads it
+/// as options to be passed to the program. This is used by the run command
+/// and by 'set args'.
+void CLIDebugger::parseProgramOptions(std::string &Options) {
+ // FIXME: tokenizing by whitespace is clearly incorrect. Instead we should
+ // honor quotes and other things that a shell would. Also in the future we
+ // should support redirection of standard IO.
+
+ std::vector<std::string> Arguments;
+ for (std::string A = getToken(Options); !A.empty(); A = getToken(Options))
+ Arguments.push_back(A);
+ Dbg.setProgramArguments(Arguments.begin(), Arguments.end());
+}
+
+
+//===----------------------------------------------------------------------===//
+// Program startup and shutdown options
+//===----------------------------------------------------------------------===//
+
+
+/// file command - If the user specifies an option, search the PATH for the
+/// specified program/bitcode file and load it. If the user does not specify
+/// an option, unload the current program.
+void CLIDebugger::fileCommand(std::string &Options) {
+ std::string Prog = getToken(Options);
+ if (!getToken(Options).empty())
+ throw "file command takes at most one argument.";
+
+ // Check to make sure the user knows what they are doing
+ if (Dbg.isProgramRunning() &&
+ !askYesNo("A program is already loaded. Kill it?"))
+ return;
+
+ // Unload an existing program. This kills the program if necessary.
+ eliminateRunInfo();
+ delete TheProgramInfo;
+ TheProgramInfo = 0;
+ Dbg.unloadProgram();
+ CurrentFile = 0;
+
+ // If requested, start the new program.
+ if (Prog.empty()) {
+ std::cout << "Unloaded program.\n";
+ } else {
+ std::cout << "Loading program... " << std::flush;
+ Dbg.loadProgram(Prog);
+ assert(Dbg.isProgramLoaded() &&
+ "loadProgram succeeded, but not program loaded!");
+ TheProgramInfo = new ProgramInfo(Dbg.getProgram());
+ std::cout << "successfully loaded '" << Dbg.getProgramPath() << "'!\n";
+ }
+}
+
+
+void CLIDebugger::createCommand(std::string &Options) {
+ if (!getToken(Options).empty())
+ throw "create command does not take any arguments.";
+ if (!Dbg.isProgramLoaded()) throw "No program loaded.";
+ if (Dbg.isProgramRunning() &&
+ !askYesNo("The program is already running. Restart from the beginning?"))
+ return;
+
+ // Start the program running.
+ startProgramRunning();
+
+ // The program stopped!
+ programStoppedSuccessfully();
+}
+
+void CLIDebugger::killCommand(std::string &Options) {
+ if (!getToken(Options).empty())
+ throw "kill command does not take any arguments.";
+ if (!Dbg.isProgramRunning())
+ throw "No program is currently being run.";
+
+ if (askYesNo("Kill the program being debugged?"))
+ Dbg.killProgram();
+ eliminateRunInfo();
+}
+
+void CLIDebugger::quitCommand(std::string &Options) {
+ if (!getToken(Options).empty())
+ throw "quit command does not take any arguments.";
+
+ if (Dbg.isProgramRunning() &&
+ !askYesNo("The program is running. Exit anyway?"))
+ return;
+
+ // Throw exception to get out of the user-input loop.
+ throw 0;
+}
+
+
+//===----------------------------------------------------------------------===//
+// Program execution commands
+//===----------------------------------------------------------------------===//
+
+void CLIDebugger::runCommand(std::string &Options) {
+ if (!Dbg.isProgramLoaded()) throw "No program loaded.";
+ if (Dbg.isProgramRunning() &&
+ !askYesNo("The program is already running. Restart from the beginning?"))
+ return;
+
+ // Parse all of the options to the run command, which specify program
+ // arguments to run with.
+ parseProgramOptions(Options);
+
+ eliminateRunInfo();
+
+ // Start the program running.
+ startProgramRunning();
+
+ // Start the program running...
+ Options = "";
+ contCommand(Options);
+}
+
+void CLIDebugger::contCommand(std::string &Options) {
+ if (!getToken(Options).empty()) throw "cont argument not supported yet.";
+ if (!Dbg.isProgramRunning()) throw "Program is not running.";
+
+ eliminateRunInfo();
+
+ Dbg.contProgram();
+
+ // The program stopped!
+ programStoppedSuccessfully();
+}
+
+void CLIDebugger::stepCommand(std::string &Options) {
+ if (!Dbg.isProgramRunning()) throw "Program is not running.";
+
+ // Figure out how many times to step.
+ unsigned Amount =
+ getOptionalUnsignedIntegerOption("'step' command", 1, Options);
+
+ eliminateRunInfo();
+
+ // Step the specified number of times.
+ for (; Amount; --Amount)
+ Dbg.stepProgram();
+
+ // The program stopped!
+ programStoppedSuccessfully();
+}
+
+void CLIDebugger::nextCommand(std::string &Options) {
+ if (!Dbg.isProgramRunning()) throw "Program is not running.";
+ unsigned Amount =
+ getOptionalUnsignedIntegerOption("'next' command", 1, Options);
+
+ eliminateRunInfo();
+
+ for (; Amount; --Amount)
+ Dbg.nextProgram();
+
+ // The program stopped!
+ programStoppedSuccessfully();
+}
+
+void CLIDebugger::finishCommand(std::string &Options) {
+ if (!getToken(Options).empty())
+ throw "finish command does not take any arguments.";
+ if (!Dbg.isProgramRunning()) throw "Program is not running.";
+
+ // Figure out where we are exactly. If the user requests that we return from
+ // a frame that is not the top frame, make sure we get it.
+ void *CurrentFrame = getRuntimeInfo().getCurrentFrame().getFrameID();
+
+ eliminateRunInfo();
+
+ Dbg.finishProgram(CurrentFrame);
+
+ // The program stopped!
+ programStoppedSuccessfully();
+}
+
+//===----------------------------------------------------------------------===//
+// Stack frame commands
+//===----------------------------------------------------------------------===//
+
+void CLIDebugger::backtraceCommand(std::string &Options) {
+ // Accepts "full", n, -n
+ if (!getToken(Options).empty())
+ throw "FIXME: bt command argument not implemented yet!";
+
+ RuntimeInfo &RI = getRuntimeInfo();
+ ProgramInfo &PI = getProgramInfo();
+
+ try {
+ for (unsigned i = 0; ; ++i) {
+ StackFrame &SF = RI.getStackFrame(i);
+ std::cout << "#" << i;
+ if (i == RI.getCurrentFrameIdx())
+ std::cout << " ->";
+ std::cout << "\t" << SF.getFrameID() << " in ";
+ if (const GlobalVariable *G = SF.getFunctionDesc())
+ std::cout << PI.getFunction(G).getSymbolicName();
+
+ unsigned LineNo, ColNo;
+ const SourceFileInfo *SFI;
+ SF.getSourceLocation(LineNo, ColNo, SFI);
+ if (!SFI->getBaseName().empty()) {
+ std::cout << " at " << SFI->getBaseName();
+ if (LineNo) {
+ std::cout << ":" << LineNo;
+ if (ColNo)
+ std::cout << ":" << ColNo;
+ }
+ }
+
+ // FIXME: when we support shared libraries, we should print ' from foo.so'
+ // if the stack frame is from a different object than the current one.
+
+ std::cout << "\n";
+ }
+ } catch (...) {
+ // Stop automatically when we run off the bottom of the stack.
+ }
+}
+
+void CLIDebugger::upCommand(std::string &Options) {
+ unsigned Num =
+ getOptionalUnsignedIntegerOption("'up' command", 1, Options);
+
+ RuntimeInfo &RI = getRuntimeInfo();
+ unsigned CurFrame = RI.getCurrentFrameIdx();
+
+ // Check to see if we go can up the specified number of frames.
+ try {
+ RI.getStackFrame(CurFrame+Num);
+ } catch (...) {
+ if (Num == 1)
+ throw "Initial frame selected; you cannot go up.";
+ else
+ throw "Cannot go up " + utostr(Num) + " frames!";
+ }
+
+ RI.setCurrentFrameIdx(CurFrame+Num);
+ printProgramLocation();
+}
+
+void CLIDebugger::downCommand(std::string &Options) {
+ unsigned Num =
+ getOptionalUnsignedIntegerOption("'down' command", 1, Options);
+
+ RuntimeInfo &RI = getRuntimeInfo();
+ unsigned CurFrame = RI.getCurrentFrameIdx();
+
+ // Check to see if we can go up the specified number of frames.
+ if (CurFrame < Num)
+ if (Num == 1)
+ throw "Bottom (i.e., innermost) frame selected; you cannot go down.";
+ else
+ throw "Cannot go down " + utostr(Num) + " frames!";
+
+ RI.setCurrentFrameIdx(CurFrame-Num);
+ printProgramLocation();
+}
+
+void CLIDebugger::frameCommand(std::string &Options) {
+ RuntimeInfo &RI = getRuntimeInfo();
+ unsigned CurFrame = RI.getCurrentFrameIdx();
+
+ unsigned Num =
+ getOptionalUnsignedIntegerOption("'frame' command", CurFrame, Options);
+
+ // Check to see if we go to the specified frame.
+ RI.getStackFrame(Num);
+
+ RI.setCurrentFrameIdx(Num);
+ printProgramLocation();
+}
+
+
+//===----------------------------------------------------------------------===//
+// Breakpoint related commands
+//===----------------------------------------------------------------------===//
+
+void CLIDebugger::breakCommand(std::string &Options) {
+ // Figure out where the user wants a breakpoint.
+ const SourceFile *File;
+ unsigned LineNo;
+
+ // Check to see if the user specified a line specifier.
+ std::string Option = getToken(Options); // strip whitespace
+ if (!Option.empty()) {
+ Options = Option + Options; // reconstruct string
+
+ // Parse the line specifier.
+ parseLineSpec(Options, File, LineNo);
+ } else {
+ // Build a line specifier for the current stack frame.
+ throw "FIXME: breaking at the current location is not implemented yet!";
+ }
+
+ if (!File) File = CurrentFile;
+ if (File == 0)
+ throw "Unknown file to place breakpoint!";
+
+ std::cerr << "Break: " << File->getFilename() << ":" << LineNo << "\n";
+
+ throw "breakpoints not implemented yet!";
+}
+
+//===----------------------------------------------------------------------===//
+// Miscellaneous commands
+//===----------------------------------------------------------------------===//
+
+void CLIDebugger::infoCommand(std::string &Options) {
+ std::string What = getToken(Options);
+
+ if (What.empty() || !getToken(Options).empty()){
+ std::string infoStr("info");
+ helpCommand(infoStr);
+ return;
+ }
+
+ if (What == "frame") {
+ } else if (What == "functions") {
+ const std::map<const GlobalVariable*, SourceFunctionInfo*> &Functions
+ = getProgramInfo().getSourceFunctions();
+ std::cout << "All defined functions:\n";
+ // FIXME: GDB groups these by source file. We could do that I guess.
+ for (std::map<const GlobalVariable*, SourceFunctionInfo*>::const_iterator
+ I = Functions.begin(), E = Functions.end(); I != E; ++I) {
+ std::cout << I->second->getSymbolicName() << "\n";
+ }
+
+ } else if (What == "source") {
+ if (CurrentFile == 0)
+ throw "No current source file.";
+
+ // Get the SourceFile information for the current file.
+ const SourceFileInfo &SF =
+ getProgramInfo().getSourceFile(CurrentFile->getDescriptor());
+
+ std::cout << "Current source file is: " << SF.getBaseName() << "\n"
+ << "Compilation directory is: " << SF.getDirectory() << "\n";
+ if (unsigned NL = CurrentFile->getNumLines())
+ std::cout << "Located in: " << CurrentFile->getFilename() << "\n"
+ << "Contains " << NL << " lines\n";
+ else
+ std::cout << "Could not find source file.\n";
+ std::cout << "Source language is "
+ << SF.getLanguage().getSourceLanguageName() << "\n";
+
+ } else if (What == "sources") {
+ const std::map<const GlobalVariable*, SourceFileInfo*> &SourceFiles =
+ getProgramInfo().getSourceFiles();
+ std::cout << "Source files for the program:\n";
+ for (std::map<const GlobalVariable*, SourceFileInfo*>::const_iterator I =
+ SourceFiles.begin(), E = SourceFiles.end(); I != E;) {
+ std::cout << I->second->getDirectory() << "/"
+ << I->second->getBaseName();
+ ++I;
+ if (I != E) std::cout << ", ";
+ }
+ std::cout << "\n";
+ } else if (What == "target") {
+ std::cout << Dbg.getRunningProcess().getStatus();
+ } else {
+ // See if this is something handled by the current language.
+ if (getCurrentLanguage().printInfo(What))
+ return;
+
+ throw "Unknown info command '" + What + "'. Try 'help info'.";
+ }
+}
+
+/// parseLineSpec - Parses a line specifier, for use by the 'list' command.
+/// If SourceFile is returned as a void pointer, then it was not specified.
+/// If the line specifier is invalid, an exception is thrown.
+void CLIDebugger::parseLineSpec(std::string &LineSpec,
+ const SourceFile *&SourceFile,
+ unsigned &LineNo) {
+ SourceFile = 0;
+ LineNo = 0;
+
+ // First, check to see if we have a : separator.
+ std::string FirstPart = getToken(LineSpec, ":");
+ std::string SecondPart = getToken(LineSpec, ":");
+ if (!getToken(LineSpec).empty()) throw "Malformed line specification!";
+
+ // If there is no second part, we must have either "function", "number",
+ // "+offset", or "-offset".
+ if (SecondPart.empty()) {
+ if (FirstPart.empty()) throw "Malformed line specification!";
+ if (FirstPart[0] == '+') {
+ FirstPart.erase(FirstPart.begin(), FirstPart.begin()+1);
+ // For +n, return LineListedEnd+n
+ LineNo = LineListedEnd +
+ getUnsignedIntegerOption("Line specifier '+'", FirstPart);
+
+ } else if (FirstPart[0] == '-') {
+ FirstPart.erase(FirstPart.begin(), FirstPart.begin()+1);
+ // For -n, return LineListedEnd-n
+ LineNo = LineListedEnd -
+ getUnsignedIntegerOption("Line specifier '-'", FirstPart);
+ if ((int)LineNo < 1) LineNo = 1;
+ } else if (FirstPart[0] == '*') {
+ throw "Address expressions not supported as source locations!";
+ } else {
+ // Ok, check to see if this is just a line number.
+ std::string Saved = FirstPart;
+ try {
+ LineNo = getUnsignedIntegerOption("", Saved);
+ } catch (...) {
+ // Ok, it's not a valid line number. It must be a source-language
+ // entity name.
+ std::string Name = getToken(FirstPart);
+ if (!getToken(FirstPart).empty())
+ throw "Extra junk in line specifier after '" + Name + "'.";
+ SourceFunctionInfo *SFI =
+ getCurrentLanguage().lookupFunction(Name, getProgramInfo(),
+ TheRuntimeInfo);
+ if (SFI == 0)
+ throw "Unknown identifier '" + Name + "'.";
+
+ unsigned L, C;
+ SFI->getSourceLocation(L, C);
+ if (L == 0) throw "Could not locate '" + Name + "'!";
+ LineNo = L;
+ SourceFile = &SFI->getSourceFile().getSourceText();
+ return;
+ }
+ }
+
+ } else {
+ // Ok, this must be a filename qualified line number or function name.
+ // First, figure out the source filename.
+ std::string SourceFilename = getToken(FirstPart);
+ if (!getToken(FirstPart).empty())
+ throw "Invalid filename qualified source location!";
+
+ // Next, check to see if this is just a line number.
+ std::string Saved = SecondPart;
+ try {
+ LineNo = getUnsignedIntegerOption("", Saved);
+ } catch (...) {
+ // Ok, it's not a valid line number. It must be a function name.
+ throw "FIXME: Filename qualified function names are not support "
+ "as line specifiers yet!";
+ }
+
+ // Ok, we got the line number. Now check out the source file name to make
+ // sure it's all good. If it is, return it. If not, throw exception.
+ SourceFile =&getProgramInfo().getSourceFile(SourceFilename).getSourceText();
+ }
+}
+
+void CLIDebugger::listCommand(std::string &Options) {
+ if (!Dbg.isProgramLoaded())
+ throw "No program is loaded. Use the 'file' command.";
+
+ // Handle "list foo," correctly, by returning " " as the second token
+ Options += " ";
+
+ std::string FirstLineSpec = getToken(Options, ",");
+ std::string SecondLineSpec = getToken(Options, ",");
+ if (!getToken(Options, ",").empty())
+ throw "list command only expects two source location specifiers!";
+
+ // StartLine, EndLine - The starting and ending line numbers to print.
+ unsigned StartLine = 0, EndLine = 0;
+
+ if (SecondLineSpec.empty()) { // No second line specifier provided?
+ // Handle special forms like "", "+", "-", etc.
+ std::string TmpSpec = FirstLineSpec;
+ std::string Tok = getToken(TmpSpec);
+ if (getToken(TmpSpec).empty() && (Tok == "" || Tok == "+" || Tok == "-")) {
+ if (Tok == "+" || Tok == "") {
+ StartLine = LineListedEnd;
+ EndLine = StartLine + ListSize;
+ } else {
+ assert(Tok == "-");
+ StartLine = LineListedStart-ListSize;
+ EndLine = LineListedStart;
+ if ((int)StartLine <= 0) StartLine = 1;
+ }
+ } else {
+ // Must be a normal line specifier.
+ const SourceFile *File;
+ unsigned LineNo;
+ parseLineSpec(FirstLineSpec, File, LineNo);
+
+ // If the user only specified one file specifier, we should display
+ // ListSize lines centered at the specified line.
+ if (File != 0) CurrentFile = File;
+ StartLine = LineNo - (ListSize+1)/2;
+ if ((int)StartLine <= 0) StartLine = 1;
+ EndLine = StartLine + ListSize;
+ }
+
+ } else {
+ // Parse two line specifiers...
+ const SourceFile *StartFile, *EndFile;
+ unsigned StartLineNo, EndLineNo;
+ parseLineSpec(FirstLineSpec, StartFile, StartLineNo);
+ unsigned SavedLLE = LineListedEnd;
+ LineListedEnd = StartLineNo;
+ try {
+ parseLineSpec(SecondLineSpec, EndFile, EndLineNo);
+ } catch (...) {
+ LineListedEnd = SavedLLE;
+ throw;
+ }
+
+ // Inherit file specified by the first line spec if there was one.
+ if (EndFile == 0) EndFile = StartFile;
+
+ if (StartFile != EndFile)
+ throw "Start and end line specifiers are in different files!";
+ CurrentFile = StartFile;
+ StartLine = StartLineNo;
+ EndLine = EndLineNo+1;
+ }
+
+ assert((int)StartLine > 0 && (int)EndLine > 0 && StartLine <= EndLine &&
+ "Error reading line specifiers!");
+
+ // If there was no current file, and the user didn't specify one to list, we
+ // have an error.
+ if (CurrentFile == 0)
+ throw "There is no current file to list.";
+
+ // Remember for next time.
+ LineListedStart = StartLine;
+ LineListedEnd = StartLine;
+
+ for (unsigned LineNo = StartLine; LineNo != EndLine; ++LineNo) {
+ // Print the source line, unless it is invalid.
+ if (printSourceLine(LineNo))
+ break;
+ LineListedEnd = LineNo+1;
+ }
+
+ // If we didn't print any lines, find out why.
+ if (LineListedEnd == StartLine) {
+ // See if we can read line #0 from the file, if not, we couldn't load the
+ // file.
+ const char *LineStart, *LineEnd;
+ CurrentFile->getSourceLine(0, LineStart, LineEnd);
+ if (LineStart == 0)
+ throw "Could not load source file '" + CurrentFile->getFilename() + "'!";
+ else
+ std::cout << "<end of file>\n";
+ }
+}
+
+void CLIDebugger::setCommand(std::string &Options) {
+ std::string What = getToken(Options);
+
+ if (What.empty())
+ throw "set command expects at least two arguments.";
+ if (What == "args") {
+ parseProgramOptions(Options);
+ } else if (What == "language") {
+ std::string Lang = getToken(Options);
+ if (!getToken(Options).empty())
+ throw "set language expects one argument at most.";
+ if (Lang == "") {
+ std::cout << "The currently understood settings are:\n\n"
+ << "local or auto Automatic setting based on source file\n"
+ << "c Use the C language\n"
+ << "c++ Use the C++ language\n"
+ << "unknown Use when source language is not supported\n";
+ } else if (Lang == "local" || Lang == "auto") {
+ CurrentLanguage = 0;
+ } else if (Lang == "c") {
+ CurrentLanguage = &SourceLanguage::getCFamilyInstance();
+ } else if (Lang == "c++") {
+ CurrentLanguage = &SourceLanguage::getCPlusPlusInstance();
+ } else if (Lang == "unknown") {
+ CurrentLanguage = &SourceLanguage::getUnknownLanguageInstance();
+ } else {
+ throw "Unknown language '" + Lang + "'.";
+ }
+
+ } else if (What == "listsize") {
+ ListSize = getUnsignedIntegerOption("'set prompt' command", Options);
+ } else if (What == "prompt") {
+ // Include any trailing whitespace or other tokens, but not leading
+ // whitespace.
+ Prompt = getToken(Options); // Strip leading whitespace
+ Prompt += Options; // Keep trailing whitespace or other stuff
+ } else {
+ // FIXME: Try to parse this as a source-language program expression.
+ throw "Don't know how to set '" + What + "'!";
+ }
+}
+
+void CLIDebugger::showCommand(std::string &Options) {
+ std::string What = getToken(Options);
+
+ if (What.empty() || !getToken(Options).empty())
+ throw "show command expects one argument.";
+
+ if (What == "args") {
+ std::cout << "Argument list to give program when started is \"";
+ // FIXME: This doesn't print stuff correctly if the arguments have spaces in
+ // them, but currently the only way to get that is to use the --args command
+ // line argument. This should really handle escaping all hard characters as
+ // needed.
+ for (unsigned i = 0, e = Dbg.getNumProgramArguments(); i != e; ++i)
+ std::cout << (i ? " " : "") << Dbg.getProgramArgument(i);
+ std::cout << "\"\n";
+
+ } else if (What == "language") {
+ std::cout << "The current source language is '";
+ if (CurrentLanguage)
+ std::cout << CurrentLanguage->getSourceLanguageName();
+ else
+ std::cout << "auto; currently "
+ << getCurrentLanguage().getSourceLanguageName();
+ std::cout << "'.\n";
+ } else if (What == "listsize") {
+ std::cout << "Number of source lines llvm-db will list by default is "
+ << ListSize << ".\n";
+ } else if (What == "prompt") {
+ std::cout << "llvm-db's prompt is \"" << Prompt << "\".\n";
+ } else {
+ throw "Unknown show command '" + What + "'. Try 'help show'.";
+ }
+}
+
+void CLIDebugger::helpCommand(std::string &Options) {
+ // Print out all of the commands in the CommandTable
+ std::string Command = getToken(Options);
+ if (!getToken(Options).empty())
+ throw "help command takes at most one argument.";
+
+ // Getting detailed help on a particular command?
+ if (!Command.empty()) {
+ CLICommand *C = getCommand(Command);
+ std::cout << C->getShortHelp() << ".\n" << C->getLongHelp();
+
+ // If there are aliases for this option, print them out.
+ const std::vector<std::string> &Names = C->getOptionNames();
+ if (Names.size() > 1) {
+ std::cout << "The '" << Command << "' command is known as: '"
+ << Names[0] << "'";
+ for (unsigned i = 1, e = Names.size(); i != e; ++i)
+ std::cout << ", '" << Names[i] << "'";
+ std::cout << "\n";
+ }
+
+ } else {
+ unsigned MaxSize = 0;
+ for (std::map<std::string, CLICommand*>::iterator I = CommandTable.begin(),
+ E = CommandTable.end(); I != E; ++I)
+ if (I->first.size() > MaxSize &&
+ I->first == I->second->getPrimaryOptionName())
+ MaxSize = I->first.size();
+
+ // Loop over all of the commands, printing the short help version
+ for (std::map<std::string, CLICommand*>::iterator I = CommandTable.begin(),
+ E = CommandTable.end(); I != E; ++I)
+ if (I->first == I->second->getPrimaryOptionName())
+ std::cout << I->first << std::string(MaxSize - I->first.size(), ' ')
+ << " - " << I->second->getShortHelp() << "\n";
+ }
+}
diff --git a/tools/llvm-db/Makefile b/tools/llvm-db/Makefile
new file mode 100644
index 0000000..1bc3c19
--- /dev/null
+++ b/tools/llvm-db/Makefile
@@ -0,0 +1,15 @@
+##===- tools/llvm-db/Makefile ------------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file was developed by the LLVM research group and is distributed under
+# the University of Illinois Open Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../..
+TOOLNAME = llvm-db
+LINK_COMPONENTS := debugger
+REQUIRES_EH := 1
+
+include $(LEVEL)/Makefile.common
diff --git a/tools/llvm-db/llvm-db.cpp b/tools/llvm-db/llvm-db.cpp
new file mode 100644
index 0000000..57994bf
--- /dev/null
+++ b/tools/llvm-db/llvm-db.cpp
@@ -0,0 +1,96 @@
+//===- llvm-db.cpp - LLVM Debugger ----------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This utility implements a simple text-mode front-end to the LLVM debugger
+// library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CLIDebugger.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/System/Signals.h"
+#include <iostream>
+using namespace llvm;
+
+namespace {
+ // Command line options for specifying the program to debug and options to use
+ cl::opt<std::string>
+ InputFile(cl::desc("<program>"), cl::Positional, cl::init(""));
+
+ cl::list<std::string>
+ InputArgs("args", cl::Positional, cl::desc("<program and arguments>"),
+ cl::ZeroOrMore);
+
+ // Command line options to control various directory related stuff
+ cl::list<std::string>
+ SourceDirectories("directory", cl::value_desc("directory"),
+ cl::desc("Add directory to the search for source files"));
+ cl::alias SDA("d", cl::desc("Alias for --directory"),
+ cl::aliasopt(SourceDirectories));
+
+ cl::opt<std::string>
+ WorkingDirectory("cd", cl::desc("Use directory as current working directory"),
+ cl::value_desc("directory"));
+
+ // Command line options specific to the llvm-db debugger driver
+ cl::opt<bool> Quiet("quiet", cl::desc("Do not print introductory messages"));
+ cl::alias QA1("silent", cl::desc("Alias for -quiet"), cl::aliasopt(Quiet));
+ cl::alias QA2("q", cl::desc("Alias for -quiet"), cl::aliasopt(Quiet));
+}
+
+//===----------------------------------------------------------------------===//
+// main Driver function
+//
+int main(int argc, char **argv, char * const *envp) {
+ llvm_shutdown_obj X; // Call llvm_shutdown() on exit.
+ std::cout << "NOTE: llvm-db is known useless right now.\n";
+ try {
+ cl::ParseCommandLineOptions(argc, argv,
+ " llvm source-level debugger\n");
+ sys::PrintStackTraceOnErrorSignal();
+
+ if (!Quiet)
+ std::cout << "llvm-db: The LLVM source-level debugger\n";
+
+ // Merge Inputfile and InputArgs into the InputArgs list...
+ if (!InputFile.empty() && InputArgs.empty())
+ InputArgs.push_back(InputFile);
+
+ // Create the CLI debugger...
+ CLIDebugger D;
+
+ // Initialize the debugger with the command line options we read...
+ Debugger &Dbg = D.getDebugger();
+
+ // Initialize the debugger environment.
+ Dbg.initializeEnvironment(envp);
+ Dbg.setWorkingDirectory(WorkingDirectory);
+ for (unsigned i = 0, e = SourceDirectories.size(); i != e; ++i)
+ D.addSourceDirectory(SourceDirectories[i]);
+
+ if (!InputArgs.empty()) {
+ try {
+ D.fileCommand(InputArgs[0]);
+ } catch (const std::string &Error) {
+ std::cout << "Error: " << Error << "\n";
+ }
+
+ Dbg.setProgramArguments(InputArgs.begin()+1, InputArgs.end());
+ }
+
+ // Now that we have initialized the debugger, run it.
+ return D.run();
+ } catch (const std::string& msg) {
+ std::cerr << argv[0] << ": " << msg << "\n";
+ } catch (...) {
+ std::cerr << argv[0] << ": Unexpected unknown exception occurred.\n";
+ }
+ return 1;
+}
diff --git a/tools/llvm-dis/Makefile b/tools/llvm-dis/Makefile
new file mode 100644
index 0000000..8e9501d
--- /dev/null
+++ b/tools/llvm-dis/Makefile
@@ -0,0 +1,15 @@
+##===- tools/llvm-dis/Makefile ------------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file was developed by the LLVM research group and is distributed under
+# the University of Illinois Open Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+LEVEL = ../..
+
+TOOLNAME = llvm-dis
+LINK_COMPONENTS := bitreader
+REQUIRES_EH := 1
+
+include $(LEVEL)/Makefile.common
diff --git a/tools/llvm-dis/llvm-dis.cpp b/tools/llvm-dis/llvm-dis.cpp
new file mode 100644
index 0000000..0c87f8c
--- /dev/null
+++ b/tools/llvm-dis/llvm-dis.cpp
@@ -0,0 +1,138 @@
+//===-- llvm-dis.cpp - The low-level LLVM disassembler --------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This utility may be invoked in the following manner:
+// llvm-dis [options] - Read LLVM bitcode from stdin, write asm to stdout
+// llvm-dis [options] x.bc - Read LLVM bitcode from the x.bc file, write asm
+// to the x.ll file.
+// Options:
+// --help - Output information about command line switches
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Module.h"
+#include "llvm/PassManager.h"
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/Assembly/PrintModulePass.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Streams.h"
+#include "llvm/System/Signals.h"
+#include <iostream>
+#include <fstream>
+#include <memory>
+using namespace llvm;
+
+static cl::opt<std::string>
+InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-"));
+
+static cl::opt<std::string>
+OutputFilename("o", cl::desc("Override output filename"),
+ cl::value_desc("filename"));
+
+static cl::opt<bool>
+Force("f", cl::desc("Overwrite output files"));
+
+static cl::opt<bool>
+DontPrint("disable-output", cl::desc("Don't output the .ll file"), cl::Hidden);
+
+int main(int argc, char **argv) {
+ llvm_shutdown_obj X; // Call llvm_shutdown() on exit.
+ try {
+ cl::ParseCommandLineOptions(argc, argv, " llvm .bc -> .ll disassembler\n");
+ sys::PrintStackTraceOnErrorSignal();
+
+ std::ostream *Out = &std::cout; // Default to printing to stdout.
+ std::string ErrorMessage;
+
+ std::auto_ptr<Module> M;
+
+ if (MemoryBuffer *Buffer
+ = MemoryBuffer::getFileOrSTDIN(InputFilename, &ErrorMessage)) {
+ M.reset(ParseBitcodeFile(Buffer, &ErrorMessage));
+ delete Buffer;
+ }
+
+ if (M.get() == 0) {
+ cerr << argv[0] << ": ";
+ if (ErrorMessage.size())
+ cerr << ErrorMessage << "\n";
+ else
+ cerr << "bitcode didn't read correctly.\n";
+ return 1;
+ }
+
+ if (DontPrint) {
+ // Just use stdout. We won't actually print anything on it.
+ } else if (OutputFilename != "") { // Specified an output filename?
+ if (OutputFilename != "-") { // Not stdout?
+ if (!Force && std::ifstream(OutputFilename.c_str())) {
+ // If force is not specified, make sure not to overwrite a file!
+ cerr << argv[0] << ": error opening '" << OutputFilename
+ << "': file exists! Sending to standard output.\n";
+ } else {
+ Out = new std::ofstream(OutputFilename.c_str());
+ }
+ }
+ } else {
+ if (InputFilename == "-") {
+ OutputFilename = "-";
+ } else {
+ std::string IFN = InputFilename;
+ int Len = IFN.length();
+ if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') {
+ // Source ends in .bc
+ OutputFilename = std::string(IFN.begin(), IFN.end()-3)+".ll";
+ } else {
+ OutputFilename = IFN+".ll";
+ }
+
+ if (!Force && std::ifstream(OutputFilename.c_str())) {
+ // If force is not specified, make sure not to overwrite a file!
+ cerr << argv[0] << ": error opening '" << OutputFilename
+ << "': file exists! Sending to standard output.\n";
+ } else {
+ Out = new std::ofstream(OutputFilename.c_str());
+
+ // Make sure that the Out file gets unlinked from the disk if we get a
+ // SIGINT
+ sys::RemoveFileOnSignal(sys::Path(OutputFilename));
+ }
+ }
+ }
+
+ if (!Out->good()) {
+ cerr << argv[0] << ": error opening " << OutputFilename
+ << ": sending to stdout instead!\n";
+ Out = &std::cout;
+ }
+
+ // All that llvm-dis does is write the assembly to a file.
+ if (!DontPrint) {
+ PassManager Passes;
+ OStream L(*Out);
+ Passes.add(new PrintModulePass(&L));
+ Passes.run(*M.get());
+ }
+
+ if (Out != &std::cout) {
+ ((std::ofstream*)Out)->close();
+ delete Out;
+ }
+ return 0;
+ } catch (const std::string& msg) {
+ cerr << argv[0] << ": " << msg << "\n";
+ } catch (...) {
+ cerr << argv[0] << ": Unexpected unknown exception occurred.\n";
+ }
+
+ return 1;
+}
+
diff --git a/tools/llvm-extract/Makefile b/tools/llvm-extract/Makefile
new file mode 100644
index 0000000..fafa1cb
--- /dev/null
+++ b/tools/llvm-extract/Makefile
@@ -0,0 +1,15 @@
+##===- tools/llvm-extract/Makefile -------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file was developed by the LLVM research group and is distributed under
+# the University of Illinois Open Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../..
+
+TOOLNAME = llvm-extract
+LINK_COMPONENTS := ipo bitreader bitwriter
+
+include $(LEVEL)/Makefile.common
diff --git a/tools/llvm-extract/llvm-extract.cpp b/tools/llvm-extract/llvm-extract.cpp
new file mode 100644
index 0000000..becceb6
--- /dev/null
+++ b/tools/llvm-extract/llvm-extract.cpp
@@ -0,0 +1,117 @@
+//===- llvm-extract.cpp - LLVM function extraction utility ----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This utility changes the input module to only contain a single function,
+// which is primarily used for debugging transformations.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Module.h"
+#include "llvm/PassManager.h"
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/Transforms/IPO.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/System/Signals.h"
+#include <iostream>
+#include <memory>
+#include <fstream>
+using namespace llvm;
+
+// InputFilename - The filename to read from.
+static cl::opt<std::string>
+InputFilename(cl::Positional, cl::desc("<input bitcode file>"),
+ cl::init("-"), cl::value_desc("filename"));
+
+static cl::opt<std::string>
+OutputFilename("o", cl::desc("Specify output filename"),
+ cl::value_desc("filename"), cl::init("-"));
+
+static cl::opt<bool>
+Force("f", cl::desc("Overwrite output files"));
+
+static cl::opt<bool>
+DeleteFn("delete", cl::desc("Delete specified function from Module"));
+
+static cl::opt<bool>
+Relink("relink",
+ cl::desc("Turn external linkage for callees of function to delete"));
+
+// ExtractFunc - The function to extract from the module... defaults to main.
+static cl::opt<std::string>
+ExtractFunc("func", cl::desc("Specify function to extract"), cl::init("main"),
+ cl::value_desc("function"));
+
+int main(int argc, char **argv) {
+ llvm_shutdown_obj X; // Call llvm_shutdown() on exit.
+ cl::ParseCommandLineOptions(argc, argv, " llvm extractor\n");
+ sys::PrintStackTraceOnErrorSignal();
+
+ std::auto_ptr<Module> M;
+
+ MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename);
+ if (Buffer == 0) {
+ cerr << "Error reading file '" + InputFilename + "'";
+ return 1;
+ } else {
+ M.reset(ParseBitcodeFile(Buffer));
+ }
+ delete Buffer;
+
+ if (M.get() == 0) {
+ cerr << argv[0] << ": bitcode didn't read correctly.\n";
+ return 1;
+ }
+
+ // Figure out which function we should extract
+ Function *F = M.get()->getFunction(ExtractFunc);
+ if (F == 0) {
+ cerr << argv[0] << ": program doesn't contain function named '"
+ << ExtractFunc << "'!\n";
+ return 1;
+ }
+
+ // In addition to deleting all other functions, we also want to spiff it
+ // up a little bit. Do this now.
+ PassManager Passes;
+ Passes.add(new TargetData(M.get())); // Use correct TargetData
+ // Either isolate the function or delete it from the Module
+ Passes.add(createFunctionExtractionPass(F, DeleteFn, Relink));
+ if (!DeleteFn)
+ Passes.add(createGlobalDCEPass()); // Delete unreachable globals
+ Passes.add(createDeadTypeEliminationPass()); // Remove dead types...
+ Passes.add(createStripDeadPrototypesPass()); // Remove dead func decls
+
+ std::ostream *Out = 0;
+
+ if (OutputFilename != "-") { // Not stdout?
+ if (!Force && std::ifstream(OutputFilename.c_str())) {
+ // If force is not specified, make sure not to overwrite a file!
+ cerr << argv[0] << ": error opening '" << OutputFilename
+ << "': file exists!\n"
+ << "Use -f command line argument to force output\n";
+ return 1;
+ }
+ std::ios::openmode io_mode = std::ios::out | std::ios::trunc |
+ std::ios::binary;
+ Out = new std::ofstream(OutputFilename.c_str(), io_mode);
+ } else { // Specified stdout
+ // FIXME: cout is not binary!
+ Out = &std::cout;
+ }
+
+ Passes.add(CreateBitcodeWriterPass(*Out));
+ Passes.run(*M.get());
+
+ if (Out != &std::cout)
+ delete Out;
+ return 0;
+}
diff --git a/tools/llvm-ld/Makefile b/tools/llvm-ld/Makefile
new file mode 100644
index 0000000..f772504
--- /dev/null
+++ b/tools/llvm-ld/Makefile
@@ -0,0 +1,16 @@
+##===- tools/llvm-ld/Makefile ------------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file was developed by the LLVM research group and is distributed under
+# the University of Illinois Open Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../..
+
+TOOLNAME = llvm-ld
+LINK_COMPONENTS = ipo scalaropts linker archive bitwriter
+REQUIRES_EH := 1
+
+include $(LEVEL)/Makefile.common
diff --git a/tools/llvm-ld/Optimize.cpp b/tools/llvm-ld/Optimize.cpp
new file mode 100644
index 0000000..308fd54
--- /dev/null
+++ b/tools/llvm-ld/Optimize.cpp
@@ -0,0 +1,216 @@
+//===- Optimize.cpp - Optimize a complete program -------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements all optimization of the linked module for llvm-ld.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Module.h"
+#include "llvm/PassManager.h"
+#include "llvm/Analysis/LoadValueNumbering.h"
+#include "llvm/Analysis/Passes.h"
+#include "llvm/Analysis/LoopPass.h"
+#include "llvm/Analysis/Verifier.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/System/DynamicLibrary.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Transforms/IPO.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Support/PassNameParser.h"
+#include "llvm/Support/PluginLoader.h"
+#include <iostream>
+using namespace llvm;
+
+// Pass Name Options as generated by the PassNameParser
+static cl::list<const PassInfo*, bool, PassNameParser>
+ OptimizationList(cl::desc("Optimizations available:"));
+
+// Optimization Enumeration
+enum OptimizationLevels {
+ OPT_FAST_COMPILE = 1,
+ OPT_SIMPLE = 2,
+ OPT_AGGRESSIVE = 3,
+ OPT_LINK_TIME = 4,
+ OPT_AGGRESSIVE_LINK_TIME = 5
+};
+
+// Optimization Options
+static cl::opt<OptimizationLevels> OptLevel(
+ cl::desc("Choose level of optimization to apply:"),
+ cl::init(OPT_FAST_COMPILE), cl::values(
+ clEnumValN(OPT_FAST_COMPILE,"O0",
+ "An alias for the -O1 option."),
+ clEnumValN(OPT_FAST_COMPILE,"O1",
+ "Optimize for linking speed, not execution speed."),
+ clEnumValN(OPT_SIMPLE,"O2",
+ "Perform only required/minimal optimizations"),
+ clEnumValN(OPT_AGGRESSIVE,"O3",
+ "An alias for the -O2 option."),
+ clEnumValN(OPT_LINK_TIME,"O4",
+ "Perform standard link time optimizations"),
+ clEnumValN(OPT_AGGRESSIVE_LINK_TIME,"O5",
+ "Perform aggressive link time optimizations"),
+ clEnumValEnd
+ )
+);
+
+static cl::opt<bool> DisableInline("disable-inlining",
+ cl::desc("Do not run the inliner pass"));
+
+static cl::opt<bool>
+DisableOptimizations("disable-opt",
+ cl::desc("Do not run any optimization passes"));
+
+static cl::opt<bool> DisableInternalize("disable-internalize",
+ cl::desc("Do not mark all symbols as internal"));
+
+static cl::opt<bool> VerifyEach("verify-each",
+ cl::desc("Verify intermediate results of all passes"));
+
+static cl::alias ExportDynamic("export-dynamic",
+ cl::aliasopt(DisableInternalize),
+ cl::desc("Alias for -disable-internalize"));
+
+static cl::opt<bool> Strip("strip-all",
+ cl::desc("Strip all symbol info from executable"));
+
+static cl::alias A0("s", cl::desc("Alias for --strip-all"),
+ cl::aliasopt(Strip));
+
+static cl::opt<bool> StripDebug("strip-debug",
+ cl::desc("Strip debugger symbol info from executable"));
+
+static cl::alias A1("S", cl::desc("Alias for --strip-debug"),
+ cl::aliasopt(StripDebug));
+
+// A utility function that adds a pass to the pass manager but will also add
+// a verifier pass after if we're supposed to verify.
+static inline void addPass(PassManager &PM, Pass *P) {
+ // Add the pass to the pass manager...
+ PM.add(P);
+
+ // If we are verifying all of the intermediate steps, add the verifier...
+ if (VerifyEach)
+ PM.add(createVerifierPass());
+}
+
+namespace llvm {
+
+/// Optimize - Perform link time optimizations. This will run the scalar
+/// optimizations, any loaded plugin-optimization modules, and then the
+/// inter-procedural optimizations if applicable.
+void Optimize(Module* M) {
+
+ // Instantiate the pass manager to organize the passes.
+ PassManager Passes;
+
+ // If we're verifying, start off with a verification pass.
+ if (VerifyEach)
+ Passes.add(createVerifierPass());
+
+ // Add an appropriate TargetData instance for this module...
+ addPass(Passes, new TargetData(M));
+
+ if (!DisableOptimizations) {
+ // Now that composite has been compiled, scan through the module, looking
+ // for a main function. If main is defined, mark all other functions
+ // internal.
+ if (!DisableInternalize)
+ addPass(Passes, createInternalizePass(true));
+
+ // Propagate constants at call sites into the functions they call. This
+ // opens opportunities for globalopt (and inlining) by substituting function
+ // pointers passed as arguments to direct uses of functions.
+ addPass(Passes, createIPSCCPPass());
+
+ // Now that we internalized some globals, see if we can hack on them!
+ addPass(Passes, createGlobalOptimizerPass());
+
+ // Linking modules together can lead to duplicated global constants, only
+ // keep one copy of each constant...
+ addPass(Passes, createConstantMergePass());
+
+ // Remove unused arguments from functions...
+ addPass(Passes, createDeadArgEliminationPass());
+
+ // Reduce the code after globalopt and ipsccp. Both can open up significant
+ // simplification opportunities, and both can propagate functions through
+ // function pointers. When this happens, we often have to resolve varargs
+ // calls, etc, so let instcombine do this.
+ addPass(Passes, createInstructionCombiningPass());
+
+ if (!DisableInline)
+ addPass(Passes, createFunctionInliningPass()); // Inline small functions
+
+ addPass(Passes, createPruneEHPass()); // Remove dead EH info
+ addPass(Passes, createGlobalOptimizerPass()); // Optimize globals again.
+ addPass(Passes, createGlobalDCEPass()); // Remove dead functions
+
+ // If we didn't decide to inline a function, check to see if we can
+ // transform it to pass arguments by value instead of by reference.
+ addPass(Passes, createArgumentPromotionPass());
+
+ // The IPO passes may leave cruft around. Clean up after them.
+ addPass(Passes, createInstructionCombiningPass());
+
+ addPass(Passes, createScalarReplAggregatesPass()); // Break up allocas
+
+ // Run a few AA driven optimizations here and now, to cleanup the code.
+ addPass(Passes, createGlobalsModRefPass()); // IP alias analysis
+
+ addPass(Passes, createLICMPass()); // Hoist loop invariants
+ addPass(Passes, createLoadValueNumberingPass()); // GVN for load instrs
+ addPass(Passes, createGCSEPass()); // Remove common subexprs
+ addPass(Passes, createFastDeadStoreEliminationPass()); // Nuke dead stores
+
+ // Cleanup and simplify the code after the scalar optimizations.
+ addPass(Passes, createInstructionCombiningPass());
+
+ // Delete basic blocks, which optimization passes may have killed...
+ addPass(Passes, createCFGSimplificationPass());
+
+ // Now that we have optimized the program, discard unreachable functions...
+ addPass(Passes, createGlobalDCEPass());
+ }
+
+ // If the -s or -S command line options were specified, strip the symbols out
+ // of the resulting program to make it smaller. -s and -S are GNU ld options
+ // that we are supporting; they alias -strip-all and -strip-debug.
+ if (Strip || StripDebug)
+ addPass(Passes, createStripSymbolsPass(StripDebug && !Strip));
+
+ // Create a new optimization pass for each one specified on the command line
+ std::auto_ptr<TargetMachine> target;
+ for (unsigned i = 0; i < OptimizationList.size(); ++i) {
+ const PassInfo *Opt = OptimizationList[i];
+ if (Opt->getNormalCtor())
+ addPass(Passes, Opt->getNormalCtor()());
+ else
+ std::cerr << "llvm-ld: cannot create pass: " << Opt->getPassName()
+ << "\n";
+ }
+
+ // The user's passes may leave cruft around. Clean up after them them but
+ // only if we haven't got DisableOptimizations set
+ if (!DisableOptimizations) {
+ addPass(Passes, createInstructionCombiningPass());
+ addPass(Passes, createCFGSimplificationPass());
+ addPass(Passes, createDeadCodeEliminationPass());
+ addPass(Passes, createGlobalDCEPass());
+ }
+
+ // Make sure everything is still good.
+ Passes.add(createVerifierPass());
+
+ // Run our queue of passes all at once now, efficiently.
+ Passes.run(*M);
+}
+
+}
diff --git a/tools/llvm-ld/llvm-ld.cpp b/tools/llvm-ld/llvm-ld.cpp
new file mode 100644
index 0000000..46788b1
--- /dev/null
+++ b/tools/llvm-ld/llvm-ld.cpp
@@ -0,0 +1,653 @@
+//===- llvm-ld.cpp - LLVM 'ld' compatible linker --------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This utility is intended to be compatible with GCC, and follows standard
+// system 'ld' conventions. As such, the default output file is ./a.out.
+// Additionally, this program outputs a shell script that is used to invoke LLI
+// to execute the program. In this manner, the generated executable (a.out for
+// example), is directly executable, whereas the bitcode file actually lives in
+// the a.out.bc file generated by this program. Also, Force is on by default.
+//
+// Note that if someone (or a script) deletes the executable program generated,
+// the .bc file will be left around. Considering that this is a temporary hack,
+// I'm not too worried about this.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/LinkAllVMCore.h"
+#include "llvm/Linker.h"
+#include "llvm/System/Program.h"
+#include "llvm/Module.h"
+#include "llvm/PassManager.h"
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetMachineRegistry.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FileUtilities.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Streams.h"
+#include "llvm/Support/SystemUtils.h"
+#include "llvm/System/Signals.h"
+#include <fstream>
+#include <memory>
+using namespace llvm;
+
+// Input/Output Options
+static cl::list<std::string> InputFilenames(cl::Positional, cl::OneOrMore,
+ cl::desc("<input bitcode files>"));
+
+static cl::opt<std::string> OutputFilename("o", cl::init("a.out"),
+ cl::desc("Override output filename"),
+ cl::value_desc("filename"));
+
+static cl::opt<bool> Verbose("v",
+ cl::desc("Print information about actions taken"));
+
+static cl::list<std::string> LibPaths("L", cl::Prefix,
+ cl::desc("Specify a library search path"),
+ cl::value_desc("directory"));
+
+static cl::list<std::string> Libraries("l", cl::Prefix,
+ cl::desc("Specify libraries to link to"),
+ cl::value_desc("library prefix"));
+
+// Options to control the linking, optimization, and code gen processes
+static cl::opt<bool> LinkAsLibrary("link-as-library",
+ cl::desc("Link the .bc files together as a library, not an executable"));
+
+static cl::alias Relink("r", cl::aliasopt(LinkAsLibrary),
+ cl::desc("Alias for -link-as-library"));
+
+static cl::opt<const TargetMachineRegistry::Entry*, false, TargetNameParser>
+ MachineArch("march", cl::desc("Architecture to generate assembly for:"));
+
+static cl::opt<bool> Native("native",
+ cl::desc("Generate a native binary instead of a shell script"));
+
+static cl::opt<bool>NativeCBE("native-cbe",
+ cl::desc("Generate a native binary with the C backend and GCC"));
+
+static cl::list<std::string> PostLinkOpts("post-link-opts",
+ cl::value_desc("path"),
+ cl::desc("Run one or more optimization programs after linking"));
+
+static cl::list<std::string> XLinker("Xlinker", cl::value_desc("option"),
+ cl::desc("Pass options to the system linker"));
+
+// Compatibility options that llvm-ld ignores but are supported for
+// compatibility with LD
+static cl::opt<std::string> CO3("soname", cl::Hidden,
+ cl::desc("Compatibility option: ignored"));
+
+static cl::opt<std::string> CO4("version-script", cl::Hidden,
+ cl::desc("Compatibility option: ignored"));
+
+static cl::opt<bool> CO5("eh-frame-hdr", cl::Hidden,
+ cl::desc("Compatibility option: ignored"));
+
+static cl::opt<std::string> CO6("h", cl::Hidden,
+ cl::desc("Compatibility option: ignored"));
+
+static cl::opt<bool> CO7("start-group", cl::Hidden,
+ cl::desc("Compatibility option: ignored"));
+
+static cl::opt<bool> CO8("end-group", cl::Hidden,
+ cl::desc("Compatibility option: ignored"));
+
+/// This is just for convenience so it doesn't have to be passed around
+/// everywhere.
+static std::string progname;
+
+/// PrintAndExit - Prints a message to standard error and exits with error code
+///
+/// Inputs:
+/// Message - The message to print to standard error.
+///
+static void PrintAndExit(const std::string &Message, int errcode = 1) {
+ cerr << progname << ": " << Message << "\n";
+ llvm_shutdown();
+ exit(errcode);
+}
+
+static void PrintCommand(const std::vector<const char*> &args) {
+ std::vector<const char*>::const_iterator I = args.begin(), E = args.end();
+ for (; I != E; ++I)
+ if (*I)
+ cout << "'" << *I << "'" << " ";
+ cout << "\n" << std::flush;
+}
+
+/// CopyEnv - This function takes an array of environment variables and makes a
+/// copy of it. This copy can then be manipulated any way the caller likes
+/// without affecting the process's real environment.
+///
+/// Inputs:
+/// envp - An array of C strings containing an environment.
+///
+/// Return value:
+/// NULL - An error occurred.
+///
+/// Otherwise, a pointer to a new array of C strings is returned. Every string
+/// in the array is a duplicate of the one in the original array (i.e. we do
+/// not copy the char *'s from one array to another).
+///
+static char ** CopyEnv(char ** const envp) {
+ // Count the number of entries in the old list;
+ unsigned entries; // The number of entries in the old environment list
+ for (entries = 0; envp[entries] != NULL; entries++)
+ /*empty*/;
+
+ // Add one more entry for the NULL pointer that ends the list.
+ ++entries;
+
+ // If there are no entries at all, just return NULL.
+ if (entries == 0)
+ return NULL;
+
+ // Allocate a new environment list.
+ char **newenv = new char* [entries];
+ if ((newenv = new char* [entries]) == NULL)
+ return NULL;
+
+ // Make a copy of the list. Don't forget the NULL that ends the list.
+ entries = 0;
+ while (envp[entries] != NULL) {
+ newenv[entries] = new char[strlen (envp[entries]) + 1];
+ strcpy (newenv[entries], envp[entries]);
+ ++entries;
+ }
+ newenv[entries] = NULL;
+
+ return newenv;
+}
+
+
+/// RemoveEnv - Remove the specified environment variable from the environment
+/// array.
+///
+/// Inputs:
+/// name - The name of the variable to remove. It cannot be NULL.
+/// envp - The array of environment variables. It cannot be NULL.
+///
+/// Notes:
+/// This is mainly done because functions to remove items from the environment
+/// are not available across all platforms. In particular, Solaris does not
+/// seem to have an unsetenv() function or a setenv() function (or they are
+/// undocumented if they do exist).
+///
+static void RemoveEnv(const char * name, char ** const envp) {
+ for (unsigned index=0; envp[index] != NULL; index++) {
+ // Find the first equals sign in the array and make it an EOS character.
+ char *p = strchr (envp[index], '=');
+ if (p == NULL)
+ continue;
+ else
+ *p = '\0';
+
+ // Compare the two strings. If they are equal, zap this string.
+ // Otherwise, restore it.
+ if (!strcmp(name, envp[index]))
+ *envp[index] = '\0';
+ else
+ *p = '=';
+ }
+
+ return;
+}
+
+/// GenerateBitcode - generates a bitcode file from the module provided
+void GenerateBitcode(Module* M, const std::string& FileName) {
+
+ if (Verbose)
+ cout << "Generating Bitcode To " << FileName << '\n';
+
+ // Create the output file.
+ std::ios::openmode io_mode = std::ios::out | std::ios::trunc |
+ std::ios::binary;
+ std::ofstream Out(FileName.c_str(), io_mode);
+ if (!Out.good())
+ PrintAndExit("error opening '" + FileName + "' for writing!");
+
+ // Ensure that the bitcode file gets removed from the disk if we get a
+ // terminating signal.
+ sys::RemoveFileOnSignal(sys::Path(FileName));
+
+ // Write it out
+ WriteBitcodeToFile(M, Out);
+
+ // Close the bitcode file.
+ Out.close();
+}
+
+/// GenerateAssembly - generates a native assembly language source file from the
+/// specified bitcode file.
+///
+/// Inputs:
+/// InputFilename - The name of the input bitcode file.
+/// OutputFilename - The name of the file to generate.
+/// llc - The pathname to use for LLC.
+/// envp - The environment to use when running LLC.
+///
+/// Return non-zero value on error.
+///
+static int GenerateAssembly(const std::string &OutputFilename,
+ const std::string &InputFilename,
+ const sys::Path &llc,
+ std::string &ErrMsg ) {
+ // Run LLC to convert the bitcode file into assembly code.
+ std::vector<const char*> args;
+ args.push_back(llc.c_str());
+ args.push_back("-f");
+ args.push_back("-o");
+ args.push_back(OutputFilename.c_str());
+ args.push_back(InputFilename.c_str());
+ args.push_back(0);
+
+ if (Verbose) {
+ cout << "Generating Assembly With: \n";
+ PrintCommand(args);
+ }
+
+ return sys::Program::ExecuteAndWait(llc, &args[0], 0, 0, 0, 0, &ErrMsg);
+}
+
+/// GenerateCFile - generates a C source file from the specified bitcode file.
+static int GenerateCFile(const std::string &OutputFile,
+ const std::string &InputFile,
+ const sys::Path &llc,
+ std::string& ErrMsg) {
+ // Run LLC to convert the bitcode file into C.
+ std::vector<const char*> args;
+ args.push_back(llc.c_str());
+ args.push_back("-march=c");
+ args.push_back("-f");
+ args.push_back("-o");
+ args.push_back(OutputFile.c_str());
+ args.push_back(InputFile.c_str());
+ args.push_back(0);
+
+ if (Verbose) {
+ cout << "Generating C Source With: \n";
+ PrintCommand(args);
+ }
+
+ return sys::Program::ExecuteAndWait(llc, &args[0], 0, 0, 0, 0, &ErrMsg);
+}
+
+/// GenerateNative - generates a native object file from the
+/// specified bitcode file.
+///
+/// Inputs:
+/// InputFilename - The name of the input bitcode file.
+/// OutputFilename - The name of the file to generate.
+/// NativeLinkItems - The native libraries, files, code with which to link
+/// LibPaths - The list of directories in which to find libraries.
+/// gcc - The pathname to use for GGC.
+/// envp - A copy of the process's current environment.
+///
+/// Outputs:
+/// None.
+///
+/// Returns non-zero value on error.
+///
+static int GenerateNative(const std::string &OutputFilename,
+ const std::string &InputFilename,
+ const Linker::ItemList &LinkItems,
+ const sys::Path &gcc, char ** const envp,
+ std::string& ErrMsg) {
+ // Remove these environment variables from the environment of the
+ // programs that we will execute. It appears that GCC sets these
+ // environment variables so that the programs it uses can configure
+ // themselves identically.
+ //
+ // However, when we invoke GCC below, we want it to use its normal
+ // configuration. Hence, we must sanitize its environment.
+ char ** clean_env = CopyEnv(envp);
+ if (clean_env == NULL)
+ return 1;
+ RemoveEnv("LIBRARY_PATH", clean_env);
+ RemoveEnv("COLLECT_GCC_OPTIONS", clean_env);
+ RemoveEnv("GCC_EXEC_PREFIX", clean_env);
+ RemoveEnv("COMPILER_PATH", clean_env);
+ RemoveEnv("COLLECT_GCC", clean_env);
+
+
+ // Run GCC to assemble and link the program into native code.
+ //
+ // Note:
+ // We can't just assemble and link the file with the system assembler
+ // and linker because we don't know where to put the _start symbol.
+ // GCC mysteriously knows how to do it.
+ std::vector<std::string> args;
+ args.push_back(gcc.c_str());
+ args.push_back("-fno-strict-aliasing");
+ args.push_back("-O3");
+ args.push_back("-o");
+ args.push_back(OutputFilename);
+ args.push_back(InputFilename);
+
+ // Add in the library paths
+ for (unsigned index = 0; index < LibPaths.size(); index++) {
+ args.push_back("-L");
+ args.push_back(LibPaths[index]);
+ }
+
+ // Add the requested options
+ for (unsigned index = 0; index < XLinker.size(); index++) {
+ args.push_back(XLinker[index]);
+ args.push_back(Libraries[index]);
+ }
+
+ // Add in the libraries to link.
+ for (unsigned index = 0; index < LinkItems.size(); index++)
+ if (LinkItems[index].first != "crtend") {
+ if (LinkItems[index].second)
+ args.push_back("-l" + LinkItems[index].first);
+ else
+ args.push_back(LinkItems[index].first);
+ }
+
+
+ // Now that "args" owns all the std::strings for the arguments, call the c_str
+ // method to get the underlying string array. We do this game so that the
+ // std::string array is guaranteed to outlive the const char* array.
+ std::vector<const char *> Args;
+ for (unsigned i = 0, e = args.size(); i != e; ++i)
+ Args.push_back(args[i].c_str());
+ Args.push_back(0);
+
+ if (Verbose) {
+ cout << "Generating Native Executable With:\n";
+ PrintCommand(Args);
+ }
+
+ // Run the compiler to assembly and link together the program.
+ int R = sys::Program::ExecuteAndWait(
+ gcc, &Args[0], (const char**)clean_env, 0, 0, 0, &ErrMsg);
+ delete [] clean_env;
+ return R;
+}
+
+/// EmitShellScript - Output the wrapper file that invokes the JIT on the LLVM
+/// bitcode file for the program.
+static void EmitShellScript(char **argv) {
+ if (Verbose)
+ cout << "Emitting Shell Script\n";
+#if defined(_WIN32) || defined(__CYGWIN__)
+ // Windows doesn't support #!/bin/sh style shell scripts in .exe files. To
+ // support windows systems, we copy the llvm-stub.exe executable from the
+ // build tree to the destination file.
+ std::string ErrMsg;
+ sys::Path llvmstub = FindExecutable("llvm-stub.exe", argv[0]);
+ if (llvmstub.isEmpty())
+ PrintAndExit("Could not find llvm-stub.exe executable!");
+
+ if (0 != sys::CopyFile(sys::Path(OutputFilename), llvmstub, &ErrMsg))
+ PrintAndExit(ErrMsg);
+
+ return;
+#endif
+
+ // Output the script to start the program...
+ std::ofstream Out2(OutputFilename.c_str());
+ if (!Out2.good())
+ PrintAndExit("error opening '" + OutputFilename + "' for writing!");
+
+ Out2 << "#!/bin/sh\n";
+ // Allow user to setenv LLVMINTERP if lli is not in their PATH.
+ Out2 << "lli=${LLVMINTERP-lli}\n";
+ Out2 << "exec $lli \\\n";
+ // gcc accepts -l<lib> and implicitly searches /lib and /usr/lib.
+ LibPaths.push_back("/lib");
+ LibPaths.push_back("/usr/lib");
+ LibPaths.push_back("/usr/X11R6/lib");
+ // We don't need to link in libc! In fact, /usr/lib/libc.so may not be a
+ // shared object at all! See RH 8: plain text.
+ std::vector<std::string>::iterator libc =
+ std::find(Libraries.begin(), Libraries.end(), "c");
+ if (libc != Libraries.end()) Libraries.erase(libc);
+ // List all the shared object (native) libraries this executable will need
+ // on the command line, so that we don't have to do this manually!
+ for (std::vector<std::string>::iterator i = Libraries.begin(),
+ e = Libraries.end(); i != e; ++i) {
+ sys::Path FullLibraryPath = sys::Path::FindLibrary(*i);
+ if (!FullLibraryPath.isEmpty() && FullLibraryPath.isDynamicLibrary())
+ Out2 << " -load=" << FullLibraryPath.toString() << " \\\n";
+ }
+ Out2 << " $0.bc ${1+\"$@\"}\n";
+ Out2.close();
+}
+
+// BuildLinkItems -- This function generates a LinkItemList for the LinkItems
+// linker function by combining the Files and Libraries in the order they were
+// declared on the command line.
+static void BuildLinkItems(
+ Linker::ItemList& Items,
+ const cl::list<std::string>& Files,
+ const cl::list<std::string>& Libraries) {
+
+ // Build the list of linkage items for LinkItems.
+
+ cl::list<std::string>::const_iterator fileIt = Files.begin();
+ cl::list<std::string>::const_iterator libIt = Libraries.begin();
+
+ int libPos = -1, filePos = -1;
+ while ( libIt != Libraries.end() || fileIt != Files.end() ) {
+ if (libIt != Libraries.end())
+ libPos = Libraries.getPosition(libIt - Libraries.begin());
+ else
+ libPos = -1;
+ if (fileIt != Files.end())
+ filePos = Files.getPosition(fileIt - Files.begin());
+ else
+ filePos = -1;
+
+ if (filePos != -1 && (libPos == -1 || filePos < libPos)) {
+ // Add a source file
+ Items.push_back(std::make_pair(*fileIt++, false));
+ } else if (libPos != -1 && (filePos == -1 || libPos < filePos)) {
+ // Add a library
+ Items.push_back(std::make_pair(*libIt++, true));
+ }
+ }
+}
+
+// Rightly this should go in a header file but it just seems such a waste.
+namespace llvm {
+extern void Optimize(Module*);
+}
+
+int main(int argc, char **argv, char **envp) {
+ llvm_shutdown_obj X; // Call llvm_shutdown() on exit.
+ try {
+ // Initial global variable above for convenience printing of program name.
+ progname = sys::Path(argv[0]).getBasename();
+
+ // Parse the command line options
+ cl::ParseCommandLineOptions(argc, argv, " llvm linker\n");
+ sys::PrintStackTraceOnErrorSignal();
+
+ // Construct a Linker (now that Verbose is set)
+ Linker TheLinker(progname, OutputFilename, Verbose);
+
+ // Keep track of the native link items (versus the bitcode items)
+ Linker::ItemList NativeLinkItems;
+
+ // Add library paths to the linker
+ TheLinker.addPaths(LibPaths);
+ TheLinker.addSystemPaths();
+
+ // Remove any consecutive duplicates of the same library...
+ Libraries.erase(std::unique(Libraries.begin(), Libraries.end()),
+ Libraries.end());
+
+ if (LinkAsLibrary) {
+ std::vector<sys::Path> Files;
+ for (unsigned i = 0; i < InputFilenames.size(); ++i )
+ Files.push_back(sys::Path(InputFilenames[i]));
+ if (TheLinker.LinkInFiles(Files))
+ return 1; // Error already printed
+
+ // The libraries aren't linked in but are noted as "dependent" in the
+ // module.
+ for (cl::list<std::string>::const_iterator I = Libraries.begin(),
+ E = Libraries.end(); I != E ; ++I) {
+ TheLinker.getModule()->addLibrary(*I);
+ }
+ } else {
+ // Build a list of the items from our command line
+ Linker::ItemList Items;
+ BuildLinkItems(Items, InputFilenames, Libraries);
+
+ // Link all the items together
+ if (TheLinker.LinkInItems(Items, NativeLinkItems) )
+ return 1; // Error already printed
+ }
+
+ std::auto_ptr<Module> Composite(TheLinker.releaseModule());
+
+ // Optimize the module
+ Optimize(Composite.get());
+
+ // Generate the bitcode for the optimized module.
+ std::string RealBitcodeOutput = OutputFilename;
+ if (!LinkAsLibrary) RealBitcodeOutput += ".bc";
+ GenerateBitcode(Composite.get(), RealBitcodeOutput);
+
+ // If we are not linking a library, generate either a native executable
+ // or a JIT shell script, depending upon what the user wants.
+ if (!LinkAsLibrary) {
+ // If the user wants to run a post-link optimization, run it now.
+ if (!PostLinkOpts.empty()) {
+ std::vector<std::string> opts = PostLinkOpts;
+ for (std::vector<std::string>::iterator I = opts.begin(),
+ E = opts.end(); I != E; ++I) {
+ sys::Path prog(*I);
+ if (!prog.canExecute()) {
+ prog = sys::Program::FindProgramByName(*I);
+ if (prog.isEmpty())
+ PrintAndExit(std::string("Optimization program '") + *I +
+ "' is not found or not executable.");
+ }
+ // Get the program arguments
+ sys::Path tmp_output("opt_result");
+ std::string ErrMsg;
+ if (tmp_output.createTemporaryFileOnDisk(true, &ErrMsg))
+ PrintAndExit(ErrMsg);
+
+ const char* args[4];
+ args[0] = I->c_str();
+ args[1] = RealBitcodeOutput.c_str();
+ args[2] = tmp_output.c_str();
+ args[3] = 0;
+ if (0 == sys::Program::ExecuteAndWait(prog, args, 0,0,0,0, &ErrMsg)) {
+ if (tmp_output.isBitcodeFile() || tmp_output.isBitcodeFile()) {
+ sys::Path target(RealBitcodeOutput);
+ target.eraseFromDisk();
+ if (tmp_output.renamePathOnDisk(target, &ErrMsg))
+ PrintAndExit(ErrMsg, 2);
+ } else
+ PrintAndExit("Post-link optimization output is not bitcode");
+ } else {
+ PrintAndExit(ErrMsg);
+ }
+ }
+ }
+
+ // If the user wants to generate a native executable, compile it from the
+ // bitcode file.
+ //
+ // Otherwise, create a script that will run the bitcode through the JIT.
+ if (Native) {
+ // Name of the Assembly Language output file
+ sys::Path AssemblyFile ( OutputFilename);
+ AssemblyFile.appendSuffix("s");
+
+ // Mark the output files for removal if we get an interrupt.
+ sys::RemoveFileOnSignal(AssemblyFile);
+ sys::RemoveFileOnSignal(sys::Path(OutputFilename));
+
+ // Determine the locations of the llc and gcc programs.
+ sys::Path llc = FindExecutable("llc", argv[0]);
+ if (llc.isEmpty())
+ PrintAndExit("Failed to find llc");
+
+ sys::Path gcc = FindExecutable("gcc", argv[0]);
+ if (gcc.isEmpty())
+ PrintAndExit("Failed to find gcc");
+
+ // Generate an assembly language file for the bitcode.
+ std::string ErrMsg;
+ if (0 != GenerateAssembly(AssemblyFile.toString(), RealBitcodeOutput,
+ llc, ErrMsg))
+ PrintAndExit(ErrMsg);
+
+ if (0 != GenerateNative(OutputFilename, AssemblyFile.toString(),
+ NativeLinkItems, gcc, envp, ErrMsg))
+ PrintAndExit(ErrMsg);
+
+ // Remove the assembly language file.
+ AssemblyFile.eraseFromDisk();
+ } else if (NativeCBE) {
+ sys::Path CFile (OutputFilename);
+ CFile.appendSuffix("cbe.c");
+
+ // Mark the output files for removal if we get an interrupt.
+ sys::RemoveFileOnSignal(CFile);
+ sys::RemoveFileOnSignal(sys::Path(OutputFilename));
+
+ // Determine the locations of the llc and gcc programs.
+ sys::Path llc = FindExecutable("llc", argv[0]);
+ if (llc.isEmpty())
+ PrintAndExit("Failed to find llc");
+
+ sys::Path gcc = FindExecutable("gcc", argv[0]);
+ if (gcc.isEmpty())
+ PrintAndExit("Failed to find gcc");
+
+ // Generate an assembly language file for the bitcode.
+ std::string ErrMsg;
+ if (0 != GenerateCFile(
+ CFile.toString(), RealBitcodeOutput, llc, ErrMsg))
+ PrintAndExit(ErrMsg);
+
+ if (0 != GenerateNative(OutputFilename, CFile.toString(),
+ NativeLinkItems, gcc, envp, ErrMsg))
+ PrintAndExit(ErrMsg);
+
+ // Remove the assembly language file.
+ CFile.eraseFromDisk();
+
+ } else {
+ EmitShellScript(argv);
+ }
+
+ // Make the script executable...
+ std::string ErrMsg;
+ if (sys::Path(OutputFilename).makeExecutableOnDisk(&ErrMsg))
+ PrintAndExit(ErrMsg);
+
+ // Make the bitcode file readable and directly executable in LLEE as well
+ if (sys::Path(RealBitcodeOutput).makeExecutableOnDisk(&ErrMsg))
+ PrintAndExit(ErrMsg);
+
+ if (sys::Path(RealBitcodeOutput).makeReadableOnDisk(&ErrMsg))
+ PrintAndExit(ErrMsg);
+ }
+ } catch (const std::string& msg) {
+ PrintAndExit(msg,2);
+ } catch (...) {
+ PrintAndExit("Unexpected unknown exception occurred.", 2);
+ }
+
+ // Graceful exit
+ return 0;
+}
diff --git a/tools/llvm-link/Makefile b/tools/llvm-link/Makefile
new file mode 100644
index 0000000..1985c44
--- /dev/null
+++ b/tools/llvm-link/Makefile
@@ -0,0 +1,14 @@
+##===- tools/llvm-link/Makefile ----------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file was developed by the LLVM research group and is distributed under
+# the University of Illinois Open Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+LEVEL = ../..
+
+TOOLNAME = llvm-link
+LINK_COMPONENTS = linker bitreader bitwriter
+
+include $(LEVEL)/Makefile.common
diff --git a/tools/llvm-link/llvm-link.cpp b/tools/llvm-link/llvm-link.cpp
new file mode 100644
index 0000000..5db13aa
--- /dev/null
+++ b/tools/llvm-link/llvm-link.cpp
@@ -0,0 +1,150 @@
+//===- llvm-link.cpp - Low-level LLVM linker ------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This utility may be invoked in the following manner:
+// llvm-link a.bc b.bc c.bc -o x.bc
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Linker.h"
+#include "llvm/Module.h"
+#include "llvm/Analysis/Verifier.h"
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/System/Signals.h"
+#include "llvm/System/Path.h"
+#include <fstream>
+#include <iostream>
+#include <memory>
+using namespace llvm;
+
+static cl::list<std::string>
+InputFilenames(cl::Positional, cl::OneOrMore,
+ cl::desc("<input bitcode files>"));
+
+static cl::opt<std::string>
+OutputFilename("o", cl::desc("Override output filename"), cl::init("-"),
+ cl::value_desc("filename"));
+
+static cl::opt<bool> Force("f", cl::desc("Overwrite output files"));
+
+static cl::opt<bool>
+Verbose("v", cl::desc("Print information about actions taken"));
+
+static cl::opt<bool>
+DumpAsm("d", cl::desc("Print assembly as linked"), cl::Hidden);
+
+// LoadFile - Read the specified bitcode file in and return it. This routine
+// searches the link path for the specified file to try to find it...
+//
+static inline std::auto_ptr<Module> LoadFile(const std::string &FN) {
+ sys::Path Filename;
+ if (!Filename.set(FN)) {
+ cerr << "Invalid file name: '" << FN << "'\n";
+ return std::auto_ptr<Module>();
+ }
+
+ std::string ErrorMessage;
+ if (Filename.exists()) {
+ if (Verbose) cerr << "Loading '" << Filename.c_str() << "'\n";
+ Module* Result = 0;
+
+ const std::string &FNStr = Filename.toString();
+ if (MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(FNStr,
+ &ErrorMessage)) {
+ Result = ParseBitcodeFile(Buffer, &ErrorMessage);
+ delete Buffer;
+ }
+ if (Result) return std::auto_ptr<Module>(Result); // Load successful!
+
+ if (Verbose) {
+ cerr << "Error opening bitcode file: '" << Filename.c_str() << "'";
+ if (ErrorMessage.size()) cerr << ": " << ErrorMessage;
+ cerr << "\n";
+ }
+ } else {
+ cerr << "Bitcode file: '" << Filename.c_str() << "' does not exist.\n";
+ }
+
+ return std::auto_ptr<Module>();
+}
+
+int main(int argc, char **argv) {
+ llvm_shutdown_obj X; // Call llvm_shutdown() on exit.
+ cl::ParseCommandLineOptions(argc, argv, " llvm linker\n");
+ sys::PrintStackTraceOnErrorSignal();
+ assert(InputFilenames.size() > 0 && "OneOrMore is not working");
+
+ unsigned BaseArg = 0;
+ std::string ErrorMessage;
+
+ std::auto_ptr<Module> Composite(LoadFile(InputFilenames[BaseArg]));
+ if (Composite.get() == 0) {
+ cerr << argv[0] << ": error loading file '"
+ << InputFilenames[BaseArg] << "'\n";
+ return 1;
+ }
+
+ for (unsigned i = BaseArg+1; i < InputFilenames.size(); ++i) {
+ std::auto_ptr<Module> M(LoadFile(InputFilenames[i]));
+ if (M.get() == 0) {
+ cerr << argv[0] << ": error loading file '" <<InputFilenames[i]<< "'\n";
+ return 1;
+ }
+
+ if (Verbose) cerr << "Linking in '" << InputFilenames[i] << "'\n";
+
+ if (Linker::LinkModules(Composite.get(), M.get(), &ErrorMessage)) {
+ cerr << argv[0] << ": link error in '" << InputFilenames[i]
+ << "': " << ErrorMessage << "\n";
+ return 1;
+ }
+ }
+
+ // TODO: Iterate over the -l list and link in any modules containing
+ // global symbols that have not been resolved so far.
+
+ if (DumpAsm) cerr << "Here's the assembly:\n" << *Composite.get();
+
+ // FIXME: cout is not binary!
+ std::ostream *Out = &std::cout; // Default to printing to stdout...
+ if (OutputFilename != "-") {
+ if (!Force && std::ifstream(OutputFilename.c_str())) {
+ // If force is not specified, make sure not to overwrite a file!
+ cerr << argv[0] << ": error opening '" << OutputFilename
+ << "': file exists!\n"
+ << "Use -f command line argument to force output\n";
+ return 1;
+ }
+ std::ios::openmode io_mode = std::ios::out | std::ios::trunc |
+ std::ios::binary;
+ Out = new std::ofstream(OutputFilename.c_str(), io_mode);
+ if (!Out->good()) {
+ cerr << argv[0] << ": error opening '" << OutputFilename << "'!\n";
+ return 1;
+ }
+
+ // Make sure that the Out file gets unlinked from the disk if we get a
+ // SIGINT
+ sys::RemoveFileOnSignal(sys::Path(OutputFilename));
+ }
+
+ if (verifyModule(*Composite.get())) {
+ cerr << argv[0] << ": linked module is broken!\n";
+ return 1;
+ }
+
+ if (Verbose) cerr << "Writing bitcode...\n";
+ WriteBitcodeToFile(Composite.get(), *Out);
+
+ if (Out != &std::cout) delete Out;
+ return 0;
+}
diff --git a/tools/llvm-nm/Makefile b/tools/llvm-nm/Makefile
new file mode 100644
index 0000000..4af8917
--- /dev/null
+++ b/tools/llvm-nm/Makefile
@@ -0,0 +1,14 @@
+##===- tools/llvm-nm/Makefile ------------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file was developed by the LLVM research group and is distributed under
+# the University of Illinois Open Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+LEVEL = ../..
+
+TOOLNAME = llvm-nm
+LINK_COMPONENTS = archive bitreader
+
+include $(LEVEL)/Makefile.common
diff --git a/tools/llvm-nm/llvm-nm.cpp b/tools/llvm-nm/llvm-nm.cpp
new file mode 100644
index 0000000..bf98653
--- /dev/null
+++ b/tools/llvm-nm/llvm-nm.cpp
@@ -0,0 +1,184 @@
+//===-- llvm-nm.cpp - Symbol table dumping utility for llvm ---------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This program is a utility that works like traditional Unix "nm",
+// that is, it prints out the names of symbols in a bitcode file,
+// along with some information about each symbol.
+//
+// This "nm" does not print symbols' addresses. It supports many of
+// the features of GNU "nm", including its different output formats.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Module.h"
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/Bitcode/Archive.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/System/Signals.h"
+#include <algorithm>
+#include <cctype>
+#include <cerrno>
+#include <cstring>
+#include <iostream>
+using namespace llvm;
+
+namespace {
+ enum OutputFormatTy { bsd, sysv, posix };
+ cl::opt<OutputFormatTy>
+ OutputFormat("format",
+ cl::desc("Specify output format"),
+ cl::values(clEnumVal(bsd, "BSD format"),
+ clEnumVal(sysv, "System V format"),
+ clEnumVal(posix, "POSIX.2 format"),
+ clEnumValEnd), cl::init(bsd));
+ cl::alias OutputFormat2("f", cl::desc("Alias for --format"),
+ cl::aliasopt(OutputFormat));
+
+ cl::list<std::string>
+ InputFilenames(cl::Positional, cl::desc("<input bitcode files>"),
+ cl::ZeroOrMore);
+
+ cl::opt<bool> UndefinedOnly("undefined-only",
+ cl::desc("Show only undefined symbols"));
+ cl::alias UndefinedOnly2("u", cl::desc("Alias for --undefined-only"),
+ cl::aliasopt(UndefinedOnly));
+
+ cl::opt<bool> DefinedOnly("defined-only",
+ cl::desc("Show only defined symbols"));
+
+ cl::opt<bool> ExternalOnly("extern-only",
+ cl::desc("Show only external symbols"));
+ cl::alias ExternalOnly2("g", cl::desc("Alias for --extern-only"),
+ cl::aliasopt(ExternalOnly));
+
+ cl::opt<bool> BSDFormat("B", cl::desc("Alias for --format=bsd"));
+ cl::opt<bool> POSIXFormat("P", cl::desc("Alias for --format=posix"));
+
+ bool MultipleFiles = false;
+
+ std::string ToolName;
+}
+
+static char TypeCharForSymbol(GlobalValue &GV) {
+ if (GV.isDeclaration()) return 'U';
+ if (GV.hasLinkOnceLinkage()) return 'C';
+ if (GV.hasWeakLinkage()) return 'W';
+ if (isa<Function>(GV) && GV.hasInternalLinkage()) return 't';
+ if (isa<Function>(GV)) return 'T';
+ if (isa<GlobalVariable>(GV) && GV.hasInternalLinkage()) return 'd';
+ if (isa<GlobalVariable>(GV)) return 'D';
+ if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(&GV)) {
+ const GlobalValue *AliasedGV = GA->getAliasedGlobal();
+ if (isa<Function>(AliasedGV)) return 'T';
+ if (isa<GlobalVariable>(AliasedGV)) return 'D';
+ }
+ return '?';
+}
+
+static void DumpSymbolNameForGlobalValue(GlobalValue &GV) {
+ const std::string SymbolAddrStr = " "; // Not used yet...
+ char TypeChar = TypeCharForSymbol (GV);
+ if ((TypeChar != 'U') && UndefinedOnly)
+ return;
+ if ((TypeChar == 'U') && DefinedOnly)
+ return;
+ if (GV.hasInternalLinkage () && ExternalOnly)
+ return;
+ if (OutputFormat == posix) {
+ std::cout << GV.getName () << " " << TypeCharForSymbol (GV) << " "
+ << SymbolAddrStr << "\n";
+ } else if (OutputFormat == bsd) {
+ std::cout << SymbolAddrStr << " " << TypeCharForSymbol (GV) << " "
+ << GV.getName () << "\n";
+ } else if (OutputFormat == sysv) {
+ std::string PaddedName (GV.getName ());
+ while (PaddedName.length () < 20)
+ PaddedName += " ";
+ std::cout << PaddedName << "|" << SymbolAddrStr << "| "
+ << TypeCharForSymbol (GV)
+ << " | | | |\n";
+ }
+}
+
+static void DumpSymbolNamesFromModule(Module *M) {
+ const std::string &Filename = M->getModuleIdentifier ();
+ if (OutputFormat == posix && MultipleFiles) {
+ std::cout << Filename << ":\n";
+ } else if (OutputFormat == bsd && MultipleFiles) {
+ std::cout << "\n" << Filename << ":\n";
+ } else if (OutputFormat == sysv) {
+ std::cout << "\n\nSymbols from " << Filename << ":\n\n"
+ << "Name Value Class Type"
+ << " Size Line Section\n";
+ }
+ std::for_each (M->begin (), M->end (), DumpSymbolNameForGlobalValue);
+ std::for_each (M->global_begin (), M->global_end (),
+ DumpSymbolNameForGlobalValue);
+ std::for_each (M->alias_begin (), M->alias_end (),
+ DumpSymbolNameForGlobalValue);
+}
+
+static void DumpSymbolNamesFromFile(std::string &Filename) {
+ std::string ErrorMessage;
+ sys::Path aPath(Filename);
+ // Note: Currently we do not support reading an archive from stdin.
+ if (Filename == "-" || aPath.isBitcodeFile()) {
+ std::auto_ptr<MemoryBuffer> Buffer(
+ MemoryBuffer::getFileOrSTDIN(Filename, &ErrorMessage));
+ Module *Result = 0;
+ if (Buffer.get())
+ Result = ParseBitcodeFile(Buffer.get(), &ErrorMessage);
+
+ if (Result)
+ DumpSymbolNamesFromModule(Result);
+ else {
+ std::cerr << ToolName << ": " << Filename << ": " << ErrorMessage << "\n";
+ return;
+ }
+
+ } else if (aPath.isArchive()) {
+ std::string ErrMsg;
+ Archive* archive = Archive::OpenAndLoad(sys::Path(Filename), &ErrorMessage);
+ if (!archive)
+ std::cerr << ToolName << ": " << Filename << ": " << ErrorMessage << "\n";
+ std::vector<Module *> Modules;
+ if (archive->getAllModules(Modules, &ErrorMessage)) {
+ std::cerr << ToolName << ": " << Filename << ": " << ErrorMessage << "\n";
+ return;
+ }
+ MultipleFiles = true;
+ std::for_each (Modules.begin(), Modules.end(), DumpSymbolNamesFromModule);
+ } else {
+ std::cerr << ToolName << ": " << Filename << ": "
+ << "unrecognizable file type\n";
+ return;
+ }
+}
+
+int main(int argc, char **argv) {
+ llvm_shutdown_obj X; // Call llvm_shutdown() on exit.
+ cl::ParseCommandLineOptions(argc, argv, " llvm symbol table dumper\n");
+ sys::PrintStackTraceOnErrorSignal();
+
+ ToolName = argv[0];
+ if (BSDFormat) OutputFormat = bsd;
+ if (POSIXFormat) OutputFormat = posix;
+
+ switch (InputFilenames.size()) {
+ case 0: InputFilenames.push_back("-");
+ case 1: break;
+ default: MultipleFiles = true;
+ }
+
+ std::for_each(InputFilenames.begin(), InputFilenames.end(),
+ DumpSymbolNamesFromFile);
+ return 0;
+}
diff --git a/tools/llvm-prof/Makefile b/tools/llvm-prof/Makefile
new file mode 100644
index 0000000..505576b
--- /dev/null
+++ b/tools/llvm-prof/Makefile
@@ -0,0 +1,15 @@
+##===- tools/llvm-prof/Makefile ----------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file was developed by the LLVM research group and is distributed under
+# the University of Illinois Open Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+LEVEL = ../..
+
+TOOLNAME = llvm-prof
+LINK_COMPONENTS = bitreader analysis
+REQUIRES_EH := 1
+
+include $(LEVEL)/Makefile.common
diff --git a/tools/llvm-prof/llvm-prof.cpp b/tools/llvm-prof/llvm-prof.cpp
new file mode 100644
index 0000000..dcb9d1f
--- /dev/null
+++ b/tools/llvm-prof/llvm-prof.cpp
@@ -0,0 +1,251 @@
+//===- llvm-prof.cpp - Read in and process llvmprof.out data files --------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This tools is meant for use with the various LLVM profiling instrumentation
+// passes. It reads in the data file produced by executing an instrumented
+// program, and outputs a nice report.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/InstrTypes.h"
+#include "llvm/Module.h"
+#include "llvm/Assembly/AsmAnnotationWriter.h"
+#include "llvm/Analysis/ProfileInfoLoader.h"
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/System/Signals.h"
+#include <algorithm>
+#include <iostream>
+#include <iomanip>
+#include <map>
+#include <set>
+
+using namespace llvm;
+
+namespace {
+ cl::opt<std::string>
+ BitcodeFile(cl::Positional, cl::desc("<program bitcode file>"),
+ cl::Required);
+
+ cl::opt<std::string>
+ ProfileDataFile(cl::Positional, cl::desc("<llvmprof.out file>"),
+ cl::Optional, cl::init("llvmprof.out"));
+
+ cl::opt<bool>
+ PrintAnnotatedLLVM("annotated-llvm",
+ cl::desc("Print LLVM code with frequency annotations"));
+ cl::alias PrintAnnotated2("A", cl::desc("Alias for --annotated-llvm"),
+ cl::aliasopt(PrintAnnotatedLLVM));
+ cl::opt<bool>
+ PrintAllCode("print-all-code",
+ cl::desc("Print annotated code for the entire program"));
+}
+
+// PairSecondSort - A sorting predicate to sort by the second element of a pair.
+template<class T>
+struct PairSecondSortReverse
+ : public std::binary_function<std::pair<T, unsigned>,
+ std::pair<T, unsigned>, bool> {
+ bool operator()(const std::pair<T, unsigned> &LHS,
+ const std::pair<T, unsigned> &RHS) const {
+ return LHS.second > RHS.second;
+ }
+};
+
+namespace {
+ class ProfileAnnotator : public AssemblyAnnotationWriter {
+ std::map<const Function *, unsigned> &FuncFreqs;
+ std::map<const BasicBlock*, unsigned> &BlockFreqs;
+ std::map<ProfileInfoLoader::Edge, unsigned> &EdgeFreqs;
+ public:
+ ProfileAnnotator(std::map<const Function *, unsigned> &FF,
+ std::map<const BasicBlock*, unsigned> &BF,
+ std::map<ProfileInfoLoader::Edge, unsigned> &EF)
+ : FuncFreqs(FF), BlockFreqs(BF), EdgeFreqs(EF) {}
+
+ virtual void emitFunctionAnnot(const Function *F, std::ostream &OS) {
+ OS << ";;; %" << F->getName() << " called " << FuncFreqs[F]
+ << " times.\n;;;\n";
+ }
+ virtual void emitBasicBlockStartAnnot(const BasicBlock *BB,
+ std::ostream &OS) {
+ if (BlockFreqs.empty()) return;
+ if (unsigned Count = BlockFreqs[BB])
+ OS << "\t;;; Basic block executed " << Count << " times.\n";
+ else
+ OS << "\t;;; Never executed!\n";
+ }
+
+ virtual void emitBasicBlockEndAnnot(const BasicBlock *BB, std::ostream &OS){
+ if (EdgeFreqs.empty()) return;
+
+ // Figure out how many times each successor executed.
+ std::vector<std::pair<const BasicBlock*, unsigned> > SuccCounts;
+ const TerminatorInst *TI = BB->getTerminator();
+
+ std::map<ProfileInfoLoader::Edge, unsigned>::iterator I =
+ EdgeFreqs.lower_bound(std::make_pair(const_cast<BasicBlock*>(BB), 0U));
+ for (; I != EdgeFreqs.end() && I->first.first == BB; ++I)
+ if (I->second)
+ SuccCounts.push_back(std::make_pair(TI->getSuccessor(I->first.second),
+ I->second));
+ if (!SuccCounts.empty()) {
+ OS << "\t;;; Out-edge counts:";
+ for (unsigned i = 0, e = SuccCounts.size(); i != e; ++i)
+ OS << " [" << SuccCounts[i].second << " -> "
+ << SuccCounts[i].first->getName() << "]";
+ OS << "\n";
+ }
+ }
+ };
+}
+
+
+int main(int argc, char **argv) {
+ llvm_shutdown_obj X; // Call llvm_shutdown() on exit.
+ try {
+ cl::ParseCommandLineOptions(argc, argv, " llvm profile dump decoder\n");
+ sys::PrintStackTraceOnErrorSignal();
+
+ // Read in the bitcode file...
+ std::string ErrorMessage;
+ Module *M = 0;
+ if (MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(BitcodeFile,
+ &ErrorMessage)) {
+ M = ParseBitcodeFile(Buffer, &ErrorMessage);
+ delete Buffer;
+ }
+ if (M == 0) {
+ std::cerr << argv[0] << ": " << BitcodeFile << ": "
+ << ErrorMessage << "\n";
+ return 1;
+ }
+
+ // Read the profiling information
+ ProfileInfoLoader PI(argv[0], ProfileDataFile, *M);
+
+ std::map<const Function *, unsigned> FuncFreqs;
+ std::map<const BasicBlock*, unsigned> BlockFreqs;
+ std::map<ProfileInfoLoader::Edge, unsigned> EdgeFreqs;
+
+ // Output a report. Eventually, there will be multiple reports selectable on
+ // the command line, for now, just keep things simple.
+
+ // Emit the most frequent function table...
+ std::vector<std::pair<Function*, unsigned> > FunctionCounts;
+ PI.getFunctionCounts(FunctionCounts);
+ FuncFreqs.insert(FunctionCounts.begin(), FunctionCounts.end());
+
+ // Sort by the frequency, backwards.
+ sort(FunctionCounts.begin(), FunctionCounts.end(),
+ PairSecondSortReverse<Function*>());
+
+ uint64_t TotalExecutions = 0;
+ for (unsigned i = 0, e = FunctionCounts.size(); i != e; ++i)
+ TotalExecutions += FunctionCounts[i].second;
+
+ std::cout << "===" << std::string(73, '-') << "===\n"
+ << "LLVM profiling output for execution";
+ if (PI.getNumExecutions() != 1) std::cout << "s";
+ std::cout << ":\n";
+
+ for (unsigned i = 0, e = PI.getNumExecutions(); i != e; ++i) {
+ std::cout << " ";
+ if (e != 1) std::cout << i+1 << ". ";
+ std::cout << PI.getExecution(i) << "\n";
+ }
+
+ std::cout << "\n===" << std::string(73, '-') << "===\n";
+ std::cout << "Function execution frequencies:\n\n";
+
+ // Print out the function frequencies...
+ std::cout << " ## Frequency\n";
+ for (unsigned i = 0, e = FunctionCounts.size(); i != e; ++i) {
+ if (FunctionCounts[i].second == 0) {
+ std::cout << "\n NOTE: " << e-i << " function" <<
+ (e-i-1 ? "s were" : " was") << " never executed!\n";
+ break;
+ }
+
+ std::cout << std::setw(3) << i+1 << ". "
+ << std::setw(5) << FunctionCounts[i].second << "/"
+ << TotalExecutions << " "
+ << FunctionCounts[i].first->getName().c_str() << "\n";
+ }
+
+ std::set<Function*> FunctionsToPrint;
+
+ // If we have block count information, print out the LLVM module with
+ // frequency annotations.
+ if (PI.hasAccurateBlockCounts()) {
+ std::vector<std::pair<BasicBlock*, unsigned> > Counts;
+ PI.getBlockCounts(Counts);
+
+ TotalExecutions = 0;
+ for (unsigned i = 0, e = Counts.size(); i != e; ++i)
+ TotalExecutions += Counts[i].second;
+
+ // Sort by the frequency, backwards.
+ sort(Counts.begin(), Counts.end(),
+ PairSecondSortReverse<BasicBlock*>());
+
+ std::cout << "\n===" << std::string(73, '-') << "===\n";
+ std::cout << "Top 20 most frequently executed basic blocks:\n\n";
+
+ // Print out the function frequencies...
+ std::cout <<" ## %% \tFrequency\n";
+ unsigned BlocksToPrint = Counts.size();
+ if (BlocksToPrint > 20) BlocksToPrint = 20;
+ for (unsigned i = 0; i != BlocksToPrint; ++i) {
+ if (Counts[i].second == 0) break;
+ Function *F = Counts[i].first->getParent();
+ std::cout << std::setw(3) << i+1 << ". "
+ << std::setw(5) << std::setprecision(2)
+ << Counts[i].second/(double)TotalExecutions*100 << "% "
+ << std::setw(5) << Counts[i].second << "/"
+ << TotalExecutions << "\t"
+ << F->getName().c_str() << "() - "
+ << Counts[i].first->getName().c_str() << "\n";
+ FunctionsToPrint.insert(F);
+ }
+
+ BlockFreqs.insert(Counts.begin(), Counts.end());
+ }
+
+ if (PI.hasAccurateEdgeCounts()) {
+ std::vector<std::pair<ProfileInfoLoader::Edge, unsigned> > Counts;
+ PI.getEdgeCounts(Counts);
+ EdgeFreqs.insert(Counts.begin(), Counts.end());
+ }
+
+ if (PrintAnnotatedLLVM || PrintAllCode) {
+ std::cout << "\n===" << std::string(73, '-') << "===\n";
+ std::cout << "Annotated LLVM code for the module:\n\n";
+
+ ProfileAnnotator PA(FuncFreqs, BlockFreqs, EdgeFreqs);
+
+ if (FunctionsToPrint.empty() || PrintAllCode)
+ M->print(std::cout, &PA);
+ else
+ // Print just a subset of the functions...
+ for (std::set<Function*>::iterator I = FunctionsToPrint.begin(),
+ E = FunctionsToPrint.end(); I != E; ++I)
+ (*I)->print(std::cout, &PA);
+ }
+
+ 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;
+}
diff --git a/tools/llvm-ranlib/Makefile b/tools/llvm-ranlib/Makefile
new file mode 100644
index 0000000..0ba931e
--- /dev/null
+++ b/tools/llvm-ranlib/Makefile
@@ -0,0 +1,15 @@
+##===- tools/llvm-ranlib/Makefile --------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file was developed by the LLVM research group and is distributed under
+# the University of Illinois Open Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../..
+TOOLNAME = llvm-ranlib
+LINK_COMPONENTS = archive
+REQUIRES_EH := 1
+
+include $(LEVEL)/Makefile.common
diff --git a/tools/llvm-ranlib/llvm-ranlib.cpp b/tools/llvm-ranlib/llvm-ranlib.cpp
new file mode 100644
index 0000000..9085b7e
--- /dev/null
+++ b/tools/llvm-ranlib/llvm-ranlib.cpp
@@ -0,0 +1,96 @@
+//===-- llvm-ranlib.cpp - LLVM archive index generator --------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Adds or updates an index (symbol table) for an LLVM archive file.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Module.h"
+#include "llvm/Bitcode/Archive.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/System/Signals.h"
+#include <iostream>
+#include <iomanip>
+#include <memory>
+
+using namespace llvm;
+
+// llvm-ar operation code and modifier flags
+static cl::opt<std::string>
+ArchiveName(cl::Positional, cl::Optional, cl::desc("<archive-file>"));
+
+static cl::opt<bool>
+Verbose("verbose",cl::Optional,cl::init(false),
+ cl::desc("Print the symbol table"));
+
+// printSymbolTable - print out the archive's symbol table.
+void printSymbolTable(Archive* TheArchive) {
+ std::cout << "\nArchive Symbol Table:\n";
+ const Archive::SymTabType& symtab = TheArchive->getSymbolTable();
+ for (Archive::SymTabType::const_iterator I=symtab.begin(), E=symtab.end();
+ I != E; ++I ) {
+ unsigned offset = TheArchive->getFirstFileOffset() + I->second;
+ std::cout << " " << std::setw(9) << offset << "\t" << I->first <<"\n";
+ }
+}
+
+int main(int argc, char **argv) {
+ llvm_shutdown_obj X; // Call llvm_shutdown() on exit.
+
+ // Have the command line options parsed and handle things
+ // like --help and --version.
+ cl::ParseCommandLineOptions(argc, argv,
+ " LLVM Archive Index Generator (llvm-ranlib)\n\n"
+ " This program adds or updates an index of bitcode symbols\n"
+ " to an LLVM archive file."
+ );
+
+ // Print a stack trace if we signal out.
+ sys::PrintStackTraceOnErrorSignal();
+
+ int exitCode = 0;
+
+ // Make sure we don't exit with "unhandled exception".
+ try {
+
+ // Check the path name of the archive
+ sys::Path ArchivePath;
+ if (!ArchivePath.set(ArchiveName))
+ throw std::string("Archive name invalid: ") + ArchiveName;
+
+ // Make sure it exists, we don't create empty archives
+ if (!ArchivePath.exists())
+ throw std::string("Archive file does not exist");
+
+ std::string err_msg;
+ std::auto_ptr<Archive>
+ AutoArchive(Archive::OpenAndLoad(ArchivePath,&err_msg));
+ Archive* TheArchive = AutoArchive.get();
+ if (!TheArchive)
+ throw err_msg;
+
+ if (TheArchive->writeToDisk(true, false, false, &err_msg ))
+ throw err_msg;
+
+ if (Verbose)
+ printSymbolTable(TheArchive);
+
+ } catch (const char*msg) {
+ std::cerr << argv[0] << ": " << msg << "\n\n";
+ exitCode = 1;
+ } catch (const std::string& msg) {
+ std::cerr << argv[0] << ": " << msg << "\n";
+ exitCode = 2;
+ } catch (...) {
+ std::cerr << argv[0] << ": An unexpected unknown exception occurred.\n";
+ exitCode = 3;
+ }
+ return exitCode;
+}
diff --git a/tools/llvm-stub/Makefile b/tools/llvm-stub/Makefile
new file mode 100644
index 0000000..befcb6c
--- /dev/null
+++ b/tools/llvm-stub/Makefile
@@ -0,0 +1,13 @@
+##===- tools/llvm-stub/Makefile ----------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file was developed by the LLVM research group and is distributed under
+# the University of Illinois Open Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../..
+TOOLNAME = llvm-stub
+include $(LEVEL)/Makefile.common
+
diff --git a/tools/llvm-stub/llvm-stub.c b/tools/llvm-stub/llvm-stub.c
new file mode 100644
index 0000000..809a532
--- /dev/null
+++ b/tools/llvm-stub/llvm-stub.c
@@ -0,0 +1,69 @@
+/*===- llvm-stub.c - Stub executable to run llvm bitcode files -----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This tool is used by the gccld program to enable transparent execution of
+// bitcode files by the user. Specifically, gccld outputs two files when asked
+// to compile a <program> file:
+// 1. It outputs the LLVM bitcode file to <program>.bc
+// 2. It outputs a stub executable that runs lli on <program>.bc
+//
+// This allows the end user to just say ./<program> and have the JIT executed
+// automatically. On unix, the stub executable emitted is actually a bourne
+// shell script that does the forwarding. Windows does not like #!/bin/sh
+// programs in .exe files, so we make it an actual program, defined here.
+//
+//===----------------------------------------------------------------------===*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "llvm/Config/config.h"
+
+#if defined(HAVE_UNISTD_H) && !defined(_MSC_VER)
+#include <unistd.h>
+#endif
+
+#ifdef _WIN32
+#include <process.h>
+#include <io.h>
+#endif
+
+int main(int argc, char** argv) {
+ const char *Interp = getenv("LLVMINTERP");
+ const char **Args;
+ if (Interp == 0) Interp = "lli";
+
+ /* Set up the command line options to pass to the JIT. */
+ Args = (const char**)malloc(sizeof(char*) * (argc+2));
+ /* argv[0] is the JIT */
+ Args[0] = Interp;
+
+#ifdef __CYGWIN32__
+ /* Cygwin strips the .exe suffix off of argv[0] to "help" us. Put it back
+ * on.
+ */
+ argv[0] = strcat(strcpy((char*)malloc(strlen(argv[0])+5), argv[0]), ".exe");
+#endif
+
+ /* argv[1] is argv[0] + ".bc". */
+ Args[1] = strcat(strcpy((char*)malloc(strlen(argv[0])+4), argv[0]), ".bc");
+
+ /* The rest of the args are as before. */
+ memcpy(Args+2, argv+1, sizeof(char*)*argc);
+
+ /* Run the JIT. */
+ execvp(Interp, (char *const*)Args);
+
+ /* if _execv returns, the JIT could not be started. */
+ fprintf(stderr, "Could not execute the LLVM JIT. Either add 'lli' to your"
+ " path, or set the\ninterpreter you want to use in the LLVMINTERP "
+ "environment variable.\n");
+ return 1;
+}
diff --git a/tools/llvm-upgrade/Makefile b/tools/llvm-upgrade/Makefile
new file mode 100644
index 0000000..1bd936b
--- /dev/null
+++ b/tools/llvm-upgrade/Makefile
@@ -0,0 +1,32 @@
+##===- tools/llvm-upgrade/Makefile -------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file was developed by Reid Spencer and is distributed under the
+# University of Illinois Open Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../..
+TOOLNAME = llvm-upgrade
+LINK_COMPONENTS := Core support system
+REQUIRES_EH := 1
+
+include $(LEVEL)/Makefile.common
+
+# Make the object code file for the lexer depend upon the header file generated
+# by the Bison parser. This prevents the Lexer from being compiled before the
+# header file it needs is built.
+$(ObjDir)/upgradeLexer.o: $(PROJ_SRC_DIR)/UpgradeParser.h
+
+TESTCASE=../../test/Regression/Assembler/2004-09-29-VerifierIsReallySlow.llx
+test:
+ llvm-as $(TESTCASE) -o - | llvm-dis -o source.ll -f
+ ../../Debug/bin/llvm-upgrade -o - $(TESTCASE) 2>err.out | llvm-as | \
+ llvm-dis > upgrade.ll -f
+ diff source.ll upgrade.ll > diff.out
+
+valgrind:
+ valgrind ../../Debug/bin/llvm-upgrade -o /dev/null -f $(TESTCASE)
+
+$(ObjDir)/UpgradeLexer.o: $(PROJ_SRC_DIR)/UpgradeParser.y $(PROJ_SRC_DIR)/UpgradeParser.h
diff --git a/tools/llvm-upgrade/UpgradeInternals.h b/tools/llvm-upgrade/UpgradeInternals.h
new file mode 100644
index 0000000..0e00400
--- /dev/null
+++ b/tools/llvm-upgrade/UpgradeInternals.h
@@ -0,0 +1,395 @@
+//===-- ParserInternals.h - Definitions internal to the parser --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file defines the various variables that are shared among the
+// different components of the parser...
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef PARSER_INTERNALS_H
+#define PARSER_INTERNALS_H
+
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Function.h"
+#include "llvm/Instructions.h"
+#include "llvm/ADT/StringExtras.h"
+#include <list>
+#include <iostream>
+
+
+// Global variables exported from the lexer.
+extern int yydebug;
+extern void error(const std::string& msg, int line = -1);
+extern char* Upgradetext;
+extern int Upgradeleng;
+extern int Upgradelineno;
+
+namespace llvm {
+
+class Module;
+Module* UpgradeAssembly(const std::string &infile, std::istream& in,
+ bool debug, bool addAttrs);
+
+extern std::istream* LexInput;
+
+// UnEscapeLexed - Run through the specified buffer and change \xx codes to the
+// appropriate character. If AllowNull is set to false, a \00 value will cause
+// an error.
+//
+// If AllowNull is set to true, the return value of the function points to the
+// last character of the string in memory.
+//
+char *UnEscapeLexed(char *Buffer, bool AllowNull = false);
+
+/// InlineAsmDescriptor - This is a simple class that holds info about inline
+/// asm blocks, for use by ValID.
+struct InlineAsmDescriptor {
+ std::string AsmString, Constraints;
+ bool HasSideEffects;
+
+ InlineAsmDescriptor(const std::string &as, const std::string &c, bool HSE)
+ : AsmString(as), Constraints(c), HasSideEffects(HSE) {}
+};
+
+/// This class keeps track of the signedness of a type or value. It allows the
+/// signedness of a composite type to be captured in a relatively simple form.
+/// This is needed in order to retain the signedness of pre LLVM 2.0 types so
+/// they can be upgraded properly. Signedness of composite types must be
+/// captured in order to accurately get the signedness of a value through a
+/// GEP instruction.
+/// @brief Class to track signedness of types and values.
+struct Signedness {
+ /// The basic kinds of signedness values.
+ enum Kind {
+ Signless, ///< The type doesn't have any sign.
+ Unsigned, ///< The type is an unsigned integer.
+ Signed, ///< The type is a signed integer.
+ Named, ///< The type is a named type (probably forward ref or up ref).
+ Composite ///< The type is composite (struct, array, pointer).
+ };
+
+private:
+ /// @brief Keeps track of Signedness for composite types
+ typedef std::vector<Signedness> SignVector;
+ Kind kind; ///< The kind of signedness node
+ union {
+ SignVector *sv; ///< The vector of Signedness for composite types
+ std::string *name; ///< The name of the type for named types.
+ };
+public:
+ /// The Signedness class is used as a member of a union so it cannot have
+ /// a constructor or assignment operator. This function suffices.
+ /// @brief Copy one signedness value to another
+ void copy(const Signedness &that);
+ /// The Signedness class is used as a member of a union so it cannot have
+ /// a destructor.
+ /// @brief Release memory, if any allocated.
+ void destroy();
+
+ /// @brief Make a Signless node.
+ void makeSignless() { kind = Signless; sv = 0; }
+ /// @brief Make a Signed node.
+ void makeSigned() { kind = Signed; sv = 0; }
+ /// @brief Make an Unsigned node.
+ void makeUnsigned() { kind = Unsigned; sv = 0; }
+ /// @brief Make a Named node.
+ void makeNamed(const std::string& nm){
+ kind = Named; name = new std::string(nm);
+ }
+ /// @brief Make an empty Composite node.
+ void makeComposite() { kind = Composite; sv = new SignVector(); }
+ /// @brief Make an Composite node, with the first element given.
+ void makeComposite(const Signedness &S) {
+ kind = Composite;
+ sv = new SignVector();
+ sv->push_back(S);
+ }
+ /// @brief Add an element to a Composite node.
+ void add(const Signedness &S) {
+ assert(isComposite() && "Must be composite to use add");
+ sv->push_back(S);
+ }
+ bool operator<(const Signedness &that) const;
+ bool operator==(const Signedness &that) const;
+ bool isSigned() const { return kind == Signed; }
+ bool isUnsigned() const { return kind == Unsigned; }
+ bool isSignless() const { return kind == Signless; }
+ bool isNamed() const { return kind == Named; }
+ bool isComposite() const { return kind == Composite; }
+ /// This is used by GetElementPtr to extract the sign of an element.
+ /// @brief Get a specific element from a Composite node.
+ Signedness get(uint64_t idx) const {
+ assert(isComposite() && "Invalid Signedness type for get()");
+ assert(sv && idx < sv->size() && "Invalid index");
+ return (*sv)[idx];
+ }
+ /// @brief Get the name from a Named node.
+ const std::string& getName() const {
+ assert(isNamed() && "Can't get name from non-name Sign");
+ return *name;
+ }
+#ifndef NDEBUG
+ void dump() const;
+#endif
+};
+
+
+// ValID - Represents a reference of a definition of some sort. This may either
+// be a numeric reference or a symbolic (%var) reference. This is just a
+// discriminated union.
+//
+// Note that I can't implement this class in a straight forward manner with
+// constructors and stuff because it goes in a union.
+//
+struct ValID {
+ enum {
+ NumberVal, NameVal, ConstSIntVal, ConstUIntVal, ConstFPVal, ConstNullVal,
+ ConstUndefVal, ConstZeroVal, ConstantVal, InlineAsmVal
+ } Type;
+
+ union {
+ int Num; // If it's a numeric reference
+ char *Name; // If it's a named reference. Memory must be free'd.
+ int64_t ConstPool64; // Constant pool reference. This is the value
+ uint64_t UConstPool64;// Unsigned constant pool reference.
+ double ConstPoolFP; // Floating point constant pool reference
+ Constant *ConstantValue; // Fully resolved constant for ConstantVal case.
+ InlineAsmDescriptor *IAD;
+ };
+ Signedness S;
+
+ static ValID create(int Num) {
+ ValID D; D.Type = NumberVal; D.Num = Num; D.S.makeSignless();
+ return D;
+ }
+
+ static ValID create(char *Name) {
+ ValID D; D.Type = NameVal; D.Name = Name; D.S.makeSignless();
+ return D;
+ }
+
+ static ValID create(int64_t Val) {
+ ValID D; D.Type = ConstSIntVal; D.ConstPool64 = Val;
+ D.S.makeSigned();
+ return D;
+ }
+
+ static ValID create(uint64_t Val) {
+ ValID D; D.Type = ConstUIntVal; D.UConstPool64 = Val;
+ D.S.makeUnsigned();
+ return D;
+ }
+
+ static ValID create(double Val) {
+ ValID D; D.Type = ConstFPVal; D.ConstPoolFP = Val;
+ D.S.makeSignless();
+ return D;
+ }
+
+ static ValID createNull() {
+ ValID D; D.Type = ConstNullVal;
+ D.S.makeSignless();
+ return D;
+ }
+
+ static ValID createUndef() {
+ ValID D; D.Type = ConstUndefVal;
+ D.S.makeSignless();
+ return D;
+ }
+
+ static ValID createZeroInit() {
+ ValID D; D.Type = ConstZeroVal;
+ D.S.makeSignless();
+ return D;
+ }
+
+ static ValID create(Constant *Val) {
+ ValID D; D.Type = ConstantVal; D.ConstantValue = Val;
+ D.S.makeSignless();
+ return D;
+ }
+
+ static ValID createInlineAsm(const std::string &AsmString,
+ const std::string &Constraints,
+ bool HasSideEffects) {
+ ValID D;
+ D.Type = InlineAsmVal;
+ D.IAD = new InlineAsmDescriptor(AsmString, Constraints, HasSideEffects);
+ D.S.makeSignless();
+ return D;
+ }
+
+ inline void destroy() const {
+ if (Type == NameVal)
+ free(Name); // Free this strdup'd memory.
+ else if (Type == InlineAsmVal)
+ delete IAD;
+ }
+
+ inline ValID copy() const {
+ if (Type != NameVal) return *this;
+ ValID Result = *this;
+ Result.Name = strdup(Name);
+ return Result;
+ }
+
+ inline std::string getName() const {
+ switch (Type) {
+ case NumberVal : return std::string("#") + itostr(Num);
+ case NameVal : return Name;
+ case ConstFPVal : return ftostr(ConstPoolFP);
+ case ConstNullVal : return "null";
+ case ConstUndefVal : return "undef";
+ case ConstZeroVal : return "zeroinitializer";
+ case ConstUIntVal :
+ case ConstSIntVal : return std::string("%") + itostr(ConstPool64);
+ case ConstantVal:
+ if (ConstantValue == ConstantInt::get(Type::Int1Ty, true))
+ return "true";
+ if (ConstantValue == ConstantInt::get(Type::Int1Ty, false))
+ return "false";
+ return "<constant expression>";
+ default:
+ assert(0 && "Unknown value!");
+ abort();
+ return "";
+ }
+ }
+
+ bool operator<(const ValID &V) const {
+ if (Type != V.Type) return Type < V.Type;
+ switch (Type) {
+ case NumberVal: return Num < V.Num;
+ case NameVal: return strcmp(Name, V.Name) < 0;
+ case ConstSIntVal: return ConstPool64 < V.ConstPool64;
+ case ConstUIntVal: return UConstPool64 < V.UConstPool64;
+ case ConstFPVal: return ConstPoolFP < V.ConstPoolFP;
+ case ConstNullVal: return false;
+ case ConstUndefVal: return false;
+ case ConstZeroVal: return false;
+ case ConstantVal: return ConstantValue < V.ConstantValue;
+ default: assert(0 && "Unknown value type!"); return false;
+ }
+ }
+};
+
+/// The following enums are used to keep track of prior opcodes. The lexer will
+/// retain the ability to parse obsolete opcode mnemonics and generates semantic
+/// values containing one of these enumerators.
+enum TermOps {
+ RetOp, BrOp, SwitchOp, InvokeOp, UnwindOp, UnreachableOp
+};
+
+enum BinaryOps {
+ AddOp, SubOp, MulOp,
+ DivOp, UDivOp, SDivOp, FDivOp,
+ RemOp, URemOp, SRemOp, FRemOp,
+ AndOp, OrOp, XorOp,
+ ShlOp, ShrOp, LShrOp, AShrOp,
+ SetEQ, SetNE, SetLE, SetGE, SetLT, SetGT
+};
+
+enum MemoryOps {
+ MallocOp, FreeOp, AllocaOp, LoadOp, StoreOp, GetElementPtrOp
+};
+
+enum OtherOps {
+ PHIOp, CallOp, SelectOp, UserOp1, UserOp2, VAArg,
+ ExtractElementOp, InsertElementOp, ShuffleVectorOp,
+ ICmpOp, FCmpOp
+};
+
+enum CastOps {
+ CastOp, TruncOp, ZExtOp, SExtOp, FPTruncOp, FPExtOp, FPToUIOp, FPToSIOp,
+ UIToFPOp, SIToFPOp, PtrToIntOp, IntToPtrOp, BitCastOp
+};
+
+// An enumeration for the old calling conventions, ala LLVM 1.9
+namespace OldCallingConv {
+ enum ID {
+ C = 0, CSRet = 1, Fast = 8, Cold = 9, X86_StdCall = 64, X86_FastCall = 65,
+ None = 99999
+ };
+}
+
+/// These structures are used as the semantic values returned from various
+/// productions in the grammar. They simply bundle an LLVM IR object with
+/// its Signedness value. These help track signedness through the various
+/// productions.
+struct TypeInfo {
+ const llvm::Type *T;
+ Signedness S;
+ bool operator<(const TypeInfo& that) const {
+ if (this == &that)
+ return false;
+ if (T < that.T)
+ return true;
+ if (T == that.T) {
+ bool result = S < that.S;
+//#define TYPEINFO_DEBUG
+#ifdef TYPEINFO_DEBUG
+ std::cerr << (result?"true ":"false ") << T->getDescription() << " (";
+ S.dump();
+ std::cerr << ") < " << that.T->getDescription() << " (";
+ that.S.dump();
+ std::cerr << ")\n";
+#endif
+ return result;
+ }
+ return false;
+ }
+ bool operator==(const TypeInfo& that) const {
+ if (this == &that)
+ return true;
+ return T == that.T && S == that.S;
+ }
+ void destroy() { S.destroy(); }
+};
+
+struct PATypeInfo {
+ llvm::PATypeHolder* PAT;
+ Signedness S;
+ void destroy() { S.destroy(); delete PAT; }
+};
+
+struct ConstInfo {
+ llvm::Constant* C;
+ Signedness S;
+ void destroy() { S.destroy(); }
+};
+
+struct ValueInfo {
+ llvm::Value* V;
+ Signedness S;
+ void destroy() { S.destroy(); }
+};
+
+struct InstrInfo {
+ llvm::Instruction *I;
+ Signedness S;
+ void destroy() { S.destroy(); }
+};
+
+struct TermInstInfo {
+ llvm::TerminatorInst *TI;
+ Signedness S;
+ void destroy() { S.destroy(); }
+};
+
+struct PHIListInfo {
+ std::list<std::pair<llvm::Value*, llvm::BasicBlock*> > *P;
+ Signedness S;
+ void destroy() { S.destroy(); delete P; }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/tools/llvm-upgrade/UpgradeLexer.cpp.cvs b/tools/llvm-upgrade/UpgradeLexer.cpp.cvs
new file mode 100644
index 0000000..68ae9a4
--- /dev/null
+++ b/tools/llvm-upgrade/UpgradeLexer.cpp.cvs
@@ -0,0 +1,3077 @@
+#define yy_create_buffer Upgrade_create_buffer
+#define yy_delete_buffer Upgrade_delete_buffer
+#define yy_scan_buffer Upgrade_scan_buffer
+#define yy_scan_string Upgrade_scan_string
+#define yy_scan_bytes Upgrade_scan_bytes
+#define yy_flex_debug Upgrade_flex_debug
+#define yy_init_buffer Upgrade_init_buffer
+#define yy_flush_buffer Upgrade_flush_buffer
+#define yy_load_buffer_state Upgrade_load_buffer_state
+#define yy_switch_to_buffer Upgrade_switch_to_buffer
+#define yyin Upgradein
+#define yyleng Upgradeleng
+#define yylex Upgradelex
+#define yyout Upgradeout
+#define yyrestart Upgraderestart
+#define yytext Upgradetext
+#define yylineno Upgradelineno
+
+#line 20 "UpgradeLexer.cpp"
+/* A lexical scanner generated by flex*/
+
+/* Scanner skeleton version:
+ * $Header$
+ */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+
+#include <stdio.h>
+#include <unistd.h>
+
+
+/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
+#endif
+#endif
+
+
+#ifdef __cplusplus
+
+#include <stdlib.h>
+
+/* Use prototypes in function declarations. */
+#define YY_USE_PROTOS
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_PROTOS
+#define YY_USE_CONST
+
+#endif /* __STDC__ */
+#endif /* ! __cplusplus */
+
+#ifdef __TURBOC__
+ #pragma warn -rch
+ #pragma warn -use
+#include <io.h>
+#include <stdlib.h>
+#define YY_USE_CONST
+#define YY_USE_PROTOS
+#endif
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+
+#ifdef YY_USE_PROTOS
+#define YY_PROTO(proto) proto
+#else
+#define YY_PROTO(proto) ()
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart( yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#define YY_BUF_SIZE (16384*64)
+
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+
+extern int yyleng;
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+/* The funky do-while in the following #define is used to turn the definition
+ * int a single C statement (which needs a semi-colon terminator). This
+ * avoids problems with code like:
+ *
+ * if ( condition_holds )
+ * yyless( 5 );
+ * else
+ * do_something_else();
+ *
+ * Prior to using the do-while the compiler would get upset at the
+ * "else" because it interpreted the "if" statement as being all
+ * done when it reached the ';' after the yyless() call.
+ */
+
+/* Return all but the first 'n' matched characters back to the input stream. */
+
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ *yy_cp = yy_hold_char; \
+ YY_RESTORE_YY_MORE_OFFSET \
+ yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, yytext_ptr )
+
+/* Some routines like yy_flex_realloc() are emitted as static but are
+ not called by all lexers. This generates warnings in some compilers,
+ notably GCC. Arrange to suppress these. */
+#ifdef __GNUC__
+#define YY_MAY_BE_UNUSED __attribute__((unused))
+#else
+#define YY_MAY_BE_UNUSED
+#endif
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+typedef unsigned int yy_size_t;
+
+
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via yyrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+ };
+
+static YY_BUFFER_STATE yy_current_buffer = 0;
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ */
+#define YY_CURRENT_BUFFER yy_current_buffer
+
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+
+static int yy_n_chars; /* number of characters read into yy_ch_buf */
+
+
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 1; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart YY_PROTO(( FILE *input_file ));
+
+void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
+void yy_load_buffer_state YY_PROTO(( void ));
+YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
+void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
+void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
+
+YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
+YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));
+YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
+
+static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
+static inline void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )) YY_MAY_BE_UNUSED;
+static void yy_flex_free YY_PROTO(( void * ));
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! yy_current_buffer ) \
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ yy_current_buffer->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! yy_current_buffer ) \
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ yy_current_buffer->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
+
+
+#define YY_USES_REJECT
+
+#define yywrap() 1
+#define YY_SKIP_YYWRAP
+typedef unsigned char YY_CHAR;
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+typedef int yy_state_type;
+extern int yylineno;
+int yylineno = 1;
+extern char *yytext;
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state YY_PROTO(( void ));
+static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
+static int yy_get_next_buffer YY_PROTO(( void ));
+static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ yytext_ptr = yy_bp; \
+ yyleng = (int) (yy_cp - yy_bp); \
+ yy_hold_char = *yy_cp; \
+ *yy_cp = '\0'; \
+ yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 161
+#define YY_END_OF_BUFFER 162
+static yyconst short int yy_acclist[241] =
+ { 0,
+ 162, 160, 161, 159, 160, 161, 159, 161, 160, 161,
+ 160, 161, 160, 161, 160, 161, 160, 161, 160, 161,
+ 152, 160, 161, 152, 160, 161, 1, 160, 161, 160,
+ 161, 160, 161, 160, 161, 160, 161, 160, 161, 160,
+ 161, 160, 161, 160, 161, 160, 161, 160, 161, 160,
+ 161, 160, 161, 160, 161, 160, 161, 160, 161, 160,
+ 161, 160, 161, 160, 161, 160, 161, 160, 161, 160,
+ 161, 160, 161, 151, 149, 148, 148, 155, 153, 157,
+ 152, 1, 134, 41, 94, 62, 50, 95, 80, 23,
+ 151, 148, 148, 156, 157, 20, 157, 158, 68, 79,
+
+ 39, 34, 42, 71, 3, 53, 56, 59, 54, 70,
+ 25, 104, 109, 107, 108, 106, 105, 110, 114, 75,
+ 133, 99, 97, 88, 89, 98, 96, 69, 112, 103,
+ 101, 102, 100, 113, 111, 81, 150, 157, 157, 91,
+ 61, 115, 116, 93, 74, 141, 78, 92, 142, 57,
+ 90, 22, 154, 73, 119, 77, 26, 4, 66, 72,
+ 55, 76, 60, 11, 118, 157, 36, 2, 5, 63,
+ 121, 65, 48, 83, 87, 85, 86, 84, 82, 51,
+ 143, 117, 49, 58, 21, 131, 140, 45, 64, 30,
+ 24, 44, 123, 122, 7, 136, 33, 139, 38, 67,
+
+ 129, 125, 135, 27, 28, 124, 137, 52, 132, 130,
+ 128, 43, 6, 29, 120, 37, 8, 17, 9, 127,
+ 10, 126, 35, 12, 14, 13, 32, 40, 15, 31,
+ 138, 144, 146, 147, 16, 46, 145, 18, 47, 19
+ } ;
+
+static yyconst short int yy_accept[621] =
+ { 0,
+ 1, 1, 1, 2, 4, 7, 9, 11, 13, 15,
+ 17, 19, 21, 24, 27, 30, 32, 34, 36, 38,
+ 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
+ 60, 62, 64, 66, 68, 70, 72, 74, 74, 75,
+ 75, 76, 77, 78, 79, 79, 80, 80, 81, 82,
+ 82, 83, 83, 83, 83, 83, 83, 83, 83, 83,
+ 83, 84, 84, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 87, 87, 87, 88, 88, 88, 88, 88,
+ 88, 88, 88, 88, 88, 88, 89, 89, 89, 89,
+
+ 89, 89, 89, 89, 90, 90, 90, 90, 90, 90,
+ 90, 90, 90, 90, 90, 90, 90, 90, 90, 90,
+ 90, 90, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 92, 93, 95, 96, 97, 98, 98, 99, 99, 100,
+ 100, 100, 101, 101, 101, 102, 102, 103, 103, 103,
+ 103, 103, 104, 104, 104, 104, 104, 104, 104, 105,
+ 105, 105, 106, 106, 106, 106, 106, 106, 106, 106,
+ 106, 106, 106, 106, 106, 107, 108, 109, 109, 109,
+ 109, 110, 110, 110, 110, 110, 110, 110, 110, 110,
+
+ 110, 111, 112, 112, 113, 114, 115, 116, 117, 118,
+ 118, 119, 120, 120, 120, 121, 122, 122, 122, 122,
+ 122, 122, 122, 122, 123, 124, 125, 125, 126, 126,
+ 126, 126, 127, 128, 128, 128, 129, 129, 129, 129,
+ 129, 129, 129, 129, 129, 130, 131, 132, 132, 132,
+ 133, 133, 134, 134, 135, 135, 136, 136, 136, 136,
+ 136, 136, 136, 136, 136, 136, 136, 136, 137, 137,
+ 137, 138, 139, 139, 139, 139, 140, 140, 140, 140,
+ 141, 141, 141, 142, 143, 144, 144, 144, 144, 144,
+ 144, 144, 144, 144, 144, 144, 144, 144, 144, 144,
+
+ 144, 145, 146, 146, 146, 146, 146, 147, 148, 148,
+ 148, 149, 149, 149, 149, 149, 149, 149, 149, 149,
+ 150, 151, 152, 152, 152, 153, 153, 153, 153, 154,
+ 154, 155, 155, 155, 155, 155, 155, 155, 156, 156,
+ 156, 156, 156, 157, 157, 157, 158, 158, 158, 159,
+ 159, 160, 160, 161, 162, 162, 162, 162, 162, 162,
+ 162, 163, 163, 163, 163, 163, 164, 164, 165, 165,
+ 165, 166, 167, 168, 168, 168, 169, 169, 169, 169,
+ 169, 169, 169, 169, 169, 169, 169, 169, 169, 169,
+ 169, 170, 170, 171, 172, 172, 172, 172, 172, 172,
+
+ 172, 172, 172, 172, 172, 173, 173, 173, 173, 173,
+ 173, 173, 173, 174, 174, 174, 175, 176, 177, 178,
+ 179, 180, 181, 181, 181, 181, 182, 182, 182, 182,
+ 183, 184, 184, 185, 186, 186, 186, 186, 186, 186,
+ 187, 187, 187, 187, 187, 187, 188, 188, 188, 189,
+ 189, 189, 189, 189, 189, 189, 189, 190, 191, 192,
+ 192, 192, 193, 194, 195, 195, 195, 196, 196, 196,
+ 196, 196, 197, 197, 198, 199, 200, 201, 201, 201,
+ 201, 202, 202, 202, 203, 204, 205, 206, 207, 207,
+ 207, 208, 209, 210, 211, 211, 211, 211, 211, 211,
+
+ 212, 212, 213, 213, 214, 215, 215, 215, 215, 215,
+ 215, 216, 216, 216, 216, 216, 216, 216, 216, 216,
+ 217, 217, 217, 217, 217, 217, 217, 217, 217, 217,
+ 218, 218, 218, 218, 218, 219, 219, 219, 219, 219,
+ 220, 221, 222, 222, 223, 223, 223, 223, 223, 224,
+ 224, 224, 224, 225, 225, 226, 227, 227, 227, 227,
+ 227, 227, 227, 227, 227, 227, 227, 227, 227, 227,
+ 228, 228, 228, 228, 228, 228, 228, 228, 229, 229,
+ 229, 229, 229, 229, 230, 230, 230, 230, 230, 231,
+ 231, 231, 232, 232, 232, 232, 232, 232, 232, 232,
+
+ 232, 232, 232, 232, 232, 232, 233, 233, 234, 235,
+ 236, 236, 237, 237, 238, 239, 240, 240, 241, 241
+ } ;
+
+static yyconst int yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 1, 2, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 1, 4, 1, 5, 6, 1, 1, 1,
+ 1, 1, 7, 1, 8, 9, 1, 10, 11, 12,
+ 13, 14, 15, 16, 15, 17, 15, 18, 19, 1,
+ 1, 1, 1, 20, 21, 21, 21, 21, 22, 21,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 1, 1, 1, 1, 23, 1, 24, 25, 26, 27,
+
+ 28, 29, 30, 31, 32, 5, 33, 34, 35, 36,
+ 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
+ 47, 48, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static yyconst int yy_meta[49] =
+ { 0,
+ 1, 1, 2, 1, 3, 1, 4, 5, 3, 6,
+ 6, 6, 6, 6, 6, 6, 6, 7, 1, 1,
+ 3, 8, 3, 3, 3, 3, 3, 8, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3
+ } ;
+
+static yyconst short int yy_base[630] =
+ { 0,
+ 0, 0, 1336, 1337, 1337, 1337, 1331, 1316, 41, 0,
+ 49, 59, 69, 1287, 0, 112, 69, 72, 93, 113,
+ 52, 122, 74, 152, 120, 77, 136, 156, 135, 71,
+ 187, 186, 224, 118, 115, 56, 153, 1328, 1337, 1313,
+ 1337, 0, 256, 0, 1321, 1320, 88, 264, 1282, 283,
+ 0, 1323, 140, 157, 158, 121, 164, 183, 198, 32,
+ 1308, 190, 95, 175, 54, 165, 217, 162, 117, 182,
+ 218, 1307, 220, 272, 185, 100, 204, 219, 235, 241,
+ 264, 232, 273, 57, 1306, 284, 285, 296, 297, 299,
+ 300, 226, 298, 302, 308, 1305, 303, 309, 307, 316,
+
+ 321, 329, 330, 332, 333, 334, 313, 337, 310, 315,
+ 342, 343, 350, 353, 346, 352, 358, 363, 357, 365,
+ 366, 1304, 373, 377, 381, 385, 383, 384, 389, 390,
+ 402, 386, 392, 417, 418, 395, 271, 393, 403, 1303,
+ 0, 0, 416, 1302, 0, 447, 0, 1315, 1300, 438,
+ 428, 1299, 448, 427, 1298, 419, 1297, 451, 452, 453,
+ 406, 1296, 454, 455, 456, 461, 457, 460, 1295, 465,
+ 464, 470, 462, 477, 474, 480, 481, 482, 483, 485,
+ 488, 486, 490, 491, 1294, 1293, 1292, 492, 493, 495,
+ 506, 502, 514, 511, 494, 519, 515, 517, 520, 522,
+
+ 1291, 1290, 525, 1289, 1288, 1287, 1286, 1285, 1284, 523,
+ 1283, 1282, 531, 529, 1281, 1280, 562, 538, 537, 540,
+ 532, 567, 550, 1279, 1278, 1277, 575, 1276, 534, 533,
+ 576, 1275, 1274, 535, 578, 1273, 580, 582, 581, 586,
+ 584, 589, 587, 588, 1272, 1271, 1270, 591, 590, 1269,
+ 592, 1268, 603, 1267, 601, 1266, 607, 608, 612, 605,
+ 620, 596, 621, 616, 627, 623, 546, 1265, 628, 630,
+ 1337, 630, 646, 652, 654, 656, 632, 648, 637, 1264,
+ 639, 652, 1263, 1262, 1261, 651, 649, 653, 660, 661,
+ 664, 662, 663, 665, 666, 668, 669, 679, 674, 675,
+
+ 1260, 1259, 670, 671, 682, 686, 1258, 1257, 687, 692,
+ 1256, 689, 693, 696, 697, 702, 704, 700, 706, 1255,
+ 1254, 1253, 708, 709, 1252, 701, 710, 712, 0, 713,
+ 1251, 714, 721, 724, 730, 732, 733, 1250, 735, 736,
+ 738, 739, 1249, 741, 744, 1248, 753, 746, 1247, 749,
+ 1246, 755, 1245, 1244, 758, 760, 764, 766, 761, 768,
+ 1243, 770, 771, 773, 774, 1242, 776, 1241, 778, 777,
+ 1240, 0, 1239, 781, 779, 1238, 782, 790, 797, 796,
+ 806, 794, 807, 795, 799, 808, 809, 810, 811, 813,
+ 1237, 817, 1236, 1235, 822, 823, 820, 830, 826, 824,
+
+ 828, 831, 833, 835, 1234, 832, 844, 839, 846, 848,
+ 851, 843, 1233, 855, 859, 1232, 1231, 1230, 1229, 1228,
+ 1227, 1226, 860, 862, 864, 1225, 865, 863, 867, 1224,
+ 1223, 866, 1222, 1221, 868, 871, 872, 869, 870, 1220,
+ 875, 880, 885, 888, 889, 1219, 890, 895, 1218, 896,
+ 897, 898, 900, 901, 902, 903, 1217, 1216, 1215, 911,
+ 906, 1214, 1213, 1212, 915, 908, 1211, 918, 926, 929,
+ 909, 1210, 931, 1209, 1208, 1207, 1206, 920, 932, 934,
+ 1205, 937, 938, 1204, 1203, 1202, 1201, 1200, 940, 943,
+ 1199, 1198, 1197, 1192, 941, 944, 946, 945, 948, 1181,
+
+ 951, 1178, 953, 1170, 1167, 958, 960, 961, 962, 963,
+ 1164, 964, 965, 968, 969, 970, 971, 976, 977, 1158,
+ 979, 986, 987, 989, 990, 991, 994, 997, 998, 1146,
+ 1003, 1006, 1007, 1004, 1145, 1008, 1009, 1011, 1012, 1144,
+ 1142, 1141, 1018, 1140, 1013, 1017, 1020, 1019, 1139, 1029,
+ 1033, 1034, 1137, 1016, 1136, 1133, 1038, 1041, 1042, 1043,
+ 1045, 1046, 1047, 1050, 1053, 1052, 1054, 1056, 1057, 1131,
+ 1058, 1061, 1059, 1064, 1065, 1070, 1069, 1128, 1071, 1077,
+ 1081, 1082, 1083, 913, 1084, 1085, 1086, 1089, 784, 1091,
+ 1092, 783, 1090, 1095, 1104, 1096, 1105, 1111, 1108, 1112,
+
+ 1113, 1115, 1116, 1117, 1119, 737, 1120, 548, 391, 349,
+ 1121, 312, 1125, 270, 266, 221, 1126, 184, 1337, 1166,
+ 1172, 1178, 192, 1186, 1192, 70, 1200, 1203, 1208
+ } ;
+
+static yyconst short int yy_def[630] =
+ { 0,
+ 619, 1, 619, 619, 619, 619, 620, 621, 622, 623,
+ 621, 621, 11, 13, 624, 622, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 620, 619, 621,
+ 619, 625, 625, 626, 623, 11, 621, 11, 13, 11,
+ 624, 627, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 619,
+ 625, 43, 628, 621, 48, 11, 50, 627, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 50, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 619, 628, 629, 629, 146, 146, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 217, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 274, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+
+ 621, 621, 621, 621, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 621, 621, 621, 621, 621, 0, 619,
+ 619, 619, 619, 619, 619, 619, 619, 619, 619
+ } ;
+
+static yyconst short int yy_nxt[1386] =
+ { 0,
+ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+ 14, 14, 14, 14, 14, 14, 14, 4, 15, 16,
+ 8, 8, 8, 17, 18, 19, 20, 21, 22, 23,
+ 8, 24, 8, 25, 26, 27, 28, 29, 8, 30,
+ 31, 32, 33, 34, 35, 36, 8, 37, 43, 41,
+ 44, 44, 44, 44, 44, 44, 44, 44, 46, 46,
+ 46, 46, 46, 46, 46, 46, 41, 47, 159, 41,
+ 187, 41, 137, 41, 41, 44, 41, 48, 49, 49,
+ 49, 49, 49, 49, 49, 49, 41, 71, 41, 41,
+ 72, 41, 138, 165, 41, 53, 144, 73, 108, 58,
+
+ 93, 80, 54, 59, 55, 41, 56, 81, 60, 57,
+ 41, 61, 41, 94, 50, 52, 62, 41, 63, 95,
+ 162, 619, 619, 619, 619, 619, 619, 619, 619, 64,
+ 41, 178, 41, 65, 41, 41, 66, 41, 41, 41,
+ 67, 134, 136, 89, 68, 74, 69, 75, 76, 70,
+ 170, 90, 41, 41, 135, 77, 91, 41, 153, 78,
+ 92, 79, 82, 96, 83, 105, 149, 84, 85, 41,
+ 41, 106, 97, 41, 41, 41, 107, 86, 98, 41,
+ 139, 41, 41, 99, 152, 100, 87, 88, 150, 101,
+ 151, 102, 41, 103, 154, 104, 109, 45, 155, 41,
+
+ 41, 41, 41, 41, 41, 169, 166, 41, 163, 121,
+ 164, 110, 156, 111, 112, 41, 113, 114, 115, 177,
+ 116, 41, 122, 160, 171, 123, 117, 157, 118, 119,
+ 161, 120, 124, 109, 41, 41, 41, 41, 41, 158,
+ 179, 41, 167, 41, 172, 173, 180, 185, 125, 41,
+ 126, 127, 41, 128, 168, 129, 198, 130, 41, 131,
+ 181, 174, 182, 132, 133, 142, 142, 142, 142, 142,
+ 142, 142, 142, 145, 145, 145, 145, 145, 145, 145,
+ 145, 41, 183, 41, 186, 146, 267, 41, 41, 41,
+ 41, 146, 147, 147, 147, 147, 147, 147, 147, 147,
+
+ 184, 41, 41, 147, 147, 175, 147, 147, 147, 147,
+ 147, 147, 176, 41, 41, 41, 41, 41, 188, 41,
+ 41, 193, 189, 196, 41, 41, 41, 41, 200, 41,
+ 41, 199, 41, 41, 194, 197, 190, 191, 41, 192,
+ 195, 201, 203, 205, 202, 204, 41, 41, 207, 41,
+ 41, 41, 214, 210, 41, 217, 209, 206, 211, 41,
+ 41, 218, 208, 41, 212, 213, 41, 41, 220, 41,
+ 41, 215, 230, 219, 41, 41, 221, 224, 216, 232,
+ 41, 236, 41, 41, 222, 234, 226, 231, 223, 227,
+ 41, 225, 228, 233, 41, 229, 237, 238, 41, 235,
+
+ 41, 41, 41, 41, 240, 239, 41, 41, 41, 41,
+ 41, 246, 41, 259, 242, 241, 244, 250, 266, 41,
+ 41, 245, 260, 41, 248, 247, 251, 243, 253, 254,
+ 249, 252, 268, 255, 41, 41, 41, 273, 256, 261,
+ 262, 257, 269, 273, 41, 41, 258, 285, 270, 264,
+ 281, 265, 263, 274, 275, 41, 276, 276, 276, 276,
+ 276, 276, 276, 276, 278, 41, 280, 277, 41, 41,
+ 41, 41, 41, 41, 41, 279, 282, 41, 41, 41,
+ 286, 41, 41, 288, 289, 283, 284, 41, 294, 296,
+ 290, 41, 292, 291, 41, 287, 293, 41, 41, 41,
+
+ 41, 295, 41, 41, 297, 41, 303, 41, 41, 41,
+ 41, 41, 41, 307, 299, 310, 298, 309, 301, 41,
+ 308, 300, 313, 41, 305, 302, 312, 306, 41, 311,
+ 304, 41, 41, 314, 41, 319, 41, 41, 316, 41,
+ 41, 317, 41, 318, 321, 320, 41, 315, 41, 41,
+ 41, 41, 41, 323, 41, 41, 322, 41, 325, 333,
+ 341, 326, 340, 41, 324, 41, 327, 41, 369, 343,
+ 328, 329, 329, 329, 329, 329, 329, 329, 329, 330,
+ 331, 332, 329, 329, 41, 329, 329, 329, 329, 329,
+ 329, 338, 41, 41, 334, 41, 335, 41, 41, 41,
+
+ 336, 41, 337, 41, 41, 41, 41, 41, 41, 41,
+ 347, 349, 342, 41, 339, 346, 351, 344, 41, 350,
+ 41, 345, 41, 348, 41, 41, 355, 356, 352, 41,
+ 357, 353, 354, 41, 359, 364, 358, 41, 41, 360,
+ 41, 362, 366, 363, 41, 41, 361, 41, 365, 41,
+ 367, 273, 274, 274, 41, 368, 41, 273, 619, 619,
+ 619, 40, 619, 40, 370, 41, 41, 373, 41, 41,
+ 41, 371, 375, 374, 376, 377, 378, 41, 41, 41,
+ 41, 41, 41, 41, 382, 41, 41, 41, 41, 387,
+ 379, 41, 41, 381, 380, 383, 41, 385, 386, 41,
+
+ 392, 391, 390, 41, 41, 388, 41, 384, 389, 41,
+ 41, 393, 394, 41, 41, 399, 400, 41, 41, 41,
+ 398, 41, 395, 41, 396, 41, 41, 41, 397, 41,
+ 41, 41, 401, 403, 404, 402, 406, 405, 41, 407,
+ 413, 41, 409, 410, 408, 414, 415, 41, 412, 41,
+ 41, 411, 41, 41, 41, 41, 41, 417, 41, 419,
+ 421, 41, 416, 41, 423, 424, 41, 425, 426, 427,
+ 41, 418, 41, 420, 430, 41, 422, 41, 41, 429,
+ 428, 41, 431, 41, 436, 41, 432, 41, 41, 433,
+ 41, 41, 434, 41, 41, 41, 41, 435, 41, 41,
+
+ 41, 41, 440, 437, 446, 447, 443, 41, 445, 438,
+ 439, 41, 41, 41, 41, 449, 41, 442, 444, 441,
+ 450, 451, 448, 41, 41, 41, 41, 41, 41, 452,
+ 41, 454, 455, 453, 41, 457, 456, 41, 461, 41,
+ 41, 41, 462, 41, 458, 41, 460, 41, 41, 41,
+ 41, 459, 41, 463, 464, 465, 41, 466, 468, 467,
+ 41, 41, 472, 41, 475, 41, 470, 473, 41, 469,
+ 471, 474, 41, 476, 479, 477, 41, 41, 478, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 483, 480, 41, 482, 487, 485, 490, 41, 491, 493,
+
+ 481, 484, 41, 488, 486, 41, 41, 41, 496, 489,
+ 492, 495, 41, 41, 41, 41, 494, 41, 41, 41,
+ 41, 499, 502, 41, 498, 41, 41, 504, 41, 497,
+ 41, 501, 41, 508, 509, 41, 500, 41, 506, 507,
+ 511, 505, 512, 41, 503, 513, 41, 510, 41, 41,
+ 516, 41, 515, 514, 41, 41, 517, 41, 41, 518,
+ 41, 41, 41, 41, 521, 41, 522, 519, 41, 520,
+ 41, 523, 527, 524, 525, 41, 528, 41, 41, 41,
+ 41, 41, 41, 529, 526, 41, 41, 41, 41, 531,
+ 536, 537, 530, 41, 41, 535, 41, 532, 542, 533,
+
+ 538, 539, 540, 41, 41, 534, 41, 41, 41, 541,
+ 547, 41, 548, 546, 41, 41, 543, 549, 544, 551,
+ 41, 41, 545, 41, 41, 41, 41, 553, 41, 41,
+ 41, 557, 550, 41, 41, 41, 41, 41, 552, 561,
+ 563, 558, 564, 566, 559, 554, 41, 555, 556, 562,
+ 41, 41, 560, 565, 567, 41, 568, 570, 41, 41,
+ 41, 571, 41, 41, 41, 569, 574, 41, 572, 41,
+ 41, 41, 577, 41, 41, 41, 41, 581, 41, 575,
+ 583, 41, 41, 573, 579, 580, 41, 41, 41, 582,
+ 584, 578, 588, 576, 41, 585, 586, 589, 41, 41,
+
+ 41, 41, 41, 41, 592, 587, 41, 41, 41, 41,
+ 590, 596, 41, 41, 593, 594, 595, 598, 591, 601,
+ 603, 41, 41, 602, 599, 41, 597, 600, 41, 41,
+ 41, 605, 41, 41, 41, 604, 41, 41, 41, 610,
+ 611, 612, 41, 41, 606, 41, 616, 607, 41, 608,
+ 41, 609, 617, 41, 41, 615, 41, 41, 41, 41,
+ 614, 41, 41, 41, 613, 618, 38, 38, 38, 38,
+ 38, 38, 38, 38, 40, 41, 40, 40, 40, 40,
+ 42, 41, 42, 42, 41, 42, 51, 41, 51, 51,
+ 51, 51, 51, 51, 141, 41, 141, 141, 41, 141,
+
+ 148, 148, 148, 148, 148, 148, 148, 148, 272, 41,
+ 272, 372, 372, 372, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 39, 41,
+ 271, 41, 41, 41, 41, 41, 39, 40, 48, 143,
+ 41, 140, 40, 41, 39, 619, 3, 619, 619, 619,
+ 619, 619, 619, 619, 619, 619, 619, 619, 619, 619,
+ 619, 619, 619, 619, 619, 619, 619, 619, 619, 619,
+ 619, 619, 619, 619, 619, 619, 619, 619, 619, 619,
+ 619, 619, 619, 619, 619, 619, 619, 619, 619, 619,
+ 619, 619, 619, 619, 619
+ } ;
+
+static yyconst short int yy_chk[1386] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 9, 60,
+ 9, 9, 9, 9, 9, 9, 9, 9, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 12, 60, 21,
+ 84, 65, 36, 36, 84, 626, 12, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 17, 21, 30, 18,
+ 21, 23, 36, 65, 26, 17, 47, 21, 30, 18,
+
+ 26, 23, 17, 18, 17, 47, 17, 23, 18, 17,
+ 19, 18, 63, 26, 13, 16, 19, 76, 19, 26,
+ 63, 16, 16, 16, 16, 16, 16, 16, 16, 19,
+ 20, 76, 35, 19, 69, 34, 20, 25, 56, 22,
+ 20, 34, 35, 25, 20, 22, 20, 22, 22, 20,
+ 69, 25, 29, 27, 34, 22, 25, 53, 56, 22,
+ 25, 22, 24, 27, 24, 29, 53, 24, 24, 24,
+ 37, 29, 27, 28, 54, 55, 29, 24, 27, 68,
+ 37, 57, 66, 28, 55, 28, 24, 24, 54, 28,
+ 54, 28, 64, 28, 57, 28, 31, 623, 57, 70,
+
+ 58, 618, 75, 32, 31, 68, 66, 62, 64, 32,
+ 64, 31, 58, 31, 31, 59, 31, 31, 31, 75,
+ 31, 77, 32, 62, 70, 32, 31, 59, 31, 31,
+ 62, 31, 32, 33, 67, 71, 78, 73, 616, 59,
+ 77, 33, 67, 92, 71, 73, 78, 82, 33, 82,
+ 33, 33, 79, 33, 67, 33, 92, 33, 80, 33,
+ 78, 73, 79, 33, 33, 43, 43, 43, 43, 43,
+ 43, 43, 43, 48, 48, 48, 48, 48, 48, 48,
+ 48, 81, 80, 615, 83, 48, 137, 614, 137, 74,
+ 83, 48, 50, 50, 50, 50, 50, 50, 50, 50,
+
+ 81, 86, 87, 50, 50, 74, 50, 50, 50, 50,
+ 50, 50, 74, 88, 89, 93, 90, 91, 86, 94,
+ 97, 89, 87, 91, 99, 95, 98, 109, 94, 612,
+ 107, 93, 110, 100, 90, 91, 88, 88, 101, 88,
+ 90, 95, 98, 100, 97, 99, 102, 103, 101, 104,
+ 105, 106, 107, 103, 108, 109, 102, 100, 104, 111,
+ 112, 110, 101, 115, 105, 106, 610, 113, 112, 116,
+ 114, 108, 115, 111, 119, 117, 112, 113, 108, 116,
+ 118, 119, 120, 121, 112, 117, 114, 115, 112, 114,
+ 123, 113, 114, 116, 124, 114, 120, 121, 125, 118,
+
+ 127, 128, 126, 132, 123, 121, 129, 130, 609, 133,
+ 138, 128, 136, 132, 124, 123, 126, 130, 136, 131,
+ 139, 127, 133, 161, 129, 128, 130, 125, 131, 131,
+ 129, 130, 138, 131, 134, 135, 156, 143, 131, 134,
+ 134, 131, 139, 143, 154, 151, 131, 161, 139, 135,
+ 156, 135, 134, 146, 146, 150, 146, 146, 146, 146,
+ 146, 146, 146, 146, 151, 153, 154, 150, 158, 159,
+ 160, 163, 164, 165, 167, 153, 158, 168, 166, 173,
+ 163, 171, 170, 165, 166, 159, 160, 172, 171, 173,
+ 167, 175, 170, 168, 174, 164, 170, 176, 177, 178,
+
+ 179, 172, 180, 182, 174, 181, 179, 183, 184, 188,
+ 189, 195, 190, 182, 175, 184, 174, 183, 177, 192,
+ 182, 176, 190, 191, 181, 178, 189, 181, 194, 188,
+ 180, 193, 197, 191, 198, 195, 196, 199, 192, 200,
+ 210, 193, 203, 194, 197, 196, 214, 191, 213, 221,
+ 230, 229, 234, 199, 219, 218, 198, 220, 203, 221,
+ 230, 210, 229, 267, 200, 608, 213, 223, 267, 234,
+ 214, 217, 217, 217, 217, 217, 217, 217, 217, 218,
+ 219, 220, 217, 217, 222, 217, 217, 217, 217, 217,
+ 217, 223, 227, 231, 222, 235, 222, 237, 239, 238,
+
+ 222, 241, 222, 240, 243, 244, 242, 249, 248, 251,
+ 239, 241, 231, 262, 227, 238, 242, 235, 255, 241,
+ 253, 237, 260, 240, 257, 258, 249, 251, 243, 259,
+ 253, 244, 248, 264, 257, 262, 255, 261, 263, 258,
+ 266, 260, 264, 261, 265, 269, 259, 270, 263, 277,
+ 265, 272, 273, 273, 279, 266, 281, 272, 274, 274,
+ 275, 275, 276, 276, 269, 278, 287, 277, 286, 282,
+ 288, 270, 279, 278, 281, 282, 286, 289, 290, 292,
+ 293, 291, 294, 295, 290, 296, 297, 303, 304, 295,
+ 287, 299, 300, 289, 288, 291, 298, 293, 294, 305,
+
+ 300, 299, 298, 306, 309, 296, 312, 292, 297, 310,
+ 313, 303, 304, 314, 315, 310, 312, 318, 326, 316,
+ 309, 317, 305, 319, 305, 323, 324, 327, 306, 328,
+ 330, 332, 313, 315, 316, 314, 318, 317, 333, 319,
+ 330, 334, 324, 326, 323, 332, 333, 335, 328, 336,
+ 337, 327, 339, 340, 606, 341, 342, 335, 344, 336,
+ 337, 345, 334, 348, 340, 341, 350, 342, 344, 345,
+ 347, 335, 352, 336, 350, 355, 339, 356, 359, 348,
+ 347, 357, 352, 358, 359, 360, 355, 362, 363, 356,
+ 364, 365, 357, 367, 370, 369, 375, 358, 374, 377,
+
+ 592, 589, 364, 360, 374, 375, 369, 378, 370, 362,
+ 363, 382, 384, 380, 379, 378, 385, 367, 369, 365,
+ 379, 380, 377, 381, 383, 386, 387, 388, 389, 381,
+ 390, 383, 384, 382, 392, 386, 385, 397, 390, 395,
+ 396, 400, 392, 399, 387, 401, 389, 398, 402, 406,
+ 403, 388, 404, 395, 396, 397, 408, 398, 400, 399,
+ 412, 407, 404, 409, 408, 410, 402, 406, 411, 401,
+ 403, 407, 414, 409, 412, 410, 415, 423, 411, 424,
+ 428, 425, 427, 432, 429, 435, 438, 439, 436, 437,
+ 424, 414, 441, 423, 429, 427, 436, 442, 437, 439,
+
+ 415, 425, 443, 432, 428, 444, 445, 447, 443, 435,
+ 438, 442, 448, 450, 451, 452, 441, 453, 454, 455,
+ 456, 447, 451, 461, 445, 466, 471, 453, 460, 444,
+ 584, 450, 465, 460, 460, 468, 448, 478, 455, 456,
+ 465, 454, 466, 469, 452, 468, 470, 461, 473, 479,
+ 471, 480, 470, 469, 482, 483, 473, 489, 495, 478,
+ 490, 496, 498, 497, 482, 499, 483, 479, 501, 480,
+ 503, 489, 497, 490, 495, 506, 498, 507, 508, 509,
+ 510, 512, 513, 499, 496, 514, 515, 516, 517, 503,
+ 510, 512, 501, 518, 519, 509, 521, 506, 517, 507,
+
+ 513, 514, 515, 522, 523, 508, 524, 525, 526, 516,
+ 523, 527, 524, 522, 528, 529, 518, 525, 519, 527,
+ 531, 534, 521, 532, 533, 536, 537, 529, 538, 539,
+ 545, 534, 526, 554, 546, 543, 548, 547, 528, 539,
+ 545, 536, 546, 548, 537, 531, 550, 532, 533, 543,
+ 551, 552, 538, 547, 550, 557, 551, 554, 558, 559,
+ 560, 557, 561, 562, 563, 552, 560, 564, 558, 566,
+ 565, 567, 563, 568, 569, 571, 573, 567, 572, 561,
+ 569, 574, 575, 559, 565, 566, 577, 576, 579, 568,
+ 571, 564, 575, 562, 580, 572, 573, 576, 581, 582,
+
+ 583, 585, 586, 587, 580, 574, 588, 593, 590, 591,
+ 577, 585, 594, 596, 581, 582, 583, 587, 579, 591,
+ 594, 595, 597, 593, 588, 599, 586, 590, 598, 600,
+ 601, 596, 602, 603, 604, 595, 605, 607, 611, 601,
+ 602, 603, 613, 617, 597, 578, 611, 598, 570, 599,
+ 556, 600, 613, 555, 553, 607, 549, 544, 542, 541,
+ 605, 540, 535, 530, 604, 617, 620, 620, 620, 620,
+ 620, 620, 620, 620, 621, 520, 621, 621, 621, 621,
+ 622, 511, 622, 622, 505, 622, 624, 504, 624, 624,
+ 624, 624, 624, 624, 625, 502, 625, 625, 500, 625,
+
+ 627, 627, 627, 627, 627, 627, 627, 627, 628, 494,
+ 628, 629, 629, 629, 493, 492, 491, 488, 487, 486,
+ 485, 484, 481, 477, 476, 475, 474, 472, 467, 464,
+ 463, 462, 459, 458, 457, 449, 446, 440, 434, 433,
+ 431, 430, 426, 422, 421, 420, 419, 418, 417, 416,
+ 413, 405, 394, 393, 391, 376, 373, 371, 368, 366,
+ 361, 354, 353, 351, 349, 346, 343, 338, 331, 325,
+ 322, 321, 320, 311, 308, 307, 302, 301, 285, 284,
+ 283, 280, 268, 256, 254, 252, 250, 247, 246, 245,
+ 236, 233, 232, 228, 226, 225, 224, 216, 215, 212,
+
+ 211, 209, 208, 207, 206, 205, 204, 202, 201, 187,
+ 186, 185, 169, 162, 157, 155, 152, 149, 148, 144,
+ 140, 122, 96, 85, 72, 61, 52, 49, 46, 45,
+ 40, 38, 14, 8, 7, 3, 619, 619, 619, 619,
+ 619, 619, 619, 619, 619, 619, 619, 619, 619, 619,
+ 619, 619, 619, 619, 619, 619, 619, 619, 619, 619,
+ 619, 619, 619, 619, 619, 619, 619, 619, 619, 619,
+ 619, 619, 619, 619, 619, 619, 619, 619, 619, 619,
+ 619, 619, 619, 619, 619
+ } ;
+
+static yy_state_type yy_state_buf[YY_BUF_SIZE + 2], *yy_state_ptr;
+static char *yy_full_match;
+static int yy_lp;
+#define REJECT \
+{ \
+*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ \
+yy_cp = yy_full_match; /* restore poss. backed-over text */ \
+++yy_lp; \
+goto find_rule; \
+}
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+#define INITIAL 0
+/*===-- UpgradeLexer.l - Scanner for 1.9 assembly files --------*- C++ -*--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the flex scanner for LLVM 1.9 assembly languages files.
+//
+//===----------------------------------------------------------------------===*/
+#define YY_NEVER_INTERACTIVE 1
+#line 28 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+#include "UpgradeInternals.h"
+#include "llvm/Module.h"
+#include <list>
+#include "UpgradeParser.h"
+#include <cctype>
+#include <cstdlib>
+
+#define YY_INPUT(buf,result,max_size) \
+{ \
+ if (LexInput->good() && !LexInput->eof()) { \
+ LexInput->read(buf,max_size); \
+ result = LexInput->gcount(); \
+ } else {\
+ result = YY_NULL; \
+ } \
+}
+
+#define YY_NEVER_INTERACTIVE 1
+
+// Construct a token value for a non-obsolete token
+#define RET_TOK(type, Enum, sym) \
+ Upgradelval.type = Enum; \
+ return sym
+
+#define RET_TY(sym,NewTY,sign) \
+ Upgradelval.PrimType.T = NewTY; \
+ switch (sign) { \
+ case 0: Upgradelval.PrimType.S.makeSignless(); break; \
+ case 1: Upgradelval.PrimType.S.makeUnsigned(); break; \
+ case 2: Upgradelval.PrimType.S.makeSigned(); break; \
+ default: assert(0 && "Invalid sign kind"); break; \
+ }\
+ return sym
+
+namespace llvm {
+
+// TODO: All of the static identifiers are figured out by the lexer,
+// these should be hashed to reduce the lexer size
+
+// UnEscapeLexed - Run through the specified buffer and change \xx codes to the
+// appropriate character. If AllowNull is set to false, a \00 value will cause
+// an exception to be thrown.
+//
+// If AllowNull is set to true, the return value of the function points to the
+// last character of the string in memory.
+//
+char *UnEscapeLexed(char *Buffer, bool AllowNull) {
+ char *BOut = Buffer;
+ for (char *BIn = Buffer; *BIn; ) {
+ if (BIn[0] == '\\' && isxdigit(BIn[1]) && isxdigit(BIn[2])) {
+ char Tmp = BIn[3]; BIn[3] = 0; // Terminate string
+ *BOut = (char)strtol(BIn+1, 0, 16); // Convert to number
+ if (!AllowNull && !*BOut)
+ error("String literal cannot accept \\00 escape!");
+
+ BIn[3] = Tmp; // Restore character
+ BIn += 3; // Skip over handled chars
+ ++BOut;
+ } else {
+ *BOut++ = *BIn++;
+ }
+ }
+
+ return BOut;
+}
+
+// atoull - Convert an ascii string of decimal digits into the unsigned long
+// long representation... this does not have to do input error checking,
+// because we know that the input will be matched by a suitable regex...
+//
+static uint64_t atoull(const char *Buffer) {
+ uint64_t Result = 0;
+ for (; *Buffer; Buffer++) {
+ uint64_t OldRes = Result;
+ Result *= 10;
+ Result += *Buffer-'0';
+ if (Result < OldRes) // Uh, oh, overflow detected!!!
+ error("constant bigger than 64 bits detected!");
+ }
+ return Result;
+}
+
+static uint64_t HexIntToVal(const char *Buffer) {
+ uint64_t Result = 0;
+ for (; *Buffer; ++Buffer) {
+ uint64_t OldRes = Result;
+ Result *= 16;
+ char C = *Buffer;
+ if (C >= '0' && C <= '9')
+ Result += C-'0';
+ else if (C >= 'A' && C <= 'F')
+ Result += C-'A'+10;
+ else if (C >= 'a' && C <= 'f')
+ Result += C-'a'+10;
+
+ if (Result < OldRes) // Uh, oh, overflow detected!!!
+ error("constant bigger than 64 bits detected!");
+ }
+ return Result;
+}
+
+
+// HexToFP - Convert the ascii string in hexidecimal format to the floating
+// point representation of it.
+//
+static double HexToFP(const char *Buffer) {
+ // Behave nicely in the face of C TBAA rules... see:
+ // http://www.nullstone.com/htmls/category/aliastyp.htm
+ union {
+ uint64_t UI;
+ double FP;
+ } UIntToFP;
+ UIntToFP.UI = HexIntToVal(Buffer);
+
+ assert(sizeof(double) == sizeof(uint64_t) &&
+ "Data sizes incompatible on this target!");
+ return UIntToFP.FP; // Cast Hex constant to double
+}
+
+
+} // End llvm namespace
+
+using namespace llvm;
+
+/* Comments start with a ; and go till end of line */
+/* Variable(Value) identifiers start with a % sign */
+/* Label identifiers end with a colon */
+/* Quoted names can contain any character except " and \ */
+/* [PN]Integer: match positive and negative literal integer values that
+ * are preceeded by a '%' character. These represent unnamed variable slots.
+ */
+/* E[PN]Integer: match positive and negative literal integer values */
+/* FPConstant - A Floating point constant.
+ */
+/* HexFPConstant - Floating point constant represented in IEEE format as a
+ * hexadecimal number for when exponential notation is not precise enough.
+ */
+/* HexIntConstant - Hexadecimal constant generated by the CFE to avoid forcing
+ * it to deal with 64 bit numbers.
+ */
+#line 1094 "UpgradeLexer.cpp"
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap YY_PROTO(( void ));
+#else
+extern int yywrap YY_PROTO(( void ));
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+static inline void yyunput YY_PROTO(( int c, char *buf_ptr ));
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen YY_PROTO(( yyconst char * ));
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput YY_PROTO(( void ));
+#else
+static int input YY_PROTO(( void ));
+#endif
+#endif
+
+#if YY_STACK_USED
+static int yy_start_stack_ptr = 0;
+static int yy_start_stack_depth = 0;
+static int *yy_start_stack = 0;
+#ifndef YY_NO_PUSH_STATE
+static void yy_push_state YY_PROTO(( int new_state ));
+#endif
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state YY_PROTO(( void ));
+#endif
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state YY_PROTO(( void ));
+#endif
+
+#else
+#define YY_NO_PUSH_STATE 1
+#define YY_NO_POP_STATE 1
+#define YY_NO_TOP_STATE 1
+#endif
+
+#ifdef YY_MALLOC_DECL
+YY_MALLOC_DECL
+#else
+#if __STDC__
+#ifndef __cplusplus
+#include <stdlib.h>
+#endif
+#else
+/* Just try to get by without declaring the routines. This will fail
+ * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
+ * or sizeof(void*) != sizeof(int).
+ */
+#endif
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( yy_current_buffer->yy_is_interactive ) \
+ { \
+ int c = '*', n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \
+ && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" );
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL int yylex YY_PROTO(( void ))
+#endif
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ YY_USER_ACTION
+
+YY_DECL
+ {
+ register yy_state_type yy_current_state;
+ register char *yy_cp = NULL, *yy_bp = NULL;
+ register int yy_act;
+
+#line 194 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+
+
+#line 1248 "UpgradeLexer.cpp"
+
+ if ( yy_init )
+ {
+ yy_init = 0;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! yy_start )
+ yy_start = 1; /* first start state */
+
+ if ( ! yyin )
+ yyin = stdin;
+
+ if ( ! yyout )
+ yyout = stdout;
+
+ if ( ! yy_current_buffer )
+ yy_current_buffer =
+ yy_create_buffer( yyin, YY_BUF_SIZE );
+
+ yy_load_buffer_state();
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = yy_c_buf_p;
+
+ /* Support of yytext. */
+ *yy_cp = yy_hold_char;
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = yy_start;
+ yy_state_ptr = yy_state_buf;
+ *yy_state_ptr++ = yy_current_state;
+yy_match:
+ do
+ {
+ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 620 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ *yy_state_ptr++ = yy_current_state;
+ ++yy_cp;
+ }
+ while ( yy_current_state != 619 );
+
+yy_find_action:
+ yy_current_state = *--yy_state_ptr;
+ yy_lp = yy_accept[yy_current_state];
+find_rule: /* we branch to this label when backing up */
+ for ( ; ; ) /* until we find what rule we matched */
+ {
+ if ( yy_lp && yy_lp < yy_accept[yy_current_state + 1] )
+ {
+ yy_act = yy_acclist[yy_lp];
+ {
+ yy_full_match = yy_cp;
+ break;
+ }
+ }
+ --yy_cp;
+ yy_current_state = *--yy_state_ptr;
+ yy_lp = yy_accept[yy_current_state];
+ }
+
+ YY_DO_BEFORE_ACTION;
+
+ if ( yy_act != YY_END_OF_BUFFER )
+ {
+ int yyl;
+ for ( yyl = 0; yyl < yyleng; ++yyl )
+ if ( yytext[yyl] == '\n' )
+ ++yylineno;
+ }
+
+do_action: /* This label is used only to access EOF actions. */
+
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+case 1:
+YY_RULE_SETUP
+#line 196 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ /* Ignore comments for now */ }
+ YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 198 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return BEGINTOK; }
+ YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 199 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return ENDTOK; }
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 200 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return TRUETOK; }
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 201 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return FALSETOK; }
+ YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 202 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return DECLARE; }
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 203 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return GLOBAL; }
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 204 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return CONSTANT; }
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 205 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return INTERNAL; }
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 206 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return LINKONCE; }
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 207 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return WEAK; }
+ YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 208 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return APPENDING; }
+ YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 209 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return DLLIMPORT; }
+ YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 210 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return DLLEXPORT; }
+ YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 211 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return EXTERN_WEAK; }
+ YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 212 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return EXTERNAL; } /* Deprecated, turn into external */
+ YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 213 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return EXTERNAL; }
+ YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 214 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return IMPLEMENTATION; }
+ YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 215 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return ZEROINITIALIZER; }
+ YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 216 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return DOTDOTDOT; }
+ YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 217 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return UNDEF; }
+ YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 218 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return NULL_TOK; }
+ YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 219 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return TO; }
+ YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 220 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return EXCEPT; }
+ YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 221 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return NOT; } /* Deprecated, turned into XOR */
+ YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 222 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return TAIL; }
+ YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 223 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return TARGET; }
+ YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 224 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return TRIPLE; }
+ YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 225 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return DEPLIBS; }
+ YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 226 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return ENDIAN; }
+ YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 227 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return POINTERSIZE; }
+ YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 228 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return DATALAYOUT; }
+ YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 229 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return LITTLE; }
+ YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 230 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return BIG; }
+ YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 231 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return VOLATILE; }
+ YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 232 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return ALIGN; }
+ YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 233 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return SECTION; }
+ YY_BREAK
+case 38:
+YY_RULE_SETUP
+#line 234 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return MODULE; }
+ YY_BREAK
+case 39:
+YY_RULE_SETUP
+#line 235 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return ASM_TOK; }
+ YY_BREAK
+case 40:
+YY_RULE_SETUP
+#line 236 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return SIDEEFFECT; }
+ YY_BREAK
+case 41:
+YY_RULE_SETUP
+#line 238 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return CC_TOK; }
+ YY_BREAK
+case 42:
+YY_RULE_SETUP
+#line 239 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return CCC_TOK; }
+ YY_BREAK
+case 43:
+YY_RULE_SETUP
+#line 240 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return CSRETCC_TOK; }
+ YY_BREAK
+case 44:
+YY_RULE_SETUP
+#line 241 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return FASTCC_TOK; }
+ YY_BREAK
+case 45:
+YY_RULE_SETUP
+#line 242 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return COLDCC_TOK; }
+ YY_BREAK
+case 46:
+YY_RULE_SETUP
+#line 243 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return X86_STDCALLCC_TOK; }
+ YY_BREAK
+case 47:
+YY_RULE_SETUP
+#line 244 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return X86_FASTCALLCC_TOK; }
+ YY_BREAK
+case 48:
+YY_RULE_SETUP
+#line 246 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TY(SBYTE, Type::Int8Ty, 2); }
+ YY_BREAK
+case 49:
+YY_RULE_SETUP
+#line 247 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TY(UBYTE, Type::Int8Ty, 1); }
+ YY_BREAK
+case 50:
+YY_RULE_SETUP
+#line 248 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TY(UBYTE, Type::Int8Ty, 1); }
+ YY_BREAK
+case 51:
+YY_RULE_SETUP
+#line 249 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TY(SHORT, Type::Int16Ty, 2); }
+ YY_BREAK
+case 52:
+YY_RULE_SETUP
+#line 250 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TY(USHORT, Type::Int16Ty, 1); }
+ YY_BREAK
+case 53:
+YY_RULE_SETUP
+#line 251 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TY(USHORT, Type::Int16Ty, 1); }
+ YY_BREAK
+case 54:
+YY_RULE_SETUP
+#line 252 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TY(INT, Type::Int32Ty, 2); }
+ YY_BREAK
+case 55:
+YY_RULE_SETUP
+#line 253 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TY(UINT, Type::Int32Ty, 1); }
+ YY_BREAK
+case 56:
+YY_RULE_SETUP
+#line 254 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TY(UINT, Type::Int32Ty, 1); }
+ YY_BREAK
+case 57:
+YY_RULE_SETUP
+#line 255 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TY(LONG, Type::Int64Ty, 2); }
+ YY_BREAK
+case 58:
+YY_RULE_SETUP
+#line 256 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TY(ULONG, Type::Int64Ty, 1); }
+ YY_BREAK
+case 59:
+YY_RULE_SETUP
+#line 257 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TY(ULONG, Type::Int64Ty, 1); }
+ YY_BREAK
+case 60:
+YY_RULE_SETUP
+#line 258 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TY(VOID, Type::VoidTy, 0); }
+ YY_BREAK
+case 61:
+YY_RULE_SETUP
+#line 259 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TY(BOOL, Type::Int1Ty, 1); }
+ YY_BREAK
+case 62:
+YY_RULE_SETUP
+#line 260 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TY(BOOL, Type::Int1Ty, 1); }
+ YY_BREAK
+case 63:
+YY_RULE_SETUP
+#line 261 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TY(FLOAT, Type::FloatTy, 0); }
+ YY_BREAK
+case 64:
+YY_RULE_SETUP
+#line 262 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TY(DOUBLE, Type::DoubleTy,0); }
+ YY_BREAK
+case 65:
+YY_RULE_SETUP
+#line 263 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TY(LABEL, Type::LabelTy, 0); }
+ YY_BREAK
+case 66:
+YY_RULE_SETUP
+#line 264 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return TYPE; }
+ YY_BREAK
+case 67:
+YY_RULE_SETUP
+#line 265 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return OPAQUE; }
+ YY_BREAK
+case 68:
+YY_RULE_SETUP
+#line 267 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(BinaryOpVal, AddOp, ADD); }
+ YY_BREAK
+case 69:
+YY_RULE_SETUP
+#line 268 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(BinaryOpVal, SubOp, SUB); }
+ YY_BREAK
+case 70:
+YY_RULE_SETUP
+#line 269 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(BinaryOpVal, MulOp, MUL); }
+ YY_BREAK
+case 71:
+YY_RULE_SETUP
+#line 270 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(BinaryOpVal, DivOp, DIV); }
+ YY_BREAK
+case 72:
+YY_RULE_SETUP
+#line 271 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(BinaryOpVal, UDivOp, UDIV); }
+ YY_BREAK
+case 73:
+YY_RULE_SETUP
+#line 272 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(BinaryOpVal, SDivOp, SDIV); }
+ YY_BREAK
+case 74:
+YY_RULE_SETUP
+#line 273 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(BinaryOpVal, FDivOp, FDIV); }
+ YY_BREAK
+case 75:
+YY_RULE_SETUP
+#line 274 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(BinaryOpVal, RemOp, REM); }
+ YY_BREAK
+case 76:
+YY_RULE_SETUP
+#line 275 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(BinaryOpVal, URemOp, UREM); }
+ YY_BREAK
+case 77:
+YY_RULE_SETUP
+#line 276 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(BinaryOpVal, SRemOp, SREM); }
+ YY_BREAK
+case 78:
+YY_RULE_SETUP
+#line 277 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(BinaryOpVal, FRemOp, FREM); }
+ YY_BREAK
+case 79:
+YY_RULE_SETUP
+#line 278 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(BinaryOpVal, AndOp, AND); }
+ YY_BREAK
+case 80:
+YY_RULE_SETUP
+#line 279 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(BinaryOpVal, OrOp , OR ); }
+ YY_BREAK
+case 81:
+YY_RULE_SETUP
+#line 280 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(BinaryOpVal, XorOp, XOR); }
+ YY_BREAK
+case 82:
+YY_RULE_SETUP
+#line 281 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(BinaryOpVal, SetNE, SETNE); }
+ YY_BREAK
+case 83:
+YY_RULE_SETUP
+#line 282 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(BinaryOpVal, SetEQ, SETEQ); }
+ YY_BREAK
+case 84:
+YY_RULE_SETUP
+#line 283 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(BinaryOpVal, SetLT, SETLT); }
+ YY_BREAK
+case 85:
+YY_RULE_SETUP
+#line 284 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(BinaryOpVal, SetGT, SETGT); }
+ YY_BREAK
+case 86:
+YY_RULE_SETUP
+#line 285 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(BinaryOpVal, SetLE, SETLE); }
+ YY_BREAK
+case 87:
+YY_RULE_SETUP
+#line 286 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(BinaryOpVal, SetGE, SETGE); }
+ YY_BREAK
+case 88:
+YY_RULE_SETUP
+#line 287 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(BinaryOpVal, ShlOp, SHL); }
+ YY_BREAK
+case 89:
+YY_RULE_SETUP
+#line 288 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(BinaryOpVal, ShrOp, SHR); }
+ YY_BREAK
+case 90:
+YY_RULE_SETUP
+#line 289 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(BinaryOpVal, LShrOp, LSHR); }
+ YY_BREAK
+case 91:
+YY_RULE_SETUP
+#line 290 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(BinaryOpVal, AShrOp, ASHR); }
+ YY_BREAK
+case 92:
+YY_RULE_SETUP
+#line 292 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(OtherOpVal, ICmpOp, ICMP); }
+ YY_BREAK
+case 93:
+YY_RULE_SETUP
+#line 293 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(OtherOpVal, FCmpOp, FCMP); }
+ YY_BREAK
+case 94:
+YY_RULE_SETUP
+#line 295 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return EQ; }
+ YY_BREAK
+case 95:
+YY_RULE_SETUP
+#line 296 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return NE; }
+ YY_BREAK
+case 96:
+YY_RULE_SETUP
+#line 297 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return SLT; }
+ YY_BREAK
+case 97:
+YY_RULE_SETUP
+#line 298 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return SGT; }
+ YY_BREAK
+case 98:
+YY_RULE_SETUP
+#line 299 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return SLE; }
+ YY_BREAK
+case 99:
+YY_RULE_SETUP
+#line 300 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return SGE; }
+ YY_BREAK
+case 100:
+YY_RULE_SETUP
+#line 301 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return ULT; }
+ YY_BREAK
+case 101:
+YY_RULE_SETUP
+#line 302 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return UGT; }
+ YY_BREAK
+case 102:
+YY_RULE_SETUP
+#line 303 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return ULE; }
+ YY_BREAK
+case 103:
+YY_RULE_SETUP
+#line 304 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return UGE; }
+ YY_BREAK
+case 104:
+YY_RULE_SETUP
+#line 305 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return OEQ; }
+ YY_BREAK
+case 105:
+YY_RULE_SETUP
+#line 306 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return ONE; }
+ YY_BREAK
+case 106:
+YY_RULE_SETUP
+#line 307 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return OLT; }
+ YY_BREAK
+case 107:
+YY_RULE_SETUP
+#line 308 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return OGT; }
+ YY_BREAK
+case 108:
+YY_RULE_SETUP
+#line 309 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return OLE; }
+ YY_BREAK
+case 109:
+YY_RULE_SETUP
+#line 310 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return OGE; }
+ YY_BREAK
+case 110:
+YY_RULE_SETUP
+#line 311 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return ORD; }
+ YY_BREAK
+case 111:
+YY_RULE_SETUP
+#line 312 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return UNO; }
+ YY_BREAK
+case 112:
+YY_RULE_SETUP
+#line 313 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return UEQ; }
+ YY_BREAK
+case 113:
+YY_RULE_SETUP
+#line 314 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return UNE; }
+ YY_BREAK
+case 114:
+YY_RULE_SETUP
+#line 316 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(OtherOpVal, PHIOp, PHI_TOK); }
+ YY_BREAK
+case 115:
+YY_RULE_SETUP
+#line 317 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(OtherOpVal, CallOp, CALL); }
+ YY_BREAK
+case 116:
+YY_RULE_SETUP
+#line 318 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(CastOpVal, CastOp, CAST); }
+ YY_BREAK
+case 117:
+YY_RULE_SETUP
+#line 319 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(CastOpVal, TruncOp, TRUNC); }
+ YY_BREAK
+case 118:
+YY_RULE_SETUP
+#line 320 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(CastOpVal, ZExtOp , ZEXT); }
+ YY_BREAK
+case 119:
+YY_RULE_SETUP
+#line 321 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(CastOpVal, SExtOp, SEXT); }
+ YY_BREAK
+case 120:
+YY_RULE_SETUP
+#line 322 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(CastOpVal, FPTruncOp, FPTRUNC); }
+ YY_BREAK
+case 121:
+YY_RULE_SETUP
+#line 323 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(CastOpVal, FPExtOp, FPEXT); }
+ YY_BREAK
+case 122:
+YY_RULE_SETUP
+#line 324 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(CastOpVal, FPToUIOp, FPTOUI); }
+ YY_BREAK
+case 123:
+YY_RULE_SETUP
+#line 325 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(CastOpVal, FPToSIOp, FPTOSI); }
+ YY_BREAK
+case 124:
+YY_RULE_SETUP
+#line 326 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(CastOpVal, UIToFPOp, UITOFP); }
+ YY_BREAK
+case 125:
+YY_RULE_SETUP
+#line 327 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(CastOpVal, SIToFPOp, SITOFP); }
+ YY_BREAK
+case 126:
+YY_RULE_SETUP
+#line 328 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(CastOpVal, PtrToIntOp, PTRTOINT); }
+ YY_BREAK
+case 127:
+YY_RULE_SETUP
+#line 329 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(CastOpVal, IntToPtrOp, INTTOPTR); }
+ YY_BREAK
+case 128:
+YY_RULE_SETUP
+#line 330 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(CastOpVal, BitCastOp, BITCAST); }
+ YY_BREAK
+case 129:
+YY_RULE_SETUP
+#line 331 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(OtherOpVal, SelectOp, SELECT); }
+ YY_BREAK
+case 130:
+YY_RULE_SETUP
+#line 332 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return VANEXT_old; }
+ YY_BREAK
+case 131:
+YY_RULE_SETUP
+#line 333 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return VAARG_old; }
+ YY_BREAK
+case 132:
+YY_RULE_SETUP
+#line 334 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(OtherOpVal, VAArg , VAARG); }
+ YY_BREAK
+case 133:
+YY_RULE_SETUP
+#line 335 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(TermOpVal, RetOp, RET); }
+ YY_BREAK
+case 134:
+YY_RULE_SETUP
+#line 336 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(TermOpVal, BrOp, BR); }
+ YY_BREAK
+case 135:
+YY_RULE_SETUP
+#line 337 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(TermOpVal, SwitchOp, SWITCH); }
+ YY_BREAK
+case 136:
+YY_RULE_SETUP
+#line 338 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(TermOpVal, InvokeOp, INVOKE); }
+ YY_BREAK
+case 137:
+YY_RULE_SETUP
+#line 339 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return UNWIND; }
+ YY_BREAK
+case 138:
+YY_RULE_SETUP
+#line 340 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(TermOpVal, UnreachableOp, UNREACHABLE); }
+ YY_BREAK
+case 139:
+YY_RULE_SETUP
+#line 342 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(MemOpVal, MallocOp, MALLOC); }
+ YY_BREAK
+case 140:
+YY_RULE_SETUP
+#line 343 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(MemOpVal, AllocaOp, ALLOCA); }
+ YY_BREAK
+case 141:
+YY_RULE_SETUP
+#line 344 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(MemOpVal, FreeOp, FREE); }
+ YY_BREAK
+case 142:
+YY_RULE_SETUP
+#line 345 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(MemOpVal, LoadOp, LOAD); }
+ YY_BREAK
+case 143:
+YY_RULE_SETUP
+#line 346 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(MemOpVal, StoreOp, STORE); }
+ YY_BREAK
+case 144:
+YY_RULE_SETUP
+#line 347 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(MemOpVal, GetElementPtrOp, GETELEMENTPTR); }
+ YY_BREAK
+case 145:
+YY_RULE_SETUP
+#line 349 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(OtherOpVal, ExtractElementOp, EXTRACTELEMENT); }
+ YY_BREAK
+case 146:
+YY_RULE_SETUP
+#line 350 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(OtherOpVal, InsertElementOp, INSERTELEMENT); }
+ YY_BREAK
+case 147:
+YY_RULE_SETUP
+#line 351 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ RET_TOK(OtherOpVal, ShuffleVectorOp, SHUFFLEVECTOR); }
+ YY_BREAK
+case 148:
+YY_RULE_SETUP
+#line 354 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{
+ UnEscapeLexed(yytext+1);
+ Upgradelval.StrVal = strdup(yytext+1); // Skip %
+ return VAR_ID;
+ }
+ YY_BREAK
+case 149:
+YY_RULE_SETUP
+#line 359 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{
+ yytext[strlen(yytext)-1] = 0; // nuke colon
+ UnEscapeLexed(yytext);
+ Upgradelval.StrVal = strdup(yytext);
+ return LABELSTR;
+ }
+ YY_BREAK
+case 150:
+YY_RULE_SETUP
+#line 365 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{
+ yytext[strlen(yytext)-2] = 0; // nuke colon, end quote
+ UnEscapeLexed(yytext+1);
+ Upgradelval.StrVal = strdup(yytext+1);
+ return LABELSTR;
+ }
+ YY_BREAK
+case 151:
+YY_RULE_SETUP
+#line 372 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ // Note that we cannot unescape a string constant here! The
+ // string constant might contain a \00 which would not be
+ // understood by the string stuff. It is valid to make a
+ // [sbyte] c"Hello World\00" constant, for example.
+ //
+ yytext[strlen(yytext)-1] = 0; // nuke end quote
+ Upgradelval.StrVal = strdup(yytext+1); // Nuke start quote
+ return STRINGCONSTANT;
+ }
+ YY_BREAK
+case 152:
+YY_RULE_SETUP
+#line 383 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ Upgradelval.UInt64Val = atoull(yytext); return EUINT64VAL; }
+ YY_BREAK
+case 153:
+YY_RULE_SETUP
+#line 384 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{
+ uint64_t Val = atoull(yytext+1);
+ // +1: we have bigger negative range
+ if (Val > (uint64_t)INT64_MAX+1)
+ error("Constant too large for signed 64 bits!");
+ Upgradelval.SInt64Val = -Val;
+ return ESINT64VAL;
+ }
+ YY_BREAK
+case 154:
+YY_RULE_SETUP
+#line 392 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{
+ Upgradelval.UInt64Val = HexIntToVal(yytext+3);
+ return yytext[0] == 's' ? ESINT64VAL : EUINT64VAL;
+ }
+ YY_BREAK
+case 155:
+YY_RULE_SETUP
+#line 397 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{
+ uint64_t Val = atoull(yytext+1);
+ if ((unsigned)Val != Val)
+ error("Invalid value number (too large)!");
+ Upgradelval.UIntVal = unsigned(Val);
+ return UINTVAL;
+ }
+ YY_BREAK
+case 156:
+YY_RULE_SETUP
+#line 404 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{
+ uint64_t Val = atoull(yytext+2);
+ // +1: we have bigger negative range
+ if (Val > (uint64_t)INT32_MAX+1)
+ error("Constant too large for signed 32 bits!");
+ Upgradelval.SIntVal = (int)-Val;
+ return SINTVAL;
+ }
+ YY_BREAK
+case 157:
+YY_RULE_SETUP
+#line 413 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ Upgradelval.FPVal = atof(yytext); return FPVAL; }
+ YY_BREAK
+case 158:
+YY_RULE_SETUP
+#line 414 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ Upgradelval.FPVal = HexToFP(yytext); return FPVAL; }
+ YY_BREAK
+case YY_STATE_EOF(INITIAL):
+#line 416 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{
+ /* Make sure to free the internal buffers for flex when we are
+ * done reading our input!
+ */
+ yy_delete_buffer(YY_CURRENT_BUFFER);
+ return EOF;
+ }
+ YY_BREAK
+case 159:
+YY_RULE_SETUP
+#line 424 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ /* Ignore whitespace */ }
+ YY_BREAK
+case 160:
+YY_RULE_SETUP
+#line 425 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+{ return yytext[0]; }
+ YY_BREAK
+case 161:
+YY_RULE_SETUP
+#line 427 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+YY_FATAL_ERROR( "flex scanner jammed" );
+ YY_BREAK
+#line 2199 "UpgradeLexer.cpp"
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = yy_hold_char;
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * yylex(). If so, then we have to assure
+ * consistency between yy_current_buffer and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ yy_n_chars = yy_current_buffer->yy_n_chars;
+ yy_current_buffer->yy_input_file = yyin;
+ yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++yy_c_buf_p;
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = yy_c_buf_p;
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer() )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ yy_did_buffer_switch_on_eof = 0;
+
+ if ( yywrap() )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p =
+ yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ yy_c_buf_p =
+ &yy_current_buffer->yy_ch_buf[yy_n_chars];
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+ } /* end of yylex */
+
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+
+static int yy_get_next_buffer()
+ {
+ register char *dest = yy_current_buffer->yy_ch_buf;
+ register char *source = yytext_ptr;
+ register int number_to_move, i;
+ int ret_val;
+
+ if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( yy_current_buffer->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ yy_current_buffer->yy_n_chars = yy_n_chars = 0;
+
+ else
+ {
+ int num_to_read =
+ yy_current_buffer->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+#ifdef YY_USES_REJECT
+ YY_FATAL_ERROR(
+"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
+#else
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = yy_current_buffer;
+
+ int yy_c_buf_p_offset =
+ (int) (yy_c_buf_p - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ yy_flex_realloc( (void *) b->yy_ch_buf,
+ b->yy_buf_size + 2 );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = 0;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = yy_current_buffer->yy_buf_size -
+ number_to_move - 1;
+#endif
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
+ yy_n_chars, num_to_read );
+
+ yy_current_buffer->yy_n_chars = yy_n_chars;
+ }
+
+ if ( yy_n_chars == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart( yyin );
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ yy_current_buffer->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ yy_n_chars += number_to_move;
+ yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+ yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+ yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
+
+ return ret_val;
+ }
+
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+static yy_state_type yy_get_previous_state()
+ {
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+
+ yy_current_state = yy_start;
+ yy_state_ptr = yy_state_buf;
+ *yy_state_ptr++ = yy_current_state;
+
+ for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
+ {
+ register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 620 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ *yy_state_ptr++ = yy_current_state;
+ }
+
+ return yy_current_state;
+ }
+
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+
+#ifdef YY_USE_PROTOS
+static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
+#else
+static yy_state_type yy_try_NUL_trans( yy_current_state )
+yy_state_type yy_current_state;
+#endif
+ {
+ register int yy_is_jam;
+
+ register YY_CHAR yy_c = 1;
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 620 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_is_jam = (yy_current_state == 619);
+ if ( ! yy_is_jam )
+ *yy_state_ptr++ = yy_current_state;
+
+ return yy_is_jam ? 0 : yy_current_state;
+ }
+
+
+#ifndef YY_NO_UNPUT
+#ifdef YY_USE_PROTOS
+static inline void yyunput( int c, register char *yy_bp )
+#else
+static inline void yyunput( c, yy_bp )
+int c;
+register char *yy_bp;
+#endif
+ {
+ register char *yy_cp = yy_c_buf_p;
+
+ /* undo effects of setting up yytext */
+ *yy_cp = yy_hold_char;
+
+ if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ register int number_to_move = yy_n_chars + 2;
+ register char *dest = &yy_current_buffer->yy_ch_buf[
+ yy_current_buffer->yy_buf_size + 2];
+ register char *source =
+ &yy_current_buffer->yy_ch_buf[number_to_move];
+
+ while ( source > yy_current_buffer->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ yy_current_buffer->yy_n_chars =
+ yy_n_chars = yy_current_buffer->yy_buf_size;
+
+ if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--yy_cp = (char) c;
+
+ if ( c == '\n' )
+ --yylineno;
+
+ yytext_ptr = yy_bp;
+ yy_hold_char = *yy_cp;
+ yy_c_buf_p = yy_cp;
+ }
+#endif /* ifndef YY_NO_UNPUT */
+
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput()
+#else
+static int input()
+#endif
+ {
+ int c;
+
+ *yy_c_buf_p = yy_hold_char;
+
+ if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+ /* This was really a NUL. */
+ *yy_c_buf_p = '\0';
+
+ else
+ { /* need more input */
+ int offset = yy_c_buf_p - yytext_ptr;
+ ++yy_c_buf_p;
+
+ switch ( yy_get_next_buffer() )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ yyrestart( yyin );
+
+ /* fall through */
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( yywrap() )
+ return EOF;
+
+ if ( ! yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p = yytext_ptr + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */
+ *yy_c_buf_p = '\0'; /* preserve yytext */
+ yy_hold_char = *++yy_c_buf_p;
+
+ if ( c == '\n' )
+ ++yylineno;
+
+ return c;
+ }
+#endif /* YY_NO_INPUT */
+
+#ifdef YY_USE_PROTOS
+void yyrestart( FILE *input_file )
+#else
+void yyrestart( input_file )
+FILE *input_file;
+#endif
+ {
+ if ( ! yy_current_buffer )
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
+
+ yy_init_buffer( yy_current_buffer, input_file );
+ yy_load_buffer_state();
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+#else
+void yy_switch_to_buffer( new_buffer )
+YY_BUFFER_STATE new_buffer;
+#endif
+ {
+ if ( yy_current_buffer == new_buffer )
+ return;
+
+ if ( yy_current_buffer )
+ {
+ /* Flush out information for old buffer. */
+ *yy_c_buf_p = yy_hold_char;
+ yy_current_buffer->yy_buf_pos = yy_c_buf_p;
+ yy_current_buffer->yy_n_chars = yy_n_chars;
+ }
+
+ yy_current_buffer = new_buffer;
+ yy_load_buffer_state();
+
+ /* We don't actually know whether we did this switch during
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ yy_did_buffer_switch_on_eof = 1;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_load_buffer_state( void )
+#else
+void yy_load_buffer_state()
+#endif
+ {
+ yy_n_chars = yy_current_buffer->yy_n_chars;
+ yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
+ yyin = yy_current_buffer->yy_input_file;
+ yy_hold_char = *yy_c_buf_p;
+ }
+
+
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
+#else
+YY_BUFFER_STATE yy_create_buffer( file, size )
+FILE *file;
+int size;
+#endif
+ {
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer( b, file );
+
+ return b;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_delete_buffer( YY_BUFFER_STATE b )
+#else
+void yy_delete_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+ {
+ if ( ! b )
+ return;
+
+ if ( b == yy_current_buffer )
+ yy_current_buffer = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ yy_flex_free( (void *) b->yy_ch_buf );
+
+ yy_flex_free( (void *) b );
+ }
+
+
+
+#ifdef YY_USE_PROTOS
+void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
+#else
+void yy_init_buffer( b, file )
+YY_BUFFER_STATE b;
+FILE *file;
+#endif
+
+
+ {
+ yy_flush_buffer( b );
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+#if YY_ALWAYS_INTERACTIVE
+ b->yy_is_interactive = 1;
+#else
+#if YY_NEVER_INTERACTIVE
+ b->yy_is_interactive = 0;
+#else
+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+#endif
+#endif
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_flush_buffer( YY_BUFFER_STATE b )
+#else
+void yy_flush_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+
+ {
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == yy_current_buffer )
+ yy_load_buffer_state();
+ }
+
+
+#ifndef YY_NO_SCAN_BUFFER
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )
+#else
+YY_BUFFER_STATE yy_scan_buffer( base, size )
+char *base;
+yy_size_t size;
+#endif
+ {
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer( b );
+
+ return b;
+ }
+#endif
+
+
+#ifndef YY_NO_SCAN_STRING
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )
+#else
+YY_BUFFER_STATE yy_scan_string( yy_str )
+yyconst char *yy_str;
+#endif
+ {
+ int len;
+ for ( len = 0; yy_str[len]; ++len )
+ ;
+
+ return yy_scan_bytes( yy_str, len );
+ }
+#endif
+
+
+#ifndef YY_NO_SCAN_BYTES
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )
+#else
+YY_BUFFER_STATE yy_scan_bytes( bytes, len )
+yyconst char *bytes;
+int len;
+#endif
+ {
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = len + 2;
+ buf = (char *) yy_flex_alloc( n );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+ for ( i = 0; i < len; ++i )
+ buf[i] = bytes[i];
+
+ buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer( buf, n );
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+ }
+#endif
+
+
+#ifndef YY_NO_PUSH_STATE
+#ifdef YY_USE_PROTOS
+static void yy_push_state( int new_state )
+#else
+static void yy_push_state( new_state )
+int new_state;
+#endif
+ {
+ if ( yy_start_stack_ptr >= yy_start_stack_depth )
+ {
+ yy_size_t new_size;
+
+ yy_start_stack_depth += YY_START_STACK_INCR;
+ new_size = yy_start_stack_depth * sizeof( int );
+
+ if ( ! yy_start_stack )
+ yy_start_stack = (int *) yy_flex_alloc( new_size );
+
+ else
+ yy_start_stack = (int *) yy_flex_realloc(
+ (void *) yy_start_stack, new_size );
+
+ if ( ! yy_start_stack )
+ YY_FATAL_ERROR(
+ "out of memory expanding start-condition stack" );
+ }
+
+ yy_start_stack[yy_start_stack_ptr++] = YY_START;
+
+ BEGIN(new_state);
+ }
+#endif
+
+
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state()
+ {
+ if ( --yy_start_stack_ptr < 0 )
+ YY_FATAL_ERROR( "start-condition stack underflow" );
+
+ BEGIN(yy_start_stack[yy_start_stack_ptr]);
+ }
+#endif
+
+
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state()
+ {
+ return yy_start_stack[yy_start_stack_ptr - 1];
+ }
+#endif
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+#ifdef YY_USE_PROTOS
+static void yy_fatal_error( yyconst char msg[] )
+#else
+static void yy_fatal_error( msg )
+char msg[];
+#endif
+ {
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+ }
+
+
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ yytext[yyleng] = yy_hold_char; \
+ yy_c_buf_p = yytext + n; \
+ yy_hold_char = *yy_c_buf_p; \
+ *yy_c_buf_p = '\0'; \
+ yyleng = n; \
+ } \
+ while ( 0 )
+
+
+/* Internal utility routines. */
+
+#ifndef yytext_ptr
+#ifdef YY_USE_PROTOS
+static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )
+#else
+static void yy_flex_strncpy( s1, s2, n )
+char *s1;
+yyconst char *s2;
+int n;
+#endif
+ {
+ register int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+ }
+#endif
+
+#ifdef YY_NEED_STRLEN
+#ifdef YY_USE_PROTOS
+static int yy_flex_strlen( yyconst char *s )
+#else
+static int yy_flex_strlen( s )
+yyconst char *s;
+#endif
+ {
+ register int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+ }
+#endif
+
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_alloc( yy_size_t size )
+#else
+static void *yy_flex_alloc( size )
+yy_size_t size;
+#endif
+ {
+ return (void *) malloc( size );
+ }
+
+#ifdef YY_USE_PROTOS
+static inline void *yy_flex_realloc( void *ptr, yy_size_t size )
+#else
+static inline void *yy_flex_realloc( ptr, size )
+void *ptr;
+yy_size_t size;
+#endif
+ {
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+ }
+
+#ifdef YY_USE_PROTOS
+static void yy_flex_free( void *ptr )
+#else
+static void yy_flex_free( ptr )
+void *ptr;
+#endif
+ {
+ free( ptr );
+ }
+
+#if YY_MAIN
+int main()
+ {
+ yylex();
+ return 0;
+ }
+#endif
+#line 427 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeLexer.l"
+
diff --git a/tools/llvm-upgrade/UpgradeLexer.l b/tools/llvm-upgrade/UpgradeLexer.l
new file mode 100644
index 0000000..300cf5c
--- /dev/null
+++ b/tools/llvm-upgrade/UpgradeLexer.l
@@ -0,0 +1,427 @@
+/*===-- UpgradeLexer.l - Scanner for 1.9 assembly files --------*- C++ -*--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the flex scanner for LLVM 1.9 assembly languages files.
+//
+//===----------------------------------------------------------------------===*/
+
+%option prefix="Upgrade"
+%option yylineno
+%option nostdinit
+%option never-interactive
+%option batch
+%option noyywrap
+%option nodefault
+%option 8bit
+%option outfile="UpgradeLexer.cpp"
+%option ecs
+%option noreject
+%option noyymore
+
+%{
+#include "UpgradeInternals.h"
+#include "llvm/Module.h"
+#include <list>
+#include "UpgradeParser.h"
+#include <cctype>
+#include <cstdlib>
+
+#define YY_INPUT(buf,result,max_size) \
+{ \
+ if (LexInput->good() && !LexInput->eof()) { \
+ LexInput->read(buf,max_size); \
+ result = LexInput->gcount(); \
+ } else {\
+ result = YY_NULL; \
+ } \
+}
+
+#define YY_NEVER_INTERACTIVE 1
+
+// Construct a token value for a non-obsolete token
+#define RET_TOK(type, Enum, sym) \
+ Upgradelval.type = Enum; \
+ return sym
+
+#define RET_TY(sym,NewTY,sign) \
+ Upgradelval.PrimType.T = NewTY; \
+ switch (sign) { \
+ case 0: Upgradelval.PrimType.S.makeSignless(); break; \
+ case 1: Upgradelval.PrimType.S.makeUnsigned(); break; \
+ case 2: Upgradelval.PrimType.S.makeSigned(); break; \
+ default: assert(0 && "Invalid sign kind"); break; \
+ }\
+ return sym
+
+namespace llvm {
+
+// TODO: All of the static identifiers are figured out by the lexer,
+// these should be hashed to reduce the lexer size
+
+// UnEscapeLexed - Run through the specified buffer and change \xx codes to the
+// appropriate character. If AllowNull is set to false, a \00 value will cause
+// an exception to be thrown.
+//
+// If AllowNull is set to true, the return value of the function points to the
+// last character of the string in memory.
+//
+char *UnEscapeLexed(char *Buffer, bool AllowNull) {
+ char *BOut = Buffer;
+ for (char *BIn = Buffer; *BIn; ) {
+ if (BIn[0] == '\\' && isxdigit(BIn[1]) && isxdigit(BIn[2])) {
+ char Tmp = BIn[3]; BIn[3] = 0; // Terminate string
+ *BOut = (char)strtol(BIn+1, 0, 16); // Convert to number
+ if (!AllowNull && !*BOut)
+ error("String literal cannot accept \\00 escape!");
+
+ BIn[3] = Tmp; // Restore character
+ BIn += 3; // Skip over handled chars
+ ++BOut;
+ } else {
+ *BOut++ = *BIn++;
+ }
+ }
+
+ return BOut;
+}
+
+// atoull - Convert an ascii string of decimal digits into the unsigned long
+// long representation... this does not have to do input error checking,
+// because we know that the input will be matched by a suitable regex...
+//
+static uint64_t atoull(const char *Buffer) {
+ uint64_t Result = 0;
+ for (; *Buffer; Buffer++) {
+ uint64_t OldRes = Result;
+ Result *= 10;
+ Result += *Buffer-'0';
+ if (Result < OldRes) // Uh, oh, overflow detected!!!
+ error("constant bigger than 64 bits detected!");
+ }
+ return Result;
+}
+
+static uint64_t HexIntToVal(const char *Buffer) {
+ uint64_t Result = 0;
+ for (; *Buffer; ++Buffer) {
+ uint64_t OldRes = Result;
+ Result *= 16;
+ char C = *Buffer;
+ if (C >= '0' && C <= '9')
+ Result += C-'0';
+ else if (C >= 'A' && C <= 'F')
+ Result += C-'A'+10;
+ else if (C >= 'a' && C <= 'f')
+ Result += C-'a'+10;
+
+ if (Result < OldRes) // Uh, oh, overflow detected!!!
+ error("constant bigger than 64 bits detected!");
+ }
+ return Result;
+}
+
+
+// HexToFP - Convert the ascii string in hexidecimal format to the floating
+// point representation of it.
+//
+static double HexToFP(const char *Buffer) {
+ // Behave nicely in the face of C TBAA rules... see:
+ // http://www.nullstone.com/htmls/category/aliastyp.htm
+ union {
+ uint64_t UI;
+ double FP;
+ } UIntToFP;
+ UIntToFP.UI = HexIntToVal(Buffer);
+
+ assert(sizeof(double) == sizeof(uint64_t) &&
+ "Data sizes incompatible on this target!");
+ return UIntToFP.FP; // Cast Hex constant to double
+}
+
+
+} // End llvm namespace
+
+using namespace llvm;
+
+%}
+
+
+
+/* Comments start with a ; and go till end of line */
+Comment ;.*
+
+/* Variable(Value) identifiers start with a % sign */
+VarID [%@][-a-zA-Z$._][-a-zA-Z$._0-9]*
+
+/* Label identifiers end with a colon */
+Label [-a-zA-Z$._0-9]+:
+QuoteLabel \"[^\"]+\":
+
+/* Quoted names can contain any character except " and \ */
+StringConstant @?\"[^\"]*\"
+
+
+/* [PN]Integer: match positive and negative literal integer values that
+ * are preceeded by a '%' character. These represent unnamed variable slots.
+ */
+EPInteger %[0-9]+
+ENInteger %-[0-9]+
+
+
+/* E[PN]Integer: match positive and negative literal integer values */
+PInteger [0-9]+
+NInteger -[0-9]+
+
+/* FPConstant - A Floating point constant.
+ */
+FPConstant [-+]?[0-9]+[.][0-9]*([eE][-+]?[0-9]+)?
+
+/* HexFPConstant - Floating point constant represented in IEEE format as a
+ * hexadecimal number for when exponential notation is not precise enough.
+ */
+HexFPConstant 0x[0-9A-Fa-f]+
+
+/* HexIntConstant - Hexadecimal constant generated by the CFE to avoid forcing
+ * it to deal with 64 bit numbers.
+ */
+HexIntConstant [us]0x[0-9A-Fa-f]+
+%%
+
+{Comment} { /* Ignore comments for now */ }
+
+begin { return BEGINTOK; }
+end { return ENDTOK; }
+true { return TRUETOK; }
+false { return FALSETOK; }
+declare { return DECLARE; }
+global { return GLOBAL; }
+constant { return CONSTANT; }
+internal { return INTERNAL; }
+linkonce { return LINKONCE; }
+weak { return WEAK; }
+appending { return APPENDING; }
+dllimport { return DLLIMPORT; }
+dllexport { return DLLEXPORT; }
+extern_weak { return EXTERN_WEAK; }
+uninitialized { return EXTERNAL; } /* Deprecated, turn into external */
+external { return EXTERNAL; }
+implementation { return IMPLEMENTATION; }
+zeroinitializer { return ZEROINITIALIZER; }
+\.\.\. { return DOTDOTDOT; }
+undef { return UNDEF; }
+null { return NULL_TOK; }
+to { return TO; }
+except { return EXCEPT; }
+not { return NOT; } /* Deprecated, turned into XOR */
+tail { return TAIL; }
+target { return TARGET; }
+triple { return TRIPLE; }
+deplibs { return DEPLIBS; }
+endian { return ENDIAN; }
+pointersize { return POINTERSIZE; }
+datalayout { return DATALAYOUT; }
+little { return LITTLE; }
+big { return BIG; }
+volatile { return VOLATILE; }
+align { return ALIGN; }
+section { return SECTION; }
+module { return MODULE; }
+asm { return ASM_TOK; }
+sideeffect { return SIDEEFFECT; }
+
+cc { return CC_TOK; }
+ccc { return CCC_TOK; }
+csretcc { return CSRETCC_TOK; }
+fastcc { return FASTCC_TOK; }
+coldcc { return COLDCC_TOK; }
+x86_stdcallcc { return X86_STDCALLCC_TOK; }
+x86_fastcallcc { return X86_FASTCALLCC_TOK; }
+
+sbyte { RET_TY(SBYTE, Type::Int8Ty, 2); }
+ubyte { RET_TY(UBYTE, Type::Int8Ty, 1); }
+i8 { RET_TY(UBYTE, Type::Int8Ty, 1); }
+short { RET_TY(SHORT, Type::Int16Ty, 2); }
+ushort { RET_TY(USHORT, Type::Int16Ty, 1); }
+i16 { RET_TY(USHORT, Type::Int16Ty, 1); }
+int { RET_TY(INT, Type::Int32Ty, 2); }
+uint { RET_TY(UINT, Type::Int32Ty, 1); }
+i32 { RET_TY(UINT, Type::Int32Ty, 1); }
+long { RET_TY(LONG, Type::Int64Ty, 2); }
+ulong { RET_TY(ULONG, Type::Int64Ty, 1); }
+i64 { RET_TY(ULONG, Type::Int64Ty, 1); }
+void { RET_TY(VOID, Type::VoidTy, 0); }
+bool { RET_TY(BOOL, Type::Int1Ty, 1); }
+i1 { RET_TY(BOOL, Type::Int1Ty, 1); }
+float { RET_TY(FLOAT, Type::FloatTy, 0); }
+double { RET_TY(DOUBLE, Type::DoubleTy,0); }
+label { RET_TY(LABEL, Type::LabelTy, 0); }
+type { return TYPE; }
+opaque { return OPAQUE; }
+
+add { RET_TOK(BinaryOpVal, AddOp, ADD); }
+sub { RET_TOK(BinaryOpVal, SubOp, SUB); }
+mul { RET_TOK(BinaryOpVal, MulOp, MUL); }
+div { RET_TOK(BinaryOpVal, DivOp, DIV); }
+udiv { RET_TOK(BinaryOpVal, UDivOp, UDIV); }
+sdiv { RET_TOK(BinaryOpVal, SDivOp, SDIV); }
+fdiv { RET_TOK(BinaryOpVal, FDivOp, FDIV); }
+rem { RET_TOK(BinaryOpVal, RemOp, REM); }
+urem { RET_TOK(BinaryOpVal, URemOp, UREM); }
+srem { RET_TOK(BinaryOpVal, SRemOp, SREM); }
+frem { RET_TOK(BinaryOpVal, FRemOp, FREM); }
+and { RET_TOK(BinaryOpVal, AndOp, AND); }
+or { RET_TOK(BinaryOpVal, OrOp , OR ); }
+xor { RET_TOK(BinaryOpVal, XorOp, XOR); }
+setne { RET_TOK(BinaryOpVal, SetNE, SETNE); }
+seteq { RET_TOK(BinaryOpVal, SetEQ, SETEQ); }
+setlt { RET_TOK(BinaryOpVal, SetLT, SETLT); }
+setgt { RET_TOK(BinaryOpVal, SetGT, SETGT); }
+setle { RET_TOK(BinaryOpVal, SetLE, SETLE); }
+setge { RET_TOK(BinaryOpVal, SetGE, SETGE); }
+shl { RET_TOK(BinaryOpVal, ShlOp, SHL); }
+shr { RET_TOK(BinaryOpVal, ShrOp, SHR); }
+lshr { RET_TOK(BinaryOpVal, LShrOp, LSHR); }
+ashr { RET_TOK(BinaryOpVal, AShrOp, ASHR); }
+
+icmp { RET_TOK(OtherOpVal, ICmpOp, ICMP); }
+fcmp { RET_TOK(OtherOpVal, FCmpOp, FCMP); }
+
+eq { return EQ; }
+ne { return NE; }
+slt { return SLT; }
+sgt { return SGT; }
+sle { return SLE; }
+sge { return SGE; }
+ult { return ULT; }
+ugt { return UGT; }
+ule { return ULE; }
+uge { return UGE; }
+oeq { return OEQ; }
+one { return ONE; }
+olt { return OLT; }
+ogt { return OGT; }
+ole { return OLE; }
+oge { return OGE; }
+ord { return ORD; }
+uno { return UNO; }
+ueq { return UEQ; }
+une { return UNE; }
+
+phi { RET_TOK(OtherOpVal, PHIOp, PHI_TOK); }
+call { RET_TOK(OtherOpVal, CallOp, CALL); }
+cast { RET_TOK(CastOpVal, CastOp, CAST); }
+trunc { RET_TOK(CastOpVal, TruncOp, TRUNC); }
+zext { RET_TOK(CastOpVal, ZExtOp , ZEXT); }
+sext { RET_TOK(CastOpVal, SExtOp, SEXT); }
+fptrunc { RET_TOK(CastOpVal, FPTruncOp, FPTRUNC); }
+fpext { RET_TOK(CastOpVal, FPExtOp, FPEXT); }
+fptoui { RET_TOK(CastOpVal, FPToUIOp, FPTOUI); }
+fptosi { RET_TOK(CastOpVal, FPToSIOp, FPTOSI); }
+uitofp { RET_TOK(CastOpVal, UIToFPOp, UITOFP); }
+sitofp { RET_TOK(CastOpVal, SIToFPOp, SITOFP); }
+ptrtoint { RET_TOK(CastOpVal, PtrToIntOp, PTRTOINT); }
+inttoptr { RET_TOK(CastOpVal, IntToPtrOp, INTTOPTR); }
+bitcast { RET_TOK(CastOpVal, BitCastOp, BITCAST); }
+select { RET_TOK(OtherOpVal, SelectOp, SELECT); }
+vanext { return VANEXT_old; }
+vaarg { return VAARG_old; }
+va_arg { RET_TOK(OtherOpVal, VAArg , VAARG); }
+ret { RET_TOK(TermOpVal, RetOp, RET); }
+br { RET_TOK(TermOpVal, BrOp, BR); }
+switch { RET_TOK(TermOpVal, SwitchOp, SWITCH); }
+invoke { RET_TOK(TermOpVal, InvokeOp, INVOKE); }
+unwind { return UNWIND; }
+unreachable { RET_TOK(TermOpVal, UnreachableOp, UNREACHABLE); }
+
+malloc { RET_TOK(MemOpVal, MallocOp, MALLOC); }
+alloca { RET_TOK(MemOpVal, AllocaOp, ALLOCA); }
+free { RET_TOK(MemOpVal, FreeOp, FREE); }
+load { RET_TOK(MemOpVal, LoadOp, LOAD); }
+store { RET_TOK(MemOpVal, StoreOp, STORE); }
+getelementptr { RET_TOK(MemOpVal, GetElementPtrOp, GETELEMENTPTR); }
+
+extractelement { RET_TOK(OtherOpVal, ExtractElementOp, EXTRACTELEMENT); }
+insertelement { RET_TOK(OtherOpVal, InsertElementOp, INSERTELEMENT); }
+shufflevector { RET_TOK(OtherOpVal, ShuffleVectorOp, SHUFFLEVECTOR); }
+
+
+{VarID} {
+ UnEscapeLexed(yytext+1);
+ Upgradelval.StrVal = strdup(yytext+1); // Skip %
+ return VAR_ID;
+ }
+{Label} {
+ yytext[strlen(yytext)-1] = 0; // nuke colon
+ UnEscapeLexed(yytext);
+ Upgradelval.StrVal = strdup(yytext);
+ return LABELSTR;
+ }
+{QuoteLabel} {
+ yytext[strlen(yytext)-2] = 0; // nuke colon, end quote
+ UnEscapeLexed(yytext+1);
+ Upgradelval.StrVal = strdup(yytext+1);
+ return LABELSTR;
+ }
+
+{StringConstant} { // Note that we cannot unescape a string constant here! The
+ // string constant might contain a \00 which would not be
+ // understood by the string stuff. It is valid to make a
+ // [sbyte] c"Hello World\00" constant, for example.
+ //
+ yytext[strlen(yytext)-1] = 0; // nuke end quote
+ Upgradelval.StrVal = strdup(yytext+1); // Nuke start quote
+ return STRINGCONSTANT;
+ }
+
+
+{PInteger} { Upgradelval.UInt64Val = atoull(yytext); return EUINT64VAL; }
+{NInteger} {
+ uint64_t Val = atoull(yytext+1);
+ // +1: we have bigger negative range
+ if (Val > (uint64_t)INT64_MAX+1)
+ error("Constant too large for signed 64 bits!");
+ Upgradelval.SInt64Val = -Val;
+ return ESINT64VAL;
+ }
+{HexIntConstant} {
+ Upgradelval.UInt64Val = HexIntToVal(yytext+3);
+ return yytext[0] == 's' ? ESINT64VAL : EUINT64VAL;
+ }
+
+{EPInteger} {
+ uint64_t Val = atoull(yytext+1);
+ if ((unsigned)Val != Val)
+ error("Invalid value number (too large)!");
+ Upgradelval.UIntVal = unsigned(Val);
+ return UINTVAL;
+ }
+{ENInteger} {
+ uint64_t Val = atoull(yytext+2);
+ // +1: we have bigger negative range
+ if (Val > (uint64_t)INT32_MAX+1)
+ error("Constant too large for signed 32 bits!");
+ Upgradelval.SIntVal = (int)-Val;
+ return SINTVAL;
+ }
+
+{FPConstant} { Upgradelval.FPVal = atof(yytext); return FPVAL; }
+{HexFPConstant} { Upgradelval.FPVal = HexToFP(yytext); return FPVAL; }
+
+<<EOF>> {
+ /* Make sure to free the internal buffers for flex when we are
+ * done reading our input!
+ */
+ yy_delete_buffer(YY_CURRENT_BUFFER);
+ return EOF;
+ }
+
+[ \r\t\n] { /* Ignore whitespace */ }
+. { return yytext[0]; }
+
+%%
diff --git a/tools/llvm-upgrade/UpgradeLexer.l.cvs b/tools/llvm-upgrade/UpgradeLexer.l.cvs
new file mode 100644
index 0000000..300cf5c
--- /dev/null
+++ b/tools/llvm-upgrade/UpgradeLexer.l.cvs
@@ -0,0 +1,427 @@
+/*===-- UpgradeLexer.l - Scanner for 1.9 assembly files --------*- C++ -*--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the flex scanner for LLVM 1.9 assembly languages files.
+//
+//===----------------------------------------------------------------------===*/
+
+%option prefix="Upgrade"
+%option yylineno
+%option nostdinit
+%option never-interactive
+%option batch
+%option noyywrap
+%option nodefault
+%option 8bit
+%option outfile="UpgradeLexer.cpp"
+%option ecs
+%option noreject
+%option noyymore
+
+%{
+#include "UpgradeInternals.h"
+#include "llvm/Module.h"
+#include <list>
+#include "UpgradeParser.h"
+#include <cctype>
+#include <cstdlib>
+
+#define YY_INPUT(buf,result,max_size) \
+{ \
+ if (LexInput->good() && !LexInput->eof()) { \
+ LexInput->read(buf,max_size); \
+ result = LexInput->gcount(); \
+ } else {\
+ result = YY_NULL; \
+ } \
+}
+
+#define YY_NEVER_INTERACTIVE 1
+
+// Construct a token value for a non-obsolete token
+#define RET_TOK(type, Enum, sym) \
+ Upgradelval.type = Enum; \
+ return sym
+
+#define RET_TY(sym,NewTY,sign) \
+ Upgradelval.PrimType.T = NewTY; \
+ switch (sign) { \
+ case 0: Upgradelval.PrimType.S.makeSignless(); break; \
+ case 1: Upgradelval.PrimType.S.makeUnsigned(); break; \
+ case 2: Upgradelval.PrimType.S.makeSigned(); break; \
+ default: assert(0 && "Invalid sign kind"); break; \
+ }\
+ return sym
+
+namespace llvm {
+
+// TODO: All of the static identifiers are figured out by the lexer,
+// these should be hashed to reduce the lexer size
+
+// UnEscapeLexed - Run through the specified buffer and change \xx codes to the
+// appropriate character. If AllowNull is set to false, a \00 value will cause
+// an exception to be thrown.
+//
+// If AllowNull is set to true, the return value of the function points to the
+// last character of the string in memory.
+//
+char *UnEscapeLexed(char *Buffer, bool AllowNull) {
+ char *BOut = Buffer;
+ for (char *BIn = Buffer; *BIn; ) {
+ if (BIn[0] == '\\' && isxdigit(BIn[1]) && isxdigit(BIn[2])) {
+ char Tmp = BIn[3]; BIn[3] = 0; // Terminate string
+ *BOut = (char)strtol(BIn+1, 0, 16); // Convert to number
+ if (!AllowNull && !*BOut)
+ error("String literal cannot accept \\00 escape!");
+
+ BIn[3] = Tmp; // Restore character
+ BIn += 3; // Skip over handled chars
+ ++BOut;
+ } else {
+ *BOut++ = *BIn++;
+ }
+ }
+
+ return BOut;
+}
+
+// atoull - Convert an ascii string of decimal digits into the unsigned long
+// long representation... this does not have to do input error checking,
+// because we know that the input will be matched by a suitable regex...
+//
+static uint64_t atoull(const char *Buffer) {
+ uint64_t Result = 0;
+ for (; *Buffer; Buffer++) {
+ uint64_t OldRes = Result;
+ Result *= 10;
+ Result += *Buffer-'0';
+ if (Result < OldRes) // Uh, oh, overflow detected!!!
+ error("constant bigger than 64 bits detected!");
+ }
+ return Result;
+}
+
+static uint64_t HexIntToVal(const char *Buffer) {
+ uint64_t Result = 0;
+ for (; *Buffer; ++Buffer) {
+ uint64_t OldRes = Result;
+ Result *= 16;
+ char C = *Buffer;
+ if (C >= '0' && C <= '9')
+ Result += C-'0';
+ else if (C >= 'A' && C <= 'F')
+ Result += C-'A'+10;
+ else if (C >= 'a' && C <= 'f')
+ Result += C-'a'+10;
+
+ if (Result < OldRes) // Uh, oh, overflow detected!!!
+ error("constant bigger than 64 bits detected!");
+ }
+ return Result;
+}
+
+
+// HexToFP - Convert the ascii string in hexidecimal format to the floating
+// point representation of it.
+//
+static double HexToFP(const char *Buffer) {
+ // Behave nicely in the face of C TBAA rules... see:
+ // http://www.nullstone.com/htmls/category/aliastyp.htm
+ union {
+ uint64_t UI;
+ double FP;
+ } UIntToFP;
+ UIntToFP.UI = HexIntToVal(Buffer);
+
+ assert(sizeof(double) == sizeof(uint64_t) &&
+ "Data sizes incompatible on this target!");
+ return UIntToFP.FP; // Cast Hex constant to double
+}
+
+
+} // End llvm namespace
+
+using namespace llvm;
+
+%}
+
+
+
+/* Comments start with a ; and go till end of line */
+Comment ;.*
+
+/* Variable(Value) identifiers start with a % sign */
+VarID [%@][-a-zA-Z$._][-a-zA-Z$._0-9]*
+
+/* Label identifiers end with a colon */
+Label [-a-zA-Z$._0-9]+:
+QuoteLabel \"[^\"]+\":
+
+/* Quoted names can contain any character except " and \ */
+StringConstant @?\"[^\"]*\"
+
+
+/* [PN]Integer: match positive and negative literal integer values that
+ * are preceeded by a '%' character. These represent unnamed variable slots.
+ */
+EPInteger %[0-9]+
+ENInteger %-[0-9]+
+
+
+/* E[PN]Integer: match positive and negative literal integer values */
+PInteger [0-9]+
+NInteger -[0-9]+
+
+/* FPConstant - A Floating point constant.
+ */
+FPConstant [-+]?[0-9]+[.][0-9]*([eE][-+]?[0-9]+)?
+
+/* HexFPConstant - Floating point constant represented in IEEE format as a
+ * hexadecimal number for when exponential notation is not precise enough.
+ */
+HexFPConstant 0x[0-9A-Fa-f]+
+
+/* HexIntConstant - Hexadecimal constant generated by the CFE to avoid forcing
+ * it to deal with 64 bit numbers.
+ */
+HexIntConstant [us]0x[0-9A-Fa-f]+
+%%
+
+{Comment} { /* Ignore comments for now */ }
+
+begin { return BEGINTOK; }
+end { return ENDTOK; }
+true { return TRUETOK; }
+false { return FALSETOK; }
+declare { return DECLARE; }
+global { return GLOBAL; }
+constant { return CONSTANT; }
+internal { return INTERNAL; }
+linkonce { return LINKONCE; }
+weak { return WEAK; }
+appending { return APPENDING; }
+dllimport { return DLLIMPORT; }
+dllexport { return DLLEXPORT; }
+extern_weak { return EXTERN_WEAK; }
+uninitialized { return EXTERNAL; } /* Deprecated, turn into external */
+external { return EXTERNAL; }
+implementation { return IMPLEMENTATION; }
+zeroinitializer { return ZEROINITIALIZER; }
+\.\.\. { return DOTDOTDOT; }
+undef { return UNDEF; }
+null { return NULL_TOK; }
+to { return TO; }
+except { return EXCEPT; }
+not { return NOT; } /* Deprecated, turned into XOR */
+tail { return TAIL; }
+target { return TARGET; }
+triple { return TRIPLE; }
+deplibs { return DEPLIBS; }
+endian { return ENDIAN; }
+pointersize { return POINTERSIZE; }
+datalayout { return DATALAYOUT; }
+little { return LITTLE; }
+big { return BIG; }
+volatile { return VOLATILE; }
+align { return ALIGN; }
+section { return SECTION; }
+module { return MODULE; }
+asm { return ASM_TOK; }
+sideeffect { return SIDEEFFECT; }
+
+cc { return CC_TOK; }
+ccc { return CCC_TOK; }
+csretcc { return CSRETCC_TOK; }
+fastcc { return FASTCC_TOK; }
+coldcc { return COLDCC_TOK; }
+x86_stdcallcc { return X86_STDCALLCC_TOK; }
+x86_fastcallcc { return X86_FASTCALLCC_TOK; }
+
+sbyte { RET_TY(SBYTE, Type::Int8Ty, 2); }
+ubyte { RET_TY(UBYTE, Type::Int8Ty, 1); }
+i8 { RET_TY(UBYTE, Type::Int8Ty, 1); }
+short { RET_TY(SHORT, Type::Int16Ty, 2); }
+ushort { RET_TY(USHORT, Type::Int16Ty, 1); }
+i16 { RET_TY(USHORT, Type::Int16Ty, 1); }
+int { RET_TY(INT, Type::Int32Ty, 2); }
+uint { RET_TY(UINT, Type::Int32Ty, 1); }
+i32 { RET_TY(UINT, Type::Int32Ty, 1); }
+long { RET_TY(LONG, Type::Int64Ty, 2); }
+ulong { RET_TY(ULONG, Type::Int64Ty, 1); }
+i64 { RET_TY(ULONG, Type::Int64Ty, 1); }
+void { RET_TY(VOID, Type::VoidTy, 0); }
+bool { RET_TY(BOOL, Type::Int1Ty, 1); }
+i1 { RET_TY(BOOL, Type::Int1Ty, 1); }
+float { RET_TY(FLOAT, Type::FloatTy, 0); }
+double { RET_TY(DOUBLE, Type::DoubleTy,0); }
+label { RET_TY(LABEL, Type::LabelTy, 0); }
+type { return TYPE; }
+opaque { return OPAQUE; }
+
+add { RET_TOK(BinaryOpVal, AddOp, ADD); }
+sub { RET_TOK(BinaryOpVal, SubOp, SUB); }
+mul { RET_TOK(BinaryOpVal, MulOp, MUL); }
+div { RET_TOK(BinaryOpVal, DivOp, DIV); }
+udiv { RET_TOK(BinaryOpVal, UDivOp, UDIV); }
+sdiv { RET_TOK(BinaryOpVal, SDivOp, SDIV); }
+fdiv { RET_TOK(BinaryOpVal, FDivOp, FDIV); }
+rem { RET_TOK(BinaryOpVal, RemOp, REM); }
+urem { RET_TOK(BinaryOpVal, URemOp, UREM); }
+srem { RET_TOK(BinaryOpVal, SRemOp, SREM); }
+frem { RET_TOK(BinaryOpVal, FRemOp, FREM); }
+and { RET_TOK(BinaryOpVal, AndOp, AND); }
+or { RET_TOK(BinaryOpVal, OrOp , OR ); }
+xor { RET_TOK(BinaryOpVal, XorOp, XOR); }
+setne { RET_TOK(BinaryOpVal, SetNE, SETNE); }
+seteq { RET_TOK(BinaryOpVal, SetEQ, SETEQ); }
+setlt { RET_TOK(BinaryOpVal, SetLT, SETLT); }
+setgt { RET_TOK(BinaryOpVal, SetGT, SETGT); }
+setle { RET_TOK(BinaryOpVal, SetLE, SETLE); }
+setge { RET_TOK(BinaryOpVal, SetGE, SETGE); }
+shl { RET_TOK(BinaryOpVal, ShlOp, SHL); }
+shr { RET_TOK(BinaryOpVal, ShrOp, SHR); }
+lshr { RET_TOK(BinaryOpVal, LShrOp, LSHR); }
+ashr { RET_TOK(BinaryOpVal, AShrOp, ASHR); }
+
+icmp { RET_TOK(OtherOpVal, ICmpOp, ICMP); }
+fcmp { RET_TOK(OtherOpVal, FCmpOp, FCMP); }
+
+eq { return EQ; }
+ne { return NE; }
+slt { return SLT; }
+sgt { return SGT; }
+sle { return SLE; }
+sge { return SGE; }
+ult { return ULT; }
+ugt { return UGT; }
+ule { return ULE; }
+uge { return UGE; }
+oeq { return OEQ; }
+one { return ONE; }
+olt { return OLT; }
+ogt { return OGT; }
+ole { return OLE; }
+oge { return OGE; }
+ord { return ORD; }
+uno { return UNO; }
+ueq { return UEQ; }
+une { return UNE; }
+
+phi { RET_TOK(OtherOpVal, PHIOp, PHI_TOK); }
+call { RET_TOK(OtherOpVal, CallOp, CALL); }
+cast { RET_TOK(CastOpVal, CastOp, CAST); }
+trunc { RET_TOK(CastOpVal, TruncOp, TRUNC); }
+zext { RET_TOK(CastOpVal, ZExtOp , ZEXT); }
+sext { RET_TOK(CastOpVal, SExtOp, SEXT); }
+fptrunc { RET_TOK(CastOpVal, FPTruncOp, FPTRUNC); }
+fpext { RET_TOK(CastOpVal, FPExtOp, FPEXT); }
+fptoui { RET_TOK(CastOpVal, FPToUIOp, FPTOUI); }
+fptosi { RET_TOK(CastOpVal, FPToSIOp, FPTOSI); }
+uitofp { RET_TOK(CastOpVal, UIToFPOp, UITOFP); }
+sitofp { RET_TOK(CastOpVal, SIToFPOp, SITOFP); }
+ptrtoint { RET_TOK(CastOpVal, PtrToIntOp, PTRTOINT); }
+inttoptr { RET_TOK(CastOpVal, IntToPtrOp, INTTOPTR); }
+bitcast { RET_TOK(CastOpVal, BitCastOp, BITCAST); }
+select { RET_TOK(OtherOpVal, SelectOp, SELECT); }
+vanext { return VANEXT_old; }
+vaarg { return VAARG_old; }
+va_arg { RET_TOK(OtherOpVal, VAArg , VAARG); }
+ret { RET_TOK(TermOpVal, RetOp, RET); }
+br { RET_TOK(TermOpVal, BrOp, BR); }
+switch { RET_TOK(TermOpVal, SwitchOp, SWITCH); }
+invoke { RET_TOK(TermOpVal, InvokeOp, INVOKE); }
+unwind { return UNWIND; }
+unreachable { RET_TOK(TermOpVal, UnreachableOp, UNREACHABLE); }
+
+malloc { RET_TOK(MemOpVal, MallocOp, MALLOC); }
+alloca { RET_TOK(MemOpVal, AllocaOp, ALLOCA); }
+free { RET_TOK(MemOpVal, FreeOp, FREE); }
+load { RET_TOK(MemOpVal, LoadOp, LOAD); }
+store { RET_TOK(MemOpVal, StoreOp, STORE); }
+getelementptr { RET_TOK(MemOpVal, GetElementPtrOp, GETELEMENTPTR); }
+
+extractelement { RET_TOK(OtherOpVal, ExtractElementOp, EXTRACTELEMENT); }
+insertelement { RET_TOK(OtherOpVal, InsertElementOp, INSERTELEMENT); }
+shufflevector { RET_TOK(OtherOpVal, ShuffleVectorOp, SHUFFLEVECTOR); }
+
+
+{VarID} {
+ UnEscapeLexed(yytext+1);
+ Upgradelval.StrVal = strdup(yytext+1); // Skip %
+ return VAR_ID;
+ }
+{Label} {
+ yytext[strlen(yytext)-1] = 0; // nuke colon
+ UnEscapeLexed(yytext);
+ Upgradelval.StrVal = strdup(yytext);
+ return LABELSTR;
+ }
+{QuoteLabel} {
+ yytext[strlen(yytext)-2] = 0; // nuke colon, end quote
+ UnEscapeLexed(yytext+1);
+ Upgradelval.StrVal = strdup(yytext+1);
+ return LABELSTR;
+ }
+
+{StringConstant} { // Note that we cannot unescape a string constant here! The
+ // string constant might contain a \00 which would not be
+ // understood by the string stuff. It is valid to make a
+ // [sbyte] c"Hello World\00" constant, for example.
+ //
+ yytext[strlen(yytext)-1] = 0; // nuke end quote
+ Upgradelval.StrVal = strdup(yytext+1); // Nuke start quote
+ return STRINGCONSTANT;
+ }
+
+
+{PInteger} { Upgradelval.UInt64Val = atoull(yytext); return EUINT64VAL; }
+{NInteger} {
+ uint64_t Val = atoull(yytext+1);
+ // +1: we have bigger negative range
+ if (Val > (uint64_t)INT64_MAX+1)
+ error("Constant too large for signed 64 bits!");
+ Upgradelval.SInt64Val = -Val;
+ return ESINT64VAL;
+ }
+{HexIntConstant} {
+ Upgradelval.UInt64Val = HexIntToVal(yytext+3);
+ return yytext[0] == 's' ? ESINT64VAL : EUINT64VAL;
+ }
+
+{EPInteger} {
+ uint64_t Val = atoull(yytext+1);
+ if ((unsigned)Val != Val)
+ error("Invalid value number (too large)!");
+ Upgradelval.UIntVal = unsigned(Val);
+ return UINTVAL;
+ }
+{ENInteger} {
+ uint64_t Val = atoull(yytext+2);
+ // +1: we have bigger negative range
+ if (Val > (uint64_t)INT32_MAX+1)
+ error("Constant too large for signed 32 bits!");
+ Upgradelval.SIntVal = (int)-Val;
+ return SINTVAL;
+ }
+
+{FPConstant} { Upgradelval.FPVal = atof(yytext); return FPVAL; }
+{HexFPConstant} { Upgradelval.FPVal = HexToFP(yytext); return FPVAL; }
+
+<<EOF>> {
+ /* Make sure to free the internal buffers for flex when we are
+ * done reading our input!
+ */
+ yy_delete_buffer(YY_CURRENT_BUFFER);
+ return EOF;
+ }
+
+[ \r\t\n] { /* Ignore whitespace */ }
+. { return yytext[0]; }
+
+%%
diff --git a/tools/llvm-upgrade/UpgradeParser.cpp.cvs b/tools/llvm-upgrade/UpgradeParser.cpp.cvs
new file mode 100644
index 0000000..577d94d
--- /dev/null
+++ b/tools/llvm-upgrade/UpgradeParser.cpp.cvs
@@ -0,0 +1,6944 @@
+/* A Bison parser, made by GNU Bison 2.1. */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+/* As a special exception, when this file is copied by Bison into a
+ Bison output file, you may use that output file without restriction.
+ This special exception was added by the Free Software Foundation
+ in version 1.24 of Bison. */
+
+/* Written by Richard Stallman by simplifying the original so called
+ ``semantic'' parser. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Bison version. */
+#define YYBISON_VERSION "2.1"
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 0
+
+/* Using locations. */
+#define YYLSP_NEEDED 0
+
+/* Substitute the variable and function names. */
+#define yyparse Upgradeparse
+#define yylex Upgradelex
+#define yyerror Upgradeerror
+#define yylval Upgradelval
+#define yychar Upgradechar
+#define yydebug Upgradedebug
+#define yynerrs Upgradenerrs
+
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ ESINT64VAL = 258,
+ EUINT64VAL = 259,
+ SINTVAL = 260,
+ UINTVAL = 261,
+ FPVAL = 262,
+ VOID = 263,
+ BOOL = 264,
+ SBYTE = 265,
+ UBYTE = 266,
+ SHORT = 267,
+ USHORT = 268,
+ INT = 269,
+ UINT = 270,
+ LONG = 271,
+ ULONG = 272,
+ FLOAT = 273,
+ DOUBLE = 274,
+ TYPE = 275,
+ LABEL = 276,
+ VAR_ID = 277,
+ LABELSTR = 278,
+ STRINGCONSTANT = 279,
+ IMPLEMENTATION = 280,
+ ZEROINITIALIZER = 281,
+ TRUETOK = 282,
+ FALSETOK = 283,
+ BEGINTOK = 284,
+ ENDTOK = 285,
+ DECLARE = 286,
+ GLOBAL = 287,
+ CONSTANT = 288,
+ SECTION = 289,
+ VOLATILE = 290,
+ TO = 291,
+ DOTDOTDOT = 292,
+ NULL_TOK = 293,
+ UNDEF = 294,
+ CONST = 295,
+ INTERNAL = 296,
+ LINKONCE = 297,
+ WEAK = 298,
+ APPENDING = 299,
+ DLLIMPORT = 300,
+ DLLEXPORT = 301,
+ EXTERN_WEAK = 302,
+ OPAQUE = 303,
+ NOT = 304,
+ EXTERNAL = 305,
+ TARGET = 306,
+ TRIPLE = 307,
+ ENDIAN = 308,
+ POINTERSIZE = 309,
+ LITTLE = 310,
+ BIG = 311,
+ ALIGN = 312,
+ DEPLIBS = 313,
+ CALL = 314,
+ TAIL = 315,
+ ASM_TOK = 316,
+ MODULE = 317,
+ SIDEEFFECT = 318,
+ CC_TOK = 319,
+ CCC_TOK = 320,
+ CSRETCC_TOK = 321,
+ FASTCC_TOK = 322,
+ COLDCC_TOK = 323,
+ X86_STDCALLCC_TOK = 324,
+ X86_FASTCALLCC_TOK = 325,
+ DATALAYOUT = 326,
+ RET = 327,
+ BR = 328,
+ SWITCH = 329,
+ INVOKE = 330,
+ UNREACHABLE = 331,
+ UNWIND = 332,
+ EXCEPT = 333,
+ ADD = 334,
+ SUB = 335,
+ MUL = 336,
+ DIV = 337,
+ UDIV = 338,
+ SDIV = 339,
+ FDIV = 340,
+ REM = 341,
+ UREM = 342,
+ SREM = 343,
+ FREM = 344,
+ AND = 345,
+ OR = 346,
+ XOR = 347,
+ SHL = 348,
+ SHR = 349,
+ ASHR = 350,
+ LSHR = 351,
+ SETLE = 352,
+ SETGE = 353,
+ SETLT = 354,
+ SETGT = 355,
+ SETEQ = 356,
+ SETNE = 357,
+ ICMP = 358,
+ FCMP = 359,
+ MALLOC = 360,
+ ALLOCA = 361,
+ FREE = 362,
+ LOAD = 363,
+ STORE = 364,
+ GETELEMENTPTR = 365,
+ PHI_TOK = 366,
+ SELECT = 367,
+ VAARG = 368,
+ EXTRACTELEMENT = 369,
+ INSERTELEMENT = 370,
+ SHUFFLEVECTOR = 371,
+ VAARG_old = 372,
+ VANEXT_old = 373,
+ EQ = 374,
+ NE = 375,
+ SLT = 376,
+ SGT = 377,
+ SLE = 378,
+ SGE = 379,
+ ULT = 380,
+ UGT = 381,
+ ULE = 382,
+ UGE = 383,
+ OEQ = 384,
+ ONE = 385,
+ OLT = 386,
+ OGT = 387,
+ OLE = 388,
+ OGE = 389,
+ ORD = 390,
+ UNO = 391,
+ UEQ = 392,
+ UNE = 393,
+ CAST = 394,
+ TRUNC = 395,
+ ZEXT = 396,
+ SEXT = 397,
+ FPTRUNC = 398,
+ FPEXT = 399,
+ FPTOUI = 400,
+ FPTOSI = 401,
+ UITOFP = 402,
+ SITOFP = 403,
+ PTRTOINT = 404,
+ INTTOPTR = 405,
+ BITCAST = 406
+ };
+#endif
+/* Tokens. */
+#define ESINT64VAL 258
+#define EUINT64VAL 259
+#define SINTVAL 260
+#define UINTVAL 261
+#define FPVAL 262
+#define VOID 263
+#define BOOL 264
+#define SBYTE 265
+#define UBYTE 266
+#define SHORT 267
+#define USHORT 268
+#define INT 269
+#define UINT 270
+#define LONG 271
+#define ULONG 272
+#define FLOAT 273
+#define DOUBLE 274
+#define TYPE 275
+#define LABEL 276
+#define VAR_ID 277
+#define LABELSTR 278
+#define STRINGCONSTANT 279
+#define IMPLEMENTATION 280
+#define ZEROINITIALIZER 281
+#define TRUETOK 282
+#define FALSETOK 283
+#define BEGINTOK 284
+#define ENDTOK 285
+#define DECLARE 286
+#define GLOBAL 287
+#define CONSTANT 288
+#define SECTION 289
+#define VOLATILE 290
+#define TO 291
+#define DOTDOTDOT 292
+#define NULL_TOK 293
+#define UNDEF 294
+#define CONST 295
+#define INTERNAL 296
+#define LINKONCE 297
+#define WEAK 298
+#define APPENDING 299
+#define DLLIMPORT 300
+#define DLLEXPORT 301
+#define EXTERN_WEAK 302
+#define OPAQUE 303
+#define NOT 304
+#define EXTERNAL 305
+#define TARGET 306
+#define TRIPLE 307
+#define ENDIAN 308
+#define POINTERSIZE 309
+#define LITTLE 310
+#define BIG 311
+#define ALIGN 312
+#define DEPLIBS 313
+#define CALL 314
+#define TAIL 315
+#define ASM_TOK 316
+#define MODULE 317
+#define SIDEEFFECT 318
+#define CC_TOK 319
+#define CCC_TOK 320
+#define CSRETCC_TOK 321
+#define FASTCC_TOK 322
+#define COLDCC_TOK 323
+#define X86_STDCALLCC_TOK 324
+#define X86_FASTCALLCC_TOK 325
+#define DATALAYOUT 326
+#define RET 327
+#define BR 328
+#define SWITCH 329
+#define INVOKE 330
+#define UNREACHABLE 331
+#define UNWIND 332
+#define EXCEPT 333
+#define ADD 334
+#define SUB 335
+#define MUL 336
+#define DIV 337
+#define UDIV 338
+#define SDIV 339
+#define FDIV 340
+#define REM 341
+#define UREM 342
+#define SREM 343
+#define FREM 344
+#define AND 345
+#define OR 346
+#define XOR 347
+#define SHL 348
+#define SHR 349
+#define ASHR 350
+#define LSHR 351
+#define SETLE 352
+#define SETGE 353
+#define SETLT 354
+#define SETGT 355
+#define SETEQ 356
+#define SETNE 357
+#define ICMP 358
+#define FCMP 359
+#define MALLOC 360
+#define ALLOCA 361
+#define FREE 362
+#define LOAD 363
+#define STORE 364
+#define GETELEMENTPTR 365
+#define PHI_TOK 366
+#define SELECT 367
+#define VAARG 368
+#define EXTRACTELEMENT 369
+#define INSERTELEMENT 370
+#define SHUFFLEVECTOR 371
+#define VAARG_old 372
+#define VANEXT_old 373
+#define EQ 374
+#define NE 375
+#define SLT 376
+#define SGT 377
+#define SLE 378
+#define SGE 379
+#define ULT 380
+#define UGT 381
+#define ULE 382
+#define UGE 383
+#define OEQ 384
+#define ONE 385
+#define OLT 386
+#define OGT 387
+#define OLE 388
+#define OGE 389
+#define ORD 390
+#define UNO 391
+#define UEQ 392
+#define UNE 393
+#define CAST 394
+#define TRUNC 395
+#define ZEXT 396
+#define SEXT 397
+#define FPTRUNC 398
+#define FPEXT 399
+#define FPTOUI 400
+#define FPTOSI 401
+#define UITOFP 402
+#define SITOFP 403
+#define PTRTOINT 404
+#define INTTOPTR 405
+#define BITCAST 406
+
+
+
+
+/* Copy the first part of user declarations. */
+#line 14 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+
+#include "UpgradeInternals.h"
+#include "llvm/CallingConv.h"
+#include "llvm/InlineAsm.h"
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+#include "llvm/ParameterAttributes.h"
+#include "llvm/ValueSymbolTable.h"
+#include "llvm/Support/GetElementPtrTypeIterator.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/MathExtras.h"
+#include <algorithm>
+#include <iostream>
+#include <map>
+#include <list>
+#include <utility>
+
+// DEBUG_UPREFS - Define this symbol if you want to enable debugging output
+// relating to upreferences in the input stream.
+//
+//#define DEBUG_UPREFS 1
+#ifdef DEBUG_UPREFS
+#define UR_OUT(X) std::cerr << X
+#else
+#define UR_OUT(X)
+#endif
+
+#define YYERROR_VERBOSE 1
+#define YYINCLUDED_STDLIB_H
+#define YYDEBUG 1
+
+int yylex();
+int yyparse();
+
+int yyerror(const char*);
+static void warning(const std::string& WarningMsg);
+
+namespace llvm {
+
+std::istream* LexInput;
+static std::string CurFilename;
+
+// This bool controls whether attributes are ever added to function declarations
+// definitions and calls.
+static bool AddAttributes = false;
+
+static Module *ParserResult;
+static bool ObsoleteVarArgs;
+static bool NewVarArgs;
+static BasicBlock *CurBB;
+static GlobalVariable *CurGV;
+static unsigned lastCallingConv;
+
+// This contains info used when building the body of a function. It is
+// destroyed when the function is completed.
+//
+typedef std::vector<Value *> ValueList; // Numbered defs
+
+typedef std::pair<std::string,TypeInfo> RenameMapKey;
+typedef std::map<RenameMapKey,std::string> RenameMapType;
+
+static void
+ResolveDefinitions(std::map<const Type *,ValueList> &LateResolvers,
+ std::map<const Type *,ValueList> *FutureLateResolvers = 0);
+
+static struct PerModuleInfo {
+ Module *CurrentModule;
+ std::map<const Type *, ValueList> Values; // Module level numbered definitions
+ std::map<const Type *,ValueList> LateResolveValues;
+ std::vector<PATypeHolder> Types;
+ std::vector<Signedness> TypeSigns;
+ std::map<std::string,Signedness> NamedTypeSigns;
+ std::map<std::string,Signedness> NamedValueSigns;
+ std::map<ValID, PATypeHolder> LateResolveTypes;
+ static Module::Endianness Endian;
+ static Module::PointerSize PointerSize;
+ RenameMapType RenameMap;
+
+ /// PlaceHolderInfo - When temporary placeholder objects are created, remember
+ /// how they were referenced and on which line of the input they came from so
+ /// that we can resolve them later and print error messages as appropriate.
+ std::map<Value*, std::pair<ValID, int> > PlaceHolderInfo;
+
+ // GlobalRefs - This maintains a mapping between <Type, ValID>'s and forward
+ // references to global values. Global values may be referenced before they
+ // are defined, and if so, the temporary object that they represent is held
+ // here. This is used for forward references of GlobalValues.
+ //
+ typedef std::map<std::pair<const PointerType *, ValID>, GlobalValue*>
+ GlobalRefsType;
+ GlobalRefsType GlobalRefs;
+
+ void ModuleDone() {
+ // If we could not resolve some functions at function compilation time
+ // (calls to functions before they are defined), resolve them now... Types
+ // are resolved when the constant pool has been completely parsed.
+ //
+ ResolveDefinitions(LateResolveValues);
+
+ // Check to make sure that all global value forward references have been
+ // resolved!
+ //
+ if (!GlobalRefs.empty()) {
+ std::string UndefinedReferences = "Unresolved global references exist:\n";
+
+ for (GlobalRefsType::iterator I = GlobalRefs.begin(), E =GlobalRefs.end();
+ I != E; ++I) {
+ UndefinedReferences += " " + I->first.first->getDescription() + " " +
+ I->first.second.getName() + "\n";
+ }
+ error(UndefinedReferences);
+ return;
+ }
+
+ if (CurrentModule->getDataLayout().empty()) {
+ std::string dataLayout;
+ if (Endian != Module::AnyEndianness)
+ dataLayout.append(Endian == Module::BigEndian ? "E" : "e");
+ if (PointerSize != Module::AnyPointerSize) {
+ if (!dataLayout.empty())
+ dataLayout += "-";
+ dataLayout.append(PointerSize == Module::Pointer64 ?
+ "p:64:64" : "p:32:32");
+ }
+ CurrentModule->setDataLayout(dataLayout);
+ }
+
+ Values.clear(); // Clear out function local definitions
+ Types.clear();
+ TypeSigns.clear();
+ NamedTypeSigns.clear();
+ NamedValueSigns.clear();
+ CurrentModule = 0;
+ }
+
+ // GetForwardRefForGlobal - Check to see if there is a forward reference
+ // for this global. If so, remove it from the GlobalRefs map and return it.
+ // If not, just return null.
+ GlobalValue *GetForwardRefForGlobal(const PointerType *PTy, ValID ID) {
+ // Check to see if there is a forward reference to this global variable...
+ // if there is, eliminate it and patch the reference to use the new def'n.
+ GlobalRefsType::iterator I = GlobalRefs.find(std::make_pair(PTy, ID));
+ GlobalValue *Ret = 0;
+ if (I != GlobalRefs.end()) {
+ Ret = I->second;
+ GlobalRefs.erase(I);
+ }
+ return Ret;
+ }
+ void setEndianness(Module::Endianness E) { Endian = E; }
+ void setPointerSize(Module::PointerSize sz) { PointerSize = sz; }
+} CurModule;
+
+Module::Endianness PerModuleInfo::Endian = Module::AnyEndianness;
+Module::PointerSize PerModuleInfo::PointerSize = Module::AnyPointerSize;
+
+static struct PerFunctionInfo {
+ Function *CurrentFunction; // Pointer to current function being created
+
+ std::map<const Type*, ValueList> Values; // Keep track of #'d definitions
+ std::map<const Type*, ValueList> LateResolveValues;
+ bool isDeclare; // Is this function a forward declararation?
+ GlobalValue::LinkageTypes Linkage;// Linkage for forward declaration.
+
+ /// BBForwardRefs - When we see forward references to basic blocks, keep
+ /// track of them here.
+ std::map<BasicBlock*, std::pair<ValID, int> > BBForwardRefs;
+ std::vector<BasicBlock*> NumberedBlocks;
+ RenameMapType RenameMap;
+ unsigned NextBBNum;
+
+ inline PerFunctionInfo() {
+ CurrentFunction = 0;
+ isDeclare = false;
+ Linkage = GlobalValue::ExternalLinkage;
+ }
+
+ inline void FunctionStart(Function *M) {
+ CurrentFunction = M;
+ NextBBNum = 0;
+ }
+
+ void FunctionDone() {
+ NumberedBlocks.clear();
+
+ // Any forward referenced blocks left?
+ if (!BBForwardRefs.empty()) {
+ error("Undefined reference to label " +
+ BBForwardRefs.begin()->first->getName());
+ return;
+ }
+
+ // Resolve all forward references now.
+ ResolveDefinitions(LateResolveValues, &CurModule.LateResolveValues);
+
+ Values.clear(); // Clear out function local definitions
+ RenameMap.clear();
+ CurrentFunction = 0;
+ isDeclare = false;
+ Linkage = GlobalValue::ExternalLinkage;
+ }
+} CurFun; // Info for the current function...
+
+static bool inFunctionScope() { return CurFun.CurrentFunction != 0; }
+
+/// This function is just a utility to make a Key value for the rename map.
+/// The Key is a combination of the name, type, Signedness of the original
+/// value (global/function). This just constructs the key and ensures that
+/// named Signedness values are resolved to the actual Signedness.
+/// @brief Make a key for the RenameMaps
+static RenameMapKey makeRenameMapKey(const std::string &Name, const Type* Ty,
+ const Signedness &Sign) {
+ TypeInfo TI;
+ TI.T = Ty;
+ if (Sign.isNamed())
+ // Don't allow Named Signedness nodes because they won't match. The actual
+ // Signedness must be looked up in the NamedTypeSigns map.
+ TI.S.copy(CurModule.NamedTypeSigns[Sign.getName()]);
+ else
+ TI.S.copy(Sign);
+ return std::make_pair(Name, TI);
+}
+
+
+//===----------------------------------------------------------------------===//
+// Code to handle definitions of all the types
+//===----------------------------------------------------------------------===//
+
+static int InsertValue(Value *V,
+ std::map<const Type*,ValueList> &ValueTab = CurFun.Values) {
+ if (V->hasName()) return -1; // Is this a numbered definition?
+
+ // Yes, insert the value into the value table...
+ ValueList &List = ValueTab[V->getType()];
+ List.push_back(V);
+ return List.size()-1;
+}
+
+static const Type *getType(const ValID &D, bool DoNotImprovise = false) {
+ switch (D.Type) {
+ case ValID::NumberVal: // Is it a numbered definition?
+ // Module constants occupy the lowest numbered slots...
+ if ((unsigned)D.Num < CurModule.Types.size()) {
+ return CurModule.Types[(unsigned)D.Num];
+ }
+ break;
+ case ValID::NameVal: // Is it a named definition?
+ if (const Type *N = CurModule.CurrentModule->getTypeByName(D.Name)) {
+ return N;
+ }
+ break;
+ default:
+ error("Internal parser error: Invalid symbol type reference");
+ return 0;
+ }
+
+ // If we reached here, we referenced either a symbol that we don't know about
+ // or an id number that hasn't been read yet. We may be referencing something
+ // forward, so just create an entry to be resolved later and get to it...
+ //
+ if (DoNotImprovise) return 0; // Do we just want a null to be returned?
+
+ if (inFunctionScope()) {
+ if (D.Type == ValID::NameVal) {
+ error("Reference to an undefined type: '" + D.getName() + "'");
+ return 0;
+ } else {
+ error("Reference to an undefined type: #" + itostr(D.Num));
+ return 0;
+ }
+ }
+
+ std::map<ValID, PATypeHolder>::iterator I =CurModule.LateResolveTypes.find(D);
+ if (I != CurModule.LateResolveTypes.end())
+ return I->second;
+
+ Type *Typ = OpaqueType::get();
+ CurModule.LateResolveTypes.insert(std::make_pair(D, Typ));
+ return Typ;
+}
+
+/// This is like the getType method except that instead of looking up the type
+/// for a given ID, it looks up that type's sign.
+/// @brief Get the signedness of a referenced type
+static Signedness getTypeSign(const ValID &D) {
+ switch (D.Type) {
+ case ValID::NumberVal: // Is it a numbered definition?
+ // Module constants occupy the lowest numbered slots...
+ if ((unsigned)D.Num < CurModule.TypeSigns.size()) {
+ return CurModule.TypeSigns[(unsigned)D.Num];
+ }
+ break;
+ case ValID::NameVal: { // Is it a named definition?
+ std::map<std::string,Signedness>::const_iterator I =
+ CurModule.NamedTypeSigns.find(D.Name);
+ if (I != CurModule.NamedTypeSigns.end())
+ return I->second;
+ // Perhaps its a named forward .. just cache the name
+ Signedness S;
+ S.makeNamed(D.Name);
+ return S;
+ }
+ default:
+ break;
+ }
+ // If we don't find it, its signless
+ Signedness S;
+ S.makeSignless();
+ return S;
+}
+
+/// This function is analagous to getElementType in LLVM. It provides the same
+/// function except that it looks up the Signedness instead of the type. This is
+/// used when processing GEP instructions that need to extract the type of an
+/// indexed struct/array/ptr member.
+/// @brief Look up an element's sign.
+static Signedness getElementSign(const ValueInfo& VI,
+ const std::vector<Value*> &Indices) {
+ const Type *Ptr = VI.V->getType();
+ assert(isa<PointerType>(Ptr) && "Need pointer type");
+
+ unsigned CurIdx = 0;
+ Signedness S(VI.S);
+ while (const CompositeType *CT = dyn_cast<CompositeType>(Ptr)) {
+ if (CurIdx == Indices.size())
+ break;
+
+ Value *Index = Indices[CurIdx++];
+ assert(!isa<PointerType>(CT) || CurIdx == 1 && "Invalid type");
+ Ptr = CT->getTypeAtIndex(Index);
+ if (const Type* Ty = Ptr->getForwardedType())
+ Ptr = Ty;
+ assert(S.isComposite() && "Bad Signedness type");
+ if (isa<StructType>(CT)) {
+ S = S.get(cast<ConstantInt>(Index)->getZExtValue());
+ } else {
+ S = S.get(0UL);
+ }
+ if (S.isNamed())
+ S = CurModule.NamedTypeSigns[S.getName()];
+ }
+ Signedness Result;
+ Result.makeComposite(S);
+ return Result;
+}
+
+/// This function just translates a ConstantInfo into a ValueInfo and calls
+/// getElementSign(ValueInfo,...). Its just a convenience.
+/// @brief ConstantInfo version of getElementSign.
+static Signedness getElementSign(const ConstInfo& CI,
+ const std::vector<Constant*> &Indices) {
+ ValueInfo VI;
+ VI.V = CI.C;
+ VI.S.copy(CI.S);
+ std::vector<Value*> Idx;
+ for (unsigned i = 0; i < Indices.size(); ++i)
+ Idx.push_back(Indices[i]);
+ Signedness result = getElementSign(VI, Idx);
+ VI.destroy();
+ return result;
+}
+
+/// This function determines if two function types differ only in their use of
+/// the sret parameter attribute in the first argument. If they are identical
+/// in all other respects, it returns true. Otherwise, it returns false.
+static bool FuncTysDifferOnlyBySRet(const FunctionType *F1,
+ const FunctionType *F2) {
+ if (F1->getReturnType() != F2->getReturnType() ||
+ F1->getNumParams() != F2->getNumParams())
+ return false;
+ const ParamAttrsList *PAL1 = F1->getParamAttrs();
+ const ParamAttrsList *PAL2 = F2->getParamAttrs();
+ if (PAL1 && !PAL2 || PAL2 && !PAL1)
+ return false;
+ if (PAL1 && PAL2 && ((PAL1->size() != PAL2->size()) ||
+ (PAL1->getParamAttrs(0) != PAL2->getParamAttrs(0))))
+ return false;
+ unsigned SRetMask = ~unsigned(ParamAttr::StructRet);
+ for (unsigned i = 0; i < F1->getNumParams(); ++i) {
+ if (F1->getParamType(i) != F2->getParamType(i) || (PAL1 && PAL2 &&
+ (unsigned(PAL1->getParamAttrs(i+1)) & SRetMask !=
+ unsigned(PAL2->getParamAttrs(i+1)) & SRetMask)))
+ return false;
+ }
+ return true;
+}
+
+/// This function determines if the type of V and Ty differ only by the SRet
+/// parameter attribute. This is a more generalized case of
+/// FuncTysDIfferOnlyBySRet since it doesn't require FunctionType arguments.
+static bool TypesDifferOnlyBySRet(Value *V, const Type* Ty) {
+ if (V->getType() == Ty)
+ return true;
+ const PointerType *PF1 = dyn_cast<PointerType>(Ty);
+ const PointerType *PF2 = dyn_cast<PointerType>(V->getType());
+ if (PF1 && PF2) {
+ const FunctionType* FT1 = dyn_cast<FunctionType>(PF1->getElementType());
+ const FunctionType* FT2 = dyn_cast<FunctionType>(PF2->getElementType());
+ if (FT1 && FT2)
+ return FuncTysDifferOnlyBySRet(FT1, FT2);
+ }
+ return false;
+}
+
+// The upgrade of csretcc to sret param attribute may have caused a function
+// to not be found because the param attribute changed the type of the called
+// function. This helper function, used in getExistingValue, detects that
+// situation and bitcasts the function to the correct type.
+static Value* handleSRetFuncTypeMerge(Value *V, const Type* Ty) {
+ // Handle degenerate cases
+ if (!V)
+ return 0;
+ if (V->getType() == Ty)
+ return V;
+
+ const PointerType *PF1 = dyn_cast<PointerType>(Ty);
+ const PointerType *PF2 = dyn_cast<PointerType>(V->getType());
+ if (PF1 && PF2) {
+ const FunctionType *FT1 = dyn_cast<FunctionType>(PF1->getElementType());
+ const FunctionType *FT2 = dyn_cast<FunctionType>(PF2->getElementType());
+ if (FT1 && FT2 && FuncTysDifferOnlyBySRet(FT1, FT2)) {
+ const ParamAttrsList *PAL2 = FT2->getParamAttrs();
+ if (PAL2 && PAL2->paramHasAttr(1, ParamAttr::StructRet))
+ return V;
+ else if (Constant *C = dyn_cast<Constant>(V))
+ return ConstantExpr::getBitCast(C, PF1);
+ else
+ return new BitCastInst(V, PF1, "upgrd.cast", CurBB);
+ }
+
+ }
+ return 0;
+}
+
+// getExistingValue - Look up the value specified by the provided type and
+// the provided ValID. If the value exists and has already been defined, return
+// it. Otherwise return null.
+//
+static Value *getExistingValue(const Type *Ty, const ValID &D) {
+ if (isa<FunctionType>(Ty)) {
+ error("Functions are not values and must be referenced as pointers");
+ }
+
+ switch (D.Type) {
+ case ValID::NumberVal: { // Is it a numbered definition?
+ unsigned Num = (unsigned)D.Num;
+
+ // Module constants occupy the lowest numbered slots...
+ std::map<const Type*,ValueList>::iterator VI = CurModule.Values.find(Ty);
+ if (VI != CurModule.Values.end()) {
+ if (Num < VI->second.size())
+ return VI->second[Num];
+ Num -= VI->second.size();
+ }
+
+ // Make sure that our type is within bounds
+ VI = CurFun.Values.find(Ty);
+ if (VI == CurFun.Values.end()) return 0;
+
+ // Check that the number is within bounds...
+ if (VI->second.size() <= Num) return 0;
+
+ return VI->second[Num];
+ }
+
+ case ValID::NameVal: { // Is it a named definition?
+ // Get the name out of the ID
+ RenameMapKey Key = makeRenameMapKey(D.Name, Ty, D.S);
+ Value *V = 0;
+ if (inFunctionScope()) {
+ // See if the name was renamed
+ RenameMapType::const_iterator I = CurFun.RenameMap.find(Key);
+ std::string LookupName;
+ if (I != CurFun.RenameMap.end())
+ LookupName = I->second;
+ else
+ LookupName = D.Name;
+ ValueSymbolTable &SymTab = CurFun.CurrentFunction->getValueSymbolTable();
+ V = SymTab.lookup(LookupName);
+ if (V && V->getType() != Ty)
+ V = handleSRetFuncTypeMerge(V, Ty);
+ assert((!V || TypesDifferOnlyBySRet(V, Ty)) && "Found wrong type");
+ }
+ if (!V) {
+ RenameMapType::const_iterator I = CurModule.RenameMap.find(Key);
+ std::string LookupName;
+ if (I != CurModule.RenameMap.end())
+ LookupName = I->second;
+ else
+ LookupName = D.Name;
+ V = CurModule.CurrentModule->getValueSymbolTable().lookup(LookupName);
+ if (V && V->getType() != Ty)
+ V = handleSRetFuncTypeMerge(V, Ty);
+ assert((!V || TypesDifferOnlyBySRet(V, Ty)) && "Found wrong type");
+ }
+ if (!V)
+ return 0;
+
+ D.destroy(); // Free old strdup'd memory...
+ return V;
+ }
+
+ // Check to make sure that "Ty" is an integral type, and that our
+ // value will fit into the specified type...
+ case ValID::ConstSIntVal: // Is it a constant pool reference??
+ if (!ConstantInt::isValueValidForType(Ty, D.ConstPool64)) {
+ error("Signed integral constant '" + itostr(D.ConstPool64) +
+ "' is invalid for type '" + Ty->getDescription() + "'");
+ }
+ return ConstantInt::get(Ty, D.ConstPool64);
+
+ case ValID::ConstUIntVal: // Is it an unsigned const pool reference?
+ if (!ConstantInt::isValueValidForType(Ty, D.UConstPool64)) {
+ if (!ConstantInt::isValueValidForType(Ty, D.ConstPool64))
+ error("Integral constant '" + utostr(D.UConstPool64) +
+ "' is invalid or out of range");
+ else // This is really a signed reference. Transmogrify.
+ return ConstantInt::get(Ty, D.ConstPool64);
+ } else
+ return ConstantInt::get(Ty, D.UConstPool64);
+
+ case ValID::ConstFPVal: // Is it a floating point const pool reference?
+ if (!ConstantFP::isValueValidForType(Ty, D.ConstPoolFP))
+ error("FP constant invalid for type");
+ return ConstantFP::get(Ty, D.ConstPoolFP);
+
+ case ValID::ConstNullVal: // Is it a null value?
+ if (!isa<PointerType>(Ty))
+ error("Cannot create a a non pointer null");
+ return ConstantPointerNull::get(cast<PointerType>(Ty));
+
+ case ValID::ConstUndefVal: // Is it an undef value?
+ return UndefValue::get(Ty);
+
+ case ValID::ConstZeroVal: // Is it a zero value?
+ return Constant::getNullValue(Ty);
+
+ case ValID::ConstantVal: // Fully resolved constant?
+ if (D.ConstantValue->getType() != Ty)
+ error("Constant expression type different from required type");
+ return D.ConstantValue;
+
+ case ValID::InlineAsmVal: { // Inline asm expression
+ const PointerType *PTy = dyn_cast<PointerType>(Ty);
+ const FunctionType *FTy =
+ PTy ? dyn_cast<FunctionType>(PTy->getElementType()) : 0;
+ if (!FTy || !InlineAsm::Verify(FTy, D.IAD->Constraints))
+ error("Invalid type for asm constraint string");
+ InlineAsm *IA = InlineAsm::get(FTy, D.IAD->AsmString, D.IAD->Constraints,
+ D.IAD->HasSideEffects);
+ D.destroy(); // Free InlineAsmDescriptor.
+ return IA;
+ }
+ default:
+ assert(0 && "Unhandled case");
+ return 0;
+ } // End of switch
+
+ assert(0 && "Unhandled case");
+ return 0;
+}
+
+// getVal - This function is identical to getExistingValue, except that if a
+// value is not already defined, it "improvises" by creating a placeholder var
+// that looks and acts just like the requested variable. When the value is
+// defined later, all uses of the placeholder variable are replaced with the
+// real thing.
+//
+static Value *getVal(const Type *Ty, const ValID &ID) {
+ if (Ty == Type::LabelTy)
+ error("Cannot use a basic block here");
+
+ // See if the value has already been defined.
+ Value *V = getExistingValue(Ty, ID);
+ if (V) return V;
+
+ if (!Ty->isFirstClassType() && !isa<OpaqueType>(Ty))
+ error("Invalid use of a composite type");
+
+ // If we reached here, we referenced either a symbol that we don't know about
+ // or an id number that hasn't been read yet. We may be referencing something
+ // forward, so just create an entry to be resolved later and get to it...
+ V = new Argument(Ty);
+
+ // Remember where this forward reference came from. FIXME, shouldn't we try
+ // to recycle these things??
+ CurModule.PlaceHolderInfo.insert(
+ std::make_pair(V, std::make_pair(ID, Upgradelineno)));
+
+ if (inFunctionScope())
+ InsertValue(V, CurFun.LateResolveValues);
+ else
+ InsertValue(V, CurModule.LateResolveValues);
+ return V;
+}
+
+/// @brief This just makes any name given to it unique, up to MAX_UINT times.
+static std::string makeNameUnique(const std::string& Name) {
+ static unsigned UniqueNameCounter = 1;
+ std::string Result(Name);
+ Result += ".upgrd." + llvm::utostr(UniqueNameCounter++);
+ return Result;
+}
+
+/// getBBVal - This is used for two purposes:
+/// * If isDefinition is true, a new basic block with the specified ID is being
+/// defined.
+/// * If isDefinition is true, this is a reference to a basic block, which may
+/// or may not be a forward reference.
+///
+static BasicBlock *getBBVal(const ValID &ID, bool isDefinition = false) {
+ assert(inFunctionScope() && "Can't get basic block at global scope");
+
+ std::string Name;
+ BasicBlock *BB = 0;
+ switch (ID.Type) {
+ default:
+ error("Illegal label reference " + ID.getName());
+ break;
+ case ValID::NumberVal: // Is it a numbered definition?
+ if (unsigned(ID.Num) >= CurFun.NumberedBlocks.size())
+ CurFun.NumberedBlocks.resize(ID.Num+1);
+ BB = CurFun.NumberedBlocks[ID.Num];
+ break;
+ case ValID::NameVal: // Is it a named definition?
+ Name = ID.Name;
+ if (Value *N = CurFun.CurrentFunction->getValueSymbolTable().lookup(Name)) {
+ if (N->getType() != Type::LabelTy) {
+ // Register names didn't use to conflict with basic block names
+ // because of type planes. Now they all have to be unique. So, we just
+ // rename the register and treat this name as if no basic block
+ // had been found.
+ RenameMapKey Key = makeRenameMapKey(ID.Name, N->getType(), ID.S);
+ N->setName(makeNameUnique(N->getName()));
+ CurModule.RenameMap[Key] = N->getName();
+ BB = 0;
+ } else {
+ BB = cast<BasicBlock>(N);
+ }
+ }
+ break;
+ }
+
+ // See if the block has already been defined.
+ if (BB) {
+ // If this is the definition of the block, make sure the existing value was
+ // just a forward reference. If it was a forward reference, there will be
+ // an entry for it in the PlaceHolderInfo map.
+ if (isDefinition && !CurFun.BBForwardRefs.erase(BB))
+ // The existing value was a definition, not a forward reference.
+ error("Redefinition of label " + ID.getName());
+
+ ID.destroy(); // Free strdup'd memory.
+ return BB;
+ }
+
+ // Otherwise this block has not been seen before.
+ BB = new BasicBlock("", CurFun.CurrentFunction);
+ if (ID.Type == ValID::NameVal) {
+ BB->setName(ID.Name);
+ } else {
+ CurFun.NumberedBlocks[ID.Num] = BB;
+ }
+
+ // If this is not a definition, keep track of it so we can use it as a forward
+ // reference.
+ if (!isDefinition) {
+ // Remember where this forward reference came from.
+ CurFun.BBForwardRefs[BB] = std::make_pair(ID, Upgradelineno);
+ } else {
+ // The forward declaration could have been inserted anywhere in the
+ // function: insert it into the correct place now.
+ CurFun.CurrentFunction->getBasicBlockList().remove(BB);
+ CurFun.CurrentFunction->getBasicBlockList().push_back(BB);
+ }
+ ID.destroy();
+ return BB;
+}
+
+
+//===----------------------------------------------------------------------===//
+// Code to handle forward references in instructions
+//===----------------------------------------------------------------------===//
+//
+// This code handles the late binding needed with statements that reference
+// values not defined yet... for example, a forward branch, or the PHI node for
+// a loop body.
+//
+// This keeps a table (CurFun.LateResolveValues) of all such forward references
+// and back patchs after we are done.
+//
+
+// ResolveDefinitions - If we could not resolve some defs at parsing
+// time (forward branches, phi functions for loops, etc...) resolve the
+// defs now...
+//
+static void
+ResolveDefinitions(std::map<const Type*,ValueList> &LateResolvers,
+ std::map<const Type*,ValueList> *FutureLateResolvers) {
+
+ // Loop over LateResolveDefs fixing up stuff that couldn't be resolved
+ for (std::map<const Type*,ValueList>::iterator LRI = LateResolvers.begin(),
+ E = LateResolvers.end(); LRI != E; ++LRI) {
+ const Type* Ty = LRI->first;
+ ValueList &List = LRI->second;
+ while (!List.empty()) {
+ Value *V = List.back();
+ List.pop_back();
+
+ std::map<Value*, std::pair<ValID, int> >::iterator PHI =
+ CurModule.PlaceHolderInfo.find(V);
+ assert(PHI != CurModule.PlaceHolderInfo.end() && "Placeholder error");
+
+ ValID &DID = PHI->second.first;
+
+ Value *TheRealValue = getExistingValue(Ty, DID);
+ if (TheRealValue) {
+ V->replaceAllUsesWith(TheRealValue);
+ delete V;
+ CurModule.PlaceHolderInfo.erase(PHI);
+ } else if (FutureLateResolvers) {
+ // Functions have their unresolved items forwarded to the module late
+ // resolver table
+ InsertValue(V, *FutureLateResolvers);
+ } else {
+ if (DID.Type == ValID::NameVal) {
+ error("Reference to an invalid definition: '" + DID.getName() +
+ "' of type '" + V->getType()->getDescription() + "'",
+ PHI->second.second);
+ return;
+ } else {
+ error("Reference to an invalid definition: #" +
+ itostr(DID.Num) + " of type '" +
+ V->getType()->getDescription() + "'", PHI->second.second);
+ return;
+ }
+ }
+ }
+ }
+
+ LateResolvers.clear();
+}
+
+/// This function is used for type resolution and upref handling. When a type
+/// becomes concrete, this function is called to adjust the signedness for the
+/// concrete type.
+static void ResolveTypeSign(const Type* oldTy, const Signedness &Sign) {
+ std::string TyName = CurModule.CurrentModule->getTypeName(oldTy);
+ if (!TyName.empty())
+ CurModule.NamedTypeSigns[TyName] = Sign;
+}
+
+/// ResolveTypeTo - A brand new type was just declared. This means that (if
+/// name is not null) things referencing Name can be resolved. Otherwise,
+/// things refering to the number can be resolved. Do this now.
+static void ResolveTypeTo(char *Name, const Type *ToTy, const Signedness& Sign){
+ ValID D;
+ if (Name)
+ D = ValID::create(Name);
+ else
+ D = ValID::create((int)CurModule.Types.size());
+ D.S.copy(Sign);
+
+ if (Name)
+ CurModule.NamedTypeSigns[Name] = Sign;
+
+ std::map<ValID, PATypeHolder>::iterator I =
+ CurModule.LateResolveTypes.find(D);
+ if (I != CurModule.LateResolveTypes.end()) {
+ const Type *OldTy = I->second.get();
+ ((DerivedType*)OldTy)->refineAbstractTypeTo(ToTy);
+ CurModule.LateResolveTypes.erase(I);
+ }
+}
+
+/// This is the implementation portion of TypeHasInteger. It traverses the
+/// type given, avoiding recursive types, and returns true as soon as it finds
+/// an integer type. If no integer type is found, it returns false.
+static bool TypeHasIntegerI(const Type *Ty, std::vector<const Type*> Stack) {
+ // Handle some easy cases
+ if (Ty->isPrimitiveType() || (Ty->getTypeID() == Type::OpaqueTyID))
+ return false;
+ if (Ty->isInteger())
+ return true;
+ if (const SequentialType *STy = dyn_cast<SequentialType>(Ty))
+ return STy->getElementType()->isInteger();
+
+ // Avoid type structure recursion
+ for (std::vector<const Type*>::iterator I = Stack.begin(), E = Stack.end();
+ I != E; ++I)
+ if (Ty == *I)
+ return false;
+
+ // Push us on the type stack
+ Stack.push_back(Ty);
+
+ if (const FunctionType *FTy = dyn_cast<FunctionType>(Ty)) {
+ if (TypeHasIntegerI(FTy->getReturnType(), Stack))
+ return true;
+ FunctionType::param_iterator I = FTy->param_begin();
+ FunctionType::param_iterator E = FTy->param_end();
+ for (; I != E; ++I)
+ if (TypeHasIntegerI(*I, Stack))
+ return true;
+ return false;
+ } else if (const StructType *STy = dyn_cast<StructType>(Ty)) {
+ StructType::element_iterator I = STy->element_begin();
+ StructType::element_iterator E = STy->element_end();
+ for (; I != E; ++I) {
+ if (TypeHasIntegerI(*I, Stack))
+ return true;
+ }
+ return false;
+ }
+ // There shouldn't be anything else, but its definitely not integer
+ assert(0 && "What type is this?");
+ return false;
+}
+
+/// This is the interface to TypeHasIntegerI. It just provides the type stack,
+/// to avoid recursion, and then calls TypeHasIntegerI.
+static inline bool TypeHasInteger(const Type *Ty) {
+ std::vector<const Type*> TyStack;
+ return TypeHasIntegerI(Ty, TyStack);
+}
+
+// setValueName - Set the specified value to the name given. The name may be
+// null potentially, in which case this is a noop. The string passed in is
+// assumed to be a malloc'd string buffer, and is free'd by this function.
+//
+static void setValueName(const ValueInfo &V, char *NameStr) {
+ if (NameStr) {
+ std::string Name(NameStr); // Copy string
+ free(NameStr); // Free old string
+
+ if (V.V->getType() == Type::VoidTy) {
+ error("Can't assign name '" + Name + "' to value with void type");
+ return;
+ }
+
+ assert(inFunctionScope() && "Must be in function scope");
+
+ // Search the function's symbol table for an existing value of this name
+ ValueSymbolTable &ST = CurFun.CurrentFunction->getValueSymbolTable();
+ Value* Existing = ST.lookup(Name);
+ if (Existing) {
+ // An existing value of the same name was found. This might have happened
+ // because of the integer type planes collapsing in LLVM 2.0.
+ if (Existing->getType() == V.V->getType() &&
+ !TypeHasInteger(Existing->getType())) {
+ // If the type does not contain any integers in them then this can't be
+ // a type plane collapsing issue. It truly is a redefinition and we
+ // should error out as the assembly is invalid.
+ error("Redefinition of value named '" + Name + "' of type '" +
+ V.V->getType()->getDescription() + "'");
+ return;
+ }
+ // In LLVM 2.0 we don't allow names to be re-used for any values in a
+ // function, regardless of Type. Previously re-use of names was okay as
+ // long as they were distinct types. With type planes collapsing because
+ // of the signedness change and because of PR411, this can no longer be
+ // supported. We must search the entire symbol table for a conflicting
+ // name and make the name unique. No warning is needed as this can't
+ // cause a problem.
+ std::string NewName = makeNameUnique(Name);
+ // We're changing the name but it will probably be used by other
+ // instructions as operands later on. Consequently we have to retain
+ // a mapping of the renaming that we're doing.
+ RenameMapKey Key = makeRenameMapKey(Name, V.V->getType(), V.S);
+ CurFun.RenameMap[Key] = NewName;
+ Name = NewName;
+ }
+
+ // Set the name.
+ V.V->setName(Name);
+ }
+}
+
+/// ParseGlobalVariable - Handle parsing of a global. If Initializer is null,
+/// this is a declaration, otherwise it is a definition.
+static GlobalVariable *
+ParseGlobalVariable(char *NameStr,GlobalValue::LinkageTypes Linkage,
+ bool isConstantGlobal, const Type *Ty,
+ Constant *Initializer,
+ const Signedness &Sign) {
+ if (isa<FunctionType>(Ty))
+ error("Cannot declare global vars of function type");
+
+ const PointerType *PTy = PointerType::get(Ty);
+
+ std::string Name;
+ if (NameStr) {
+ Name = NameStr; // Copy string
+ free(NameStr); // Free old string
+ }
+
+ // See if this global value was forward referenced. If so, recycle the
+ // object.
+ ValID ID;
+ if (!Name.empty()) {
+ ID = ValID::create((char*)Name.c_str());
+ } else {
+ ID = ValID::create((int)CurModule.Values[PTy].size());
+ }
+ ID.S.makeComposite(Sign);
+
+ if (GlobalValue *FWGV = CurModule.GetForwardRefForGlobal(PTy, ID)) {
+ // Move the global to the end of the list, from whereever it was
+ // previously inserted.
+ GlobalVariable *GV = cast<GlobalVariable>(FWGV);
+ CurModule.CurrentModule->getGlobalList().remove(GV);
+ CurModule.CurrentModule->getGlobalList().push_back(GV);
+ GV->setInitializer(Initializer);
+ GV->setLinkage(Linkage);
+ GV->setConstant(isConstantGlobal);
+ InsertValue(GV, CurModule.Values);
+ return GV;
+ }
+
+ // If this global has a name, check to see if there is already a definition
+ // of this global in the module and emit warnings if there are conflicts.
+ if (!Name.empty()) {
+ // The global has a name. See if there's an existing one of the same name.
+ if (CurModule.CurrentModule->getNamedGlobal(Name) ||
+ CurModule.CurrentModule->getFunction(Name)) {
+ // We found an existing global of the same name. This isn't allowed
+ // in LLVM 2.0. Consequently, we must alter the name of the global so it
+ // can at least compile. This can happen because of type planes
+ // There is alread a global of the same name which means there is a
+ // conflict. Let's see what we can do about it.
+ std::string NewName(makeNameUnique(Name));
+ if (Linkage != GlobalValue::InternalLinkage) {
+ // The linkage of this gval is external so we can't reliably rename
+ // it because it could potentially create a linking problem.
+ // However, we can't leave the name conflict in the output either or
+ // it won't assemble with LLVM 2.0. So, all we can do is rename
+ // this one to something unique and emit a warning about the problem.
+ warning("Renaming global variable '" + Name + "' to '" + NewName +
+ "' may cause linkage errors");
+ }
+
+ // Put the renaming in the global rename map
+ RenameMapKey Key = makeRenameMapKey(Name, PointerType::get(Ty), ID.S);
+ CurModule.RenameMap[Key] = NewName;
+
+ // Rename it
+ Name = NewName;
+ }
+ }
+
+ // Otherwise there is no existing GV to use, create one now.
+ GlobalVariable *GV =
+ new GlobalVariable(Ty, isConstantGlobal, Linkage, Initializer, Name,
+ CurModule.CurrentModule);
+ InsertValue(GV, CurModule.Values);
+ // Remember the sign of this global.
+ CurModule.NamedValueSigns[Name] = ID.S;
+ return GV;
+}
+
+// setTypeName - Set the specified type to the name given. The name may be
+// null potentially, in which case this is a noop. The string passed in is
+// assumed to be a malloc'd string buffer, and is freed by this function.
+//
+// This function returns true if the type has already been defined, but is
+// allowed to be redefined in the specified context. If the name is a new name
+// for the type plane, it is inserted and false is returned.
+static bool setTypeName(const PATypeInfo& TI, char *NameStr) {
+ assert(!inFunctionScope() && "Can't give types function-local names");
+ if (NameStr == 0) return false;
+
+ std::string Name(NameStr); // Copy string
+ free(NameStr); // Free old string
+
+ const Type* Ty = TI.PAT->get();
+
+ // We don't allow assigning names to void type
+ if (Ty == Type::VoidTy) {
+ error("Can't assign name '" + Name + "' to the void type");
+ return false;
+ }
+
+ // Set the type name, checking for conflicts as we do so.
+ bool AlreadyExists = CurModule.CurrentModule->addTypeName(Name, Ty);
+
+ // Save the sign information for later use
+ CurModule.NamedTypeSigns[Name] = TI.S;
+
+ if (AlreadyExists) { // Inserting a name that is already defined???
+ const Type *Existing = CurModule.CurrentModule->getTypeByName(Name);
+ assert(Existing && "Conflict but no matching type?");
+
+ // There is only one case where this is allowed: when we are refining an
+ // opaque type. In this case, Existing will be an opaque type.
+ if (const OpaqueType *OpTy = dyn_cast<OpaqueType>(Existing)) {
+ // We ARE replacing an opaque type!
+ const_cast<OpaqueType*>(OpTy)->refineAbstractTypeTo(Ty);
+ return true;
+ }
+
+ // Otherwise, this is an attempt to redefine a type. That's okay if
+ // the redefinition is identical to the original. This will be so if
+ // Existing and T point to the same Type object. In this one case we
+ // allow the equivalent redefinition.
+ if (Existing == Ty) return true; // Yes, it's equal.
+
+ // Any other kind of (non-equivalent) redefinition is an error.
+ error("Redefinition of type named '" + Name + "' in the '" +
+ Ty->getDescription() + "' type plane");
+ }
+
+ return false;
+}
+
+//===----------------------------------------------------------------------===//
+// Code for handling upreferences in type names...
+//
+
+// TypeContains - Returns true if Ty directly contains E in it.
+//
+static bool TypeContains(const Type *Ty, const Type *E) {
+ return std::find(Ty->subtype_begin(), Ty->subtype_end(),
+ E) != Ty->subtype_end();
+}
+
+namespace {
+ struct UpRefRecord {
+ // NestingLevel - The number of nesting levels that need to be popped before
+ // this type is resolved.
+ unsigned NestingLevel;
+
+ // LastContainedTy - This is the type at the current binding level for the
+ // type. Every time we reduce the nesting level, this gets updated.
+ const Type *LastContainedTy;
+
+ // UpRefTy - This is the actual opaque type that the upreference is
+ // represented with.
+ OpaqueType *UpRefTy;
+
+ UpRefRecord(unsigned NL, OpaqueType *URTy)
+ : NestingLevel(NL), LastContainedTy(URTy), UpRefTy(URTy) { }
+ };
+}
+
+// UpRefs - A list of the outstanding upreferences that need to be resolved.
+static std::vector<UpRefRecord> UpRefs;
+
+/// HandleUpRefs - Every time we finish a new layer of types, this function is
+/// called. It loops through the UpRefs vector, which is a list of the
+/// currently active types. For each type, if the up reference is contained in
+/// the newly completed type, we decrement the level count. When the level
+/// count reaches zero, the upreferenced type is the type that is passed in:
+/// thus we can complete the cycle.
+///
+static PATypeHolder HandleUpRefs(const Type *ty, const Signedness& Sign) {
+ // If Ty isn't abstract, or if there are no up-references in it, then there is
+ // nothing to resolve here.
+ if (!ty->isAbstract() || UpRefs.empty()) return ty;
+
+ PATypeHolder Ty(ty);
+ UR_OUT("Type '" << Ty->getDescription() <<
+ "' newly formed. Resolving upreferences.\n" <<
+ UpRefs.size() << " upreferences active!\n");
+
+ // If we find any resolvable upreferences (i.e., those whose NestingLevel goes
+ // to zero), we resolve them all together before we resolve them to Ty. At
+ // the end of the loop, if there is anything to resolve to Ty, it will be in
+ // this variable.
+ OpaqueType *TypeToResolve = 0;
+
+ unsigned i = 0;
+ for (; i != UpRefs.size(); ++i) {
+ UR_OUT(" UR#" << i << " - TypeContains(" << Ty->getDescription() << ", "
+ << UpRefs[i].UpRefTy->getDescription() << ") = "
+ << (TypeContains(Ty, UpRefs[i].UpRefTy) ? "true" : "false") << "\n");
+ if (TypeContains(Ty, UpRefs[i].LastContainedTy)) {
+ // Decrement level of upreference
+ unsigned Level = --UpRefs[i].NestingLevel;
+ UpRefs[i].LastContainedTy = Ty;
+ UR_OUT(" Uplevel Ref Level = " << Level << "\n");
+ if (Level == 0) { // Upreference should be resolved!
+ if (!TypeToResolve) {
+ TypeToResolve = UpRefs[i].UpRefTy;
+ } else {
+ UR_OUT(" * Resolving upreference for "
+ << UpRefs[i].UpRefTy->getDescription() << "\n";
+ std::string OldName = UpRefs[i].UpRefTy->getDescription());
+ ResolveTypeSign(UpRefs[i].UpRefTy, Sign);
+ UpRefs[i].UpRefTy->refineAbstractTypeTo(TypeToResolve);
+ UR_OUT(" * Type '" << OldName << "' refined upreference to: "
+ << (const void*)Ty << ", " << Ty->getDescription() << "\n");
+ }
+ UpRefs.erase(UpRefs.begin()+i); // Remove from upreference list...
+ --i; // Do not skip the next element...
+ }
+ }
+ }
+
+ if (TypeToResolve) {
+ UR_OUT(" * Resolving upreference for "
+ << UpRefs[i].UpRefTy->getDescription() << "\n";
+ std::string OldName = TypeToResolve->getDescription());
+ ResolveTypeSign(TypeToResolve, Sign);
+ TypeToResolve->refineAbstractTypeTo(Ty);
+ }
+
+ return Ty;
+}
+
+bool Signedness::operator<(const Signedness &that) const {
+ if (isNamed()) {
+ if (that.isNamed())
+ return *(this->name) < *(that.name);
+ else
+ return CurModule.NamedTypeSigns[*name] < that;
+ } else if (that.isNamed()) {
+ return *this < CurModule.NamedTypeSigns[*that.name];
+ }
+
+ if (isComposite() && that.isComposite()) {
+ if (sv->size() == that.sv->size()) {
+ SignVector::const_iterator thisI = sv->begin(), thisE = sv->end();
+ SignVector::const_iterator thatI = that.sv->begin(),
+ thatE = that.sv->end();
+ for (; thisI != thisE; ++thisI, ++thatI) {
+ if (*thisI < *thatI)
+ return true;
+ else if (!(*thisI == *thatI))
+ return false;
+ }
+ return false;
+ }
+ return sv->size() < that.sv->size();
+ }
+ return kind < that.kind;
+}
+
+bool Signedness::operator==(const Signedness &that) const {
+ if (isNamed())
+ if (that.isNamed())
+ return *(this->name) == *(that.name);
+ else
+ return CurModule.NamedTypeSigns[*(this->name)] == that;
+ else if (that.isNamed())
+ return *this == CurModule.NamedTypeSigns[*(that.name)];
+ if (isComposite() && that.isComposite()) {
+ if (sv->size() == that.sv->size()) {
+ SignVector::const_iterator thisI = sv->begin(), thisE = sv->end();
+ SignVector::const_iterator thatI = that.sv->begin(),
+ thatE = that.sv->end();
+ for (; thisI != thisE; ++thisI, ++thatI) {
+ if (!(*thisI == *thatI))
+ return false;
+ }
+ return true;
+ }
+ return false;
+ }
+ return kind == that.kind;
+}
+
+void Signedness::copy(const Signedness &that) {
+ if (that.isNamed()) {
+ kind = Named;
+ name = new std::string(*that.name);
+ } else if (that.isComposite()) {
+ kind = Composite;
+ sv = new SignVector();
+ *sv = *that.sv;
+ } else {
+ kind = that.kind;
+ sv = 0;
+ }
+}
+
+void Signedness::destroy() {
+ if (isNamed()) {
+ delete name;
+ } else if (isComposite()) {
+ delete sv;
+ }
+}
+
+#ifndef NDEBUG
+void Signedness::dump() const {
+ if (isComposite()) {
+ if (sv->size() == 1) {
+ (*sv)[0].dump();
+ std::cerr << "*";
+ } else {
+ std::cerr << "{ " ;
+ for (unsigned i = 0; i < sv->size(); ++i) {
+ if (i != 0)
+ std::cerr << ", ";
+ (*sv)[i].dump();
+ }
+ std::cerr << "} " ;
+ }
+ } else if (isNamed()) {
+ std::cerr << *name;
+ } else if (isSigned()) {
+ std::cerr << "S";
+ } else if (isUnsigned()) {
+ std::cerr << "U";
+ } else
+ std::cerr << ".";
+}
+#endif
+
+static inline Instruction::TermOps
+getTermOp(TermOps op) {
+ switch (op) {
+ default : assert(0 && "Invalid OldTermOp");
+ case RetOp : return Instruction::Ret;
+ case BrOp : return Instruction::Br;
+ case SwitchOp : return Instruction::Switch;
+ case InvokeOp : return Instruction::Invoke;
+ case UnwindOp : return Instruction::Unwind;
+ case UnreachableOp: return Instruction::Unreachable;
+ }
+}
+
+static inline Instruction::BinaryOps
+getBinaryOp(BinaryOps op, const Type *Ty, const Signedness& Sign) {
+ switch (op) {
+ default : assert(0 && "Invalid OldBinaryOps");
+ case SetEQ :
+ case SetNE :
+ case SetLE :
+ case SetGE :
+ case SetLT :
+ case SetGT : assert(0 && "Should use getCompareOp");
+ case AddOp : return Instruction::Add;
+ case SubOp : return Instruction::Sub;
+ case MulOp : return Instruction::Mul;
+ case DivOp : {
+ // This is an obsolete instruction so we must upgrade it based on the
+ // types of its operands.
+ bool isFP = Ty->isFloatingPoint();
+ if (const VectorType* PTy = dyn_cast<VectorType>(Ty))
+ // If its a vector type we want to use the element type
+ isFP = PTy->getElementType()->isFloatingPoint();
+ if (isFP)
+ return Instruction::FDiv;
+ else if (Sign.isSigned())
+ return Instruction::SDiv;
+ return Instruction::UDiv;
+ }
+ case UDivOp : return Instruction::UDiv;
+ case SDivOp : return Instruction::SDiv;
+ case FDivOp : return Instruction::FDiv;
+ case RemOp : {
+ // This is an obsolete instruction so we must upgrade it based on the
+ // types of its operands.
+ bool isFP = Ty->isFloatingPoint();
+ if (const VectorType* PTy = dyn_cast<VectorType>(Ty))
+ // If its a vector type we want to use the element type
+ isFP = PTy->getElementType()->isFloatingPoint();
+ // Select correct opcode
+ if (isFP)
+ return Instruction::FRem;
+ else if (Sign.isSigned())
+ return Instruction::SRem;
+ return Instruction::URem;
+ }
+ case URemOp : return Instruction::URem;
+ case SRemOp : return Instruction::SRem;
+ case FRemOp : return Instruction::FRem;
+ case LShrOp : return Instruction::LShr;
+ case AShrOp : return Instruction::AShr;
+ case ShlOp : return Instruction::Shl;
+ case ShrOp :
+ if (Sign.isSigned())
+ return Instruction::AShr;
+ return Instruction::LShr;
+ case AndOp : return Instruction::And;
+ case OrOp : return Instruction::Or;
+ case XorOp : return Instruction::Xor;
+ }
+}
+
+static inline Instruction::OtherOps
+getCompareOp(BinaryOps op, unsigned short &predicate, const Type* &Ty,
+ const Signedness &Sign) {
+ bool isSigned = Sign.isSigned();
+ bool isFP = Ty->isFloatingPoint();
+ switch (op) {
+ default : assert(0 && "Invalid OldSetCC");
+ case SetEQ :
+ if (isFP) {
+ predicate = FCmpInst::FCMP_OEQ;
+ return Instruction::FCmp;
+ } else {
+ predicate = ICmpInst::ICMP_EQ;
+ return Instruction::ICmp;
+ }
+ case SetNE :
+ if (isFP) {
+ predicate = FCmpInst::FCMP_UNE;
+ return Instruction::FCmp;
+ } else {
+ predicate = ICmpInst::ICMP_NE;
+ return Instruction::ICmp;
+ }
+ case SetLE :
+ if (isFP) {
+ predicate = FCmpInst::FCMP_OLE;
+ return Instruction::FCmp;
+ } else {
+ if (isSigned)
+ predicate = ICmpInst::ICMP_SLE;
+ else
+ predicate = ICmpInst::ICMP_ULE;
+ return Instruction::ICmp;
+ }
+ case SetGE :
+ if (isFP) {
+ predicate = FCmpInst::FCMP_OGE;
+ return Instruction::FCmp;
+ } else {
+ if (isSigned)
+ predicate = ICmpInst::ICMP_SGE;
+ else
+ predicate = ICmpInst::ICMP_UGE;
+ return Instruction::ICmp;
+ }
+ case SetLT :
+ if (isFP) {
+ predicate = FCmpInst::FCMP_OLT;
+ return Instruction::FCmp;
+ } else {
+ if (isSigned)
+ predicate = ICmpInst::ICMP_SLT;
+ else
+ predicate = ICmpInst::ICMP_ULT;
+ return Instruction::ICmp;
+ }
+ case SetGT :
+ if (isFP) {
+ predicate = FCmpInst::FCMP_OGT;
+ return Instruction::FCmp;
+ } else {
+ if (isSigned)
+ predicate = ICmpInst::ICMP_SGT;
+ else
+ predicate = ICmpInst::ICMP_UGT;
+ return Instruction::ICmp;
+ }
+ }
+}
+
+static inline Instruction::MemoryOps getMemoryOp(MemoryOps op) {
+ switch (op) {
+ default : assert(0 && "Invalid OldMemoryOps");
+ case MallocOp : return Instruction::Malloc;
+ case FreeOp : return Instruction::Free;
+ case AllocaOp : return Instruction::Alloca;
+ case LoadOp : return Instruction::Load;
+ case StoreOp : return Instruction::Store;
+ case GetElementPtrOp : return Instruction::GetElementPtr;
+ }
+}
+
+static inline Instruction::OtherOps
+getOtherOp(OtherOps op, const Signedness &Sign) {
+ switch (op) {
+ default : assert(0 && "Invalid OldOtherOps");
+ case PHIOp : return Instruction::PHI;
+ case CallOp : return Instruction::Call;
+ case SelectOp : return Instruction::Select;
+ case UserOp1 : return Instruction::UserOp1;
+ case UserOp2 : return Instruction::UserOp2;
+ case VAArg : return Instruction::VAArg;
+ case ExtractElementOp : return Instruction::ExtractElement;
+ case InsertElementOp : return Instruction::InsertElement;
+ case ShuffleVectorOp : return Instruction::ShuffleVector;
+ case ICmpOp : return Instruction::ICmp;
+ case FCmpOp : return Instruction::FCmp;
+ };
+}
+
+static inline Value*
+getCast(CastOps op, Value *Src, const Signedness &SrcSign, const Type *DstTy,
+ const Signedness &DstSign, bool ForceInstruction = false) {
+ Instruction::CastOps Opcode;
+ const Type* SrcTy = Src->getType();
+ if (op == CastOp) {
+ if (SrcTy->isFloatingPoint() && isa<PointerType>(DstTy)) {
+ // fp -> ptr cast is no longer supported but we must upgrade this
+ // by doing a double cast: fp -> int -> ptr
+ SrcTy = Type::Int64Ty;
+ Opcode = Instruction::IntToPtr;
+ if (isa<Constant>(Src)) {
+ Src = ConstantExpr::getCast(Instruction::FPToUI,
+ cast<Constant>(Src), SrcTy);
+ } else {
+ std::string NewName(makeNameUnique(Src->getName()));
+ Src = new FPToUIInst(Src, SrcTy, NewName, CurBB);
+ }
+ } else if (isa<IntegerType>(DstTy) &&
+ cast<IntegerType>(DstTy)->getBitWidth() == 1) {
+ // cast type %x to bool was previously defined as setne type %x, null
+ // The cast semantic is now to truncate, not compare so we must retain
+ // the original intent by replacing the cast with a setne
+ Constant* Null = Constant::getNullValue(SrcTy);
+ Instruction::OtherOps Opcode = Instruction::ICmp;
+ unsigned short predicate = ICmpInst::ICMP_NE;
+ if (SrcTy->isFloatingPoint()) {
+ Opcode = Instruction::FCmp;
+ predicate = FCmpInst::FCMP_ONE;
+ } else if (!SrcTy->isInteger() && !isa<PointerType>(SrcTy)) {
+ error("Invalid cast to bool");
+ }
+ if (isa<Constant>(Src) && !ForceInstruction)
+ return ConstantExpr::getCompare(predicate, cast<Constant>(Src), Null);
+ else
+ return CmpInst::create(Opcode, predicate, Src, Null);
+ }
+ // Determine the opcode to use by calling CastInst::getCastOpcode
+ Opcode =
+ CastInst::getCastOpcode(Src, SrcSign.isSigned(), DstTy,
+ DstSign.isSigned());
+
+ } else switch (op) {
+ default: assert(0 && "Invalid cast token");
+ case TruncOp: Opcode = Instruction::Trunc; break;
+ case ZExtOp: Opcode = Instruction::ZExt; break;
+ case SExtOp: Opcode = Instruction::SExt; break;
+ case FPTruncOp: Opcode = Instruction::FPTrunc; break;
+ case FPExtOp: Opcode = Instruction::FPExt; break;
+ case FPToUIOp: Opcode = Instruction::FPToUI; break;
+ case FPToSIOp: Opcode = Instruction::FPToSI; break;
+ case UIToFPOp: Opcode = Instruction::UIToFP; break;
+ case SIToFPOp: Opcode = Instruction::SIToFP; break;
+ case PtrToIntOp: Opcode = Instruction::PtrToInt; break;
+ case IntToPtrOp: Opcode = Instruction::IntToPtr; break;
+ case BitCastOp: Opcode = Instruction::BitCast; break;
+ }
+
+ if (isa<Constant>(Src) && !ForceInstruction)
+ return ConstantExpr::getCast(Opcode, cast<Constant>(Src), DstTy);
+ return CastInst::create(Opcode, Src, DstTy);
+}
+
+static Instruction *
+upgradeIntrinsicCall(const Type* RetTy, const ValID &ID,
+ std::vector<Value*>& Args) {
+
+ std::string Name = ID.Type == ValID::NameVal ? ID.Name : "";
+ if (Name.length() <= 5 || Name[0] != 'l' || Name[1] != 'l' ||
+ Name[2] != 'v' || Name[3] != 'm' || Name[4] != '.')
+ return 0;
+
+ switch (Name[5]) {
+ case 'i':
+ if (Name == "llvm.isunordered.f32" || Name == "llvm.isunordered.f64") {
+ if (Args.size() != 2)
+ error("Invalid prototype for " + Name);
+ return new FCmpInst(FCmpInst::FCMP_UNO, Args[0], Args[1]);
+ }
+ break;
+ case 'b':
+ if (Name.length() == 14 && !memcmp(&Name[5], "bswap.i", 7)) {
+ const Type* ArgTy = Args[0]->getType();
+ Name += ".i" + utostr(cast<IntegerType>(ArgTy)->getBitWidth());
+ Function *F = cast<Function>(
+ CurModule.CurrentModule->getOrInsertFunction(Name, RetTy, ArgTy,
+ (void*)0));
+ return new CallInst(F, Args[0]);
+ }
+ break;
+ case 'c':
+ if ((Name.length() <= 14 && !memcmp(&Name[5], "ctpop.i", 7)) ||
+ (Name.length() <= 13 && !memcmp(&Name[5], "ctlz.i", 6)) ||
+ (Name.length() <= 13 && !memcmp(&Name[5], "cttz.i", 6))) {
+ // These intrinsics changed their result type.
+ const Type* ArgTy = Args[0]->getType();
+ Function *OldF = CurModule.CurrentModule->getFunction(Name);
+ if (OldF)
+ OldF->setName("upgrd.rm." + Name);
+
+ Function *NewF = cast<Function>(
+ CurModule.CurrentModule->getOrInsertFunction(Name, Type::Int32Ty,
+ ArgTy, (void*)0));
+
+ Instruction *Call = new CallInst(NewF, Args[0], "", CurBB);
+ return CastInst::createIntegerCast(Call, RetTy, false);
+ }
+ break;
+
+ case 'v' : {
+ const Type* PtrTy = PointerType::get(Type::Int8Ty);
+ std::vector<const Type*> Params;
+ if (Name == "llvm.va_start" || Name == "llvm.va_end") {
+ if (Args.size() != 1)
+ error("Invalid prototype for " + Name + " prototype");
+ Params.push_back(PtrTy);
+ const FunctionType *FTy =
+ FunctionType::get(Type::VoidTy, Params, false);
+ const PointerType *PFTy = PointerType::get(FTy);
+ Value* Func = getVal(PFTy, ID);
+ Args[0] = new BitCastInst(Args[0], PtrTy, makeNameUnique("va"), CurBB);
+ return new CallInst(Func, &Args[0], Args.size());
+ } else if (Name == "llvm.va_copy") {
+ if (Args.size() != 2)
+ error("Invalid prototype for " + Name + " prototype");
+ Params.push_back(PtrTy);
+ Params.push_back(PtrTy);
+ const FunctionType *FTy =
+ FunctionType::get(Type::VoidTy, Params, false);
+ const PointerType *PFTy = PointerType::get(FTy);
+ Value* Func = getVal(PFTy, ID);
+ std::string InstName0(makeNameUnique("va0"));
+ std::string InstName1(makeNameUnique("va1"));
+ Args[0] = new BitCastInst(Args[0], PtrTy, InstName0, CurBB);
+ Args[1] = new BitCastInst(Args[1], PtrTy, InstName1, CurBB);
+ return new CallInst(Func, &Args[0], Args.size());
+ }
+ }
+ }
+ return 0;
+}
+
+const Type* upgradeGEPCEIndices(const Type* PTy,
+ std::vector<ValueInfo> *Indices,
+ std::vector<Constant*> &Result) {
+ const Type *Ty = PTy;
+ Result.clear();
+ for (unsigned i = 0, e = Indices->size(); i != e ; ++i) {
+ Constant *Index = cast<Constant>((*Indices)[i].V);
+
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(Index)) {
+ // LLVM 1.2 and earlier used ubyte struct indices. Convert any ubyte
+ // struct indices to i32 struct indices with ZExt for compatibility.
+ if (CI->getBitWidth() < 32)
+ Index = ConstantExpr::getCast(Instruction::ZExt, CI, Type::Int32Ty);
+ }
+
+ if (isa<SequentialType>(Ty)) {
+ // Make sure that unsigned SequentialType indices are zext'd to
+ // 64-bits if they were smaller than that because LLVM 2.0 will sext
+ // all indices for SequentialType elements. We must retain the same
+ // semantic (zext) for unsigned types.
+ if (const IntegerType *Ity = dyn_cast<IntegerType>(Index->getType())) {
+ if (Ity->getBitWidth() < 64 && (*Indices)[i].S.isUnsigned()) {
+ Index = ConstantExpr::getCast(Instruction::ZExt, Index,Type::Int64Ty);
+ }
+ }
+ }
+ Result.push_back(Index);
+ Ty = GetElementPtrInst::getIndexedType(PTy, (Value**)&Result[0],
+ Result.size(),true);
+ if (!Ty)
+ error("Index list invalid for constant getelementptr");
+ }
+ return Ty;
+}
+
+const Type* upgradeGEPInstIndices(const Type* PTy,
+ std::vector<ValueInfo> *Indices,
+ std::vector<Value*> &Result) {
+ const Type *Ty = PTy;
+ Result.clear();
+ for (unsigned i = 0, e = Indices->size(); i != e ; ++i) {
+ Value *Index = (*Indices)[i].V;
+
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(Index)) {
+ // LLVM 1.2 and earlier used ubyte struct indices. Convert any ubyte
+ // struct indices to i32 struct indices with ZExt for compatibility.
+ if (CI->getBitWidth() < 32)
+ Index = ConstantExpr::getCast(Instruction::ZExt, CI, Type::Int32Ty);
+ }
+
+
+ if (isa<StructType>(Ty)) { // Only change struct indices
+ if (!isa<Constant>(Index)) {
+ error("Invalid non-constant structure index");
+ return 0;
+ }
+ } else {
+ // Make sure that unsigned SequentialType indices are zext'd to
+ // 64-bits if they were smaller than that because LLVM 2.0 will sext
+ // all indices for SequentialType elements. We must retain the same
+ // semantic (zext) for unsigned types.
+ if (const IntegerType *Ity = dyn_cast<IntegerType>(Index->getType())) {
+ if (Ity->getBitWidth() < 64 && (*Indices)[i].S.isUnsigned()) {
+ if (isa<Constant>(Index))
+ Index = ConstantExpr::getCast(Instruction::ZExt,
+ cast<Constant>(Index), Type::Int64Ty);
+ else
+ Index = CastInst::create(Instruction::ZExt, Index, Type::Int64Ty,
+ makeNameUnique("gep"), CurBB);
+ }
+ }
+ }
+ Result.push_back(Index);
+ Ty = GetElementPtrInst::getIndexedType(PTy, &Result[0], Result.size(),true);
+ if (!Ty)
+ error("Index list invalid for constant getelementptr");
+ }
+ return Ty;
+}
+
+unsigned upgradeCallingConv(unsigned CC) {
+ switch (CC) {
+ case OldCallingConv::C : return CallingConv::C;
+ case OldCallingConv::CSRet : return CallingConv::C;
+ case OldCallingConv::Fast : return CallingConv::Fast;
+ case OldCallingConv::Cold : return CallingConv::Cold;
+ case OldCallingConv::X86_StdCall : return CallingConv::X86_StdCall;
+ case OldCallingConv::X86_FastCall: return CallingConv::X86_FastCall;
+ default:
+ return CC;
+ }
+}
+
+Module* UpgradeAssembly(const std::string &infile, std::istream& in,
+ bool debug, bool addAttrs)
+{
+ Upgradelineno = 1;
+ CurFilename = infile;
+ LexInput = &in;
+ yydebug = debug;
+ AddAttributes = addAttrs;
+ ObsoleteVarArgs = false;
+ NewVarArgs = false;
+
+ CurModule.CurrentModule = new Module(CurFilename);
+
+ // Check to make sure the parser succeeded
+ if (yyparse()) {
+ if (ParserResult)
+ delete ParserResult;
+ std::cerr << "llvm-upgrade: parse failed.\n";
+ return 0;
+ }
+
+ // Check to make sure that parsing produced a result
+ if (!ParserResult) {
+ std::cerr << "llvm-upgrade: no parse result.\n";
+ return 0;
+ }
+
+ // Reset ParserResult variable while saving its value for the result.
+ Module *Result = ParserResult;
+ ParserResult = 0;
+
+ //Not all functions use vaarg, so make a second check for ObsoleteVarArgs
+ {
+ Function* F;
+ if ((F = Result->getFunction("llvm.va_start"))
+ && F->getFunctionType()->getNumParams() == 0)
+ ObsoleteVarArgs = true;
+ if((F = Result->getFunction("llvm.va_copy"))
+ && F->getFunctionType()->getNumParams() == 1)
+ ObsoleteVarArgs = true;
+ }
+
+ if (ObsoleteVarArgs && NewVarArgs) {
+ error("This file is corrupt: it uses both new and old style varargs");
+ return 0;
+ }
+
+ if(ObsoleteVarArgs) {
+ if(Function* F = Result->getFunction("llvm.va_start")) {
+ if (F->arg_size() != 0) {
+ error("Obsolete va_start takes 0 argument");
+ return 0;
+ }
+
+ //foo = va_start()
+ // ->
+ //bar = alloca typeof(foo)
+ //va_start(bar)
+ //foo = load bar
+
+ const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID);
+ const Type* ArgTy = F->getFunctionType()->getReturnType();
+ const Type* ArgTyPtr = PointerType::get(ArgTy);
+ Function* NF = cast<Function>(Result->getOrInsertFunction(
+ "llvm.va_start", RetTy, ArgTyPtr, (Type *)0));
+
+ while (!F->use_empty()) {
+ CallInst* CI = cast<CallInst>(F->use_back());
+ AllocaInst* bar = new AllocaInst(ArgTy, 0, "vastart.fix.1", CI);
+ new CallInst(NF, bar, "", CI);
+ Value* foo = new LoadInst(bar, "vastart.fix.2", CI);
+ CI->replaceAllUsesWith(foo);
+ CI->getParent()->getInstList().erase(CI);
+ }
+ Result->getFunctionList().erase(F);
+ }
+
+ if(Function* F = Result->getFunction("llvm.va_end")) {
+ if(F->arg_size() != 1) {
+ error("Obsolete va_end takes 1 argument");
+ return 0;
+ }
+
+ //vaend foo
+ // ->
+ //bar = alloca 1 of typeof(foo)
+ //vaend bar
+ const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID);
+ const Type* ArgTy = F->getFunctionType()->getParamType(0);
+ const Type* ArgTyPtr = PointerType::get(ArgTy);
+ Function* NF = cast<Function>(Result->getOrInsertFunction(
+ "llvm.va_end", RetTy, ArgTyPtr, (Type *)0));
+
+ while (!F->use_empty()) {
+ CallInst* CI = cast<CallInst>(F->use_back());
+ AllocaInst* bar = new AllocaInst(ArgTy, 0, "vaend.fix.1", CI);
+ new StoreInst(CI->getOperand(1), bar, CI);
+ new CallInst(NF, bar, "", CI);
+ CI->getParent()->getInstList().erase(CI);
+ }
+ Result->getFunctionList().erase(F);
+ }
+
+ if(Function* F = Result->getFunction("llvm.va_copy")) {
+ if(F->arg_size() != 1) {
+ error("Obsolete va_copy takes 1 argument");
+ return 0;
+ }
+ //foo = vacopy(bar)
+ // ->
+ //a = alloca 1 of typeof(foo)
+ //b = alloca 1 of typeof(foo)
+ //store bar -> b
+ //vacopy(a, b)
+ //foo = load a
+
+ const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID);
+ const Type* ArgTy = F->getFunctionType()->getReturnType();
+ const Type* ArgTyPtr = PointerType::get(ArgTy);
+ Function* NF = cast<Function>(Result->getOrInsertFunction(
+ "llvm.va_copy", RetTy, ArgTyPtr, ArgTyPtr, (Type *)0));
+
+ while (!F->use_empty()) {
+ CallInst* CI = cast<CallInst>(F->use_back());
+ AllocaInst* a = new AllocaInst(ArgTy, 0, "vacopy.fix.1", CI);
+ AllocaInst* b = new AllocaInst(ArgTy, 0, "vacopy.fix.2", CI);
+ new StoreInst(CI->getOperand(1), b, CI);
+ new CallInst(NF, a, b, "", CI);
+ Value* foo = new LoadInst(a, "vacopy.fix.3", CI);
+ CI->replaceAllUsesWith(foo);
+ CI->getParent()->getInstList().erase(CI);
+ }
+ Result->getFunctionList().erase(F);
+ }
+ }
+
+ return Result;
+}
+
+} // end llvm namespace
+
+using namespace llvm;
+
+
+
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+/* Enabling the token table. */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+#line 1775 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+typedef union YYSTYPE {
+ llvm::Module *ModuleVal;
+ llvm::Function *FunctionVal;
+ std::pair<llvm::PATypeInfo, char*> *ArgVal;
+ llvm::BasicBlock *BasicBlockVal;
+ llvm::TermInstInfo TermInstVal;
+ llvm::InstrInfo InstVal;
+ llvm::ConstInfo ConstVal;
+ llvm::ValueInfo ValueVal;
+ llvm::PATypeInfo TypeVal;
+ llvm::TypeInfo PrimType;
+ llvm::PHIListInfo PHIList;
+ std::list<llvm::PATypeInfo> *TypeList;
+ std::vector<llvm::ValueInfo> *ValueList;
+ std::vector<llvm::ConstInfo> *ConstVector;
+
+
+ std::vector<std::pair<llvm::PATypeInfo,char*> > *ArgList;
+ // Represent the RHS of PHI node
+ std::vector<std::pair<llvm::Constant*, llvm::BasicBlock*> > *JumpTable;
+
+ llvm::GlobalValue::LinkageTypes Linkage;
+ int64_t SInt64Val;
+ uint64_t UInt64Val;
+ int SIntVal;
+ unsigned UIntVal;
+ double FPVal;
+ bool BoolVal;
+
+ char *StrVal; // This memory is strdup'd!
+ llvm::ValID ValIDVal; // strdup'd memory maybe!
+
+ llvm::BinaryOps BinaryOpVal;
+ llvm::TermOps TermOpVal;
+ llvm::MemoryOps MemOpVal;
+ llvm::OtherOps OtherOpVal;
+ llvm::CastOps CastOpVal;
+ llvm::ICmpInst::Predicate IPred;
+ llvm::FCmpInst::Predicate FPred;
+ llvm::Module::Endianness Endianness;
+} YYSTYPE;
+/* Line 196 of yacc.c. */
+#line 2198 "UpgradeParser.tab.c"
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+/* Copy the second part of user declarations. */
+
+
+/* Line 219 of yacc.c. */
+#line 2210 "UpgradeParser.tab.c"
+
+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
+# define YYSIZE_T __SIZE_TYPE__
+#endif
+#if ! defined (YYSIZE_T) && defined (size_t)
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T) && (defined (__STDC__) || defined (__cplusplus))
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T)
+# define YYSIZE_T unsigned int
+#endif
+
+#ifndef YY_
+# if YYENABLE_NLS
+# if ENABLE_NLS
+# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_(msgid) dgettext ("bison-runtime", msgid)
+# endif
+# endif
+# ifndef YY_
+# define YY_(msgid) msgid
+# endif
+#endif
+
+#if ! defined (yyoverflow) || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# else
+# define YYSTACK_ALLOC alloca
+# if defined (__STDC__) || defined (__cplusplus)
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# define YYINCLUDED_STDLIB_H
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's `empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+# ifndef YYSTACK_ALLOC_MAXIMUM
+ /* The OS might guarantee only one guard page at the bottom of the stack,
+ and a page size can be as small as 4096 bytes. So we cannot safely
+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
+ to allow for a few compiler-allocated temporary stack slots. */
+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2005 */
+# endif
+# else
+# define YYSTACK_ALLOC YYMALLOC
+# define YYSTACK_FREE YYFREE
+# ifndef YYSTACK_ALLOC_MAXIMUM
+# define YYSTACK_ALLOC_MAXIMUM ((YYSIZE_T) -1)
+# endif
+# ifdef __cplusplus
+extern "C" {
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# if (! defined (malloc) && ! defined (YYINCLUDED_STDLIB_H) \
+ && (defined (__STDC__) || defined (__cplusplus)))
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# ifndef YYFREE
+# define YYFREE free
+# if (! defined (free) && ! defined (YYINCLUDED_STDLIB_H) \
+ && (defined (__STDC__) || defined (__cplusplus)))
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# ifdef __cplusplus
+}
+# endif
+# endif
+#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
+
+
+#if (! defined (yyoverflow) \
+ && (! defined (__cplusplus) \
+ || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ short int yyss;
+ YYSTYPE yyvs;
+ };
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (short int) + sizeof (YYSTYPE)) \
+ + YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if defined (__GNUC__) && 1 < __GNUC__
+# define YYCOPY(To, From, Count) \
+ __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+# else
+# define YYCOPY(To, From, Count) \
+ do \
+ { \
+ YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (To)[yyi] = (From)[yyi]; \
+ } \
+ while (0)
+# endif
+# endif
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack, Stack, yysize); \
+ Stack = &yyptr->Stack; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (0)
+
+#endif
+
+#if defined (__STDC__) || defined (__cplusplus)
+ typedef signed char yysigned_char;
+#else
+ typedef short int yysigned_char;
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 4
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 1630
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 166
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 81
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 310
+/* YYNRULES -- Number of states. */
+#define YYNSTATES 606
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 406
+
+#define YYTRANSLATE(YYX) \
+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
+static const unsigned char yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 155, 156, 164, 2, 153, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 160, 152, 161, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 157, 154, 159, 2, 2, 2, 2, 2, 165,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 158, 2, 2, 162, 2, 163, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
+ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
+ 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
+ 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
+ 125, 126, 127, 128, 129, 130, 131, 132, 133, 134,
+ 135, 136, 137, 138, 139, 140, 141, 142, 143, 144,
+ 145, 146, 147, 148, 149, 150, 151
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+ YYRHS. */
+static const unsigned short int yyprhs[] =
+{
+ 0, 0, 3, 5, 7, 9, 11, 13, 15, 17,
+ 19, 21, 23, 25, 27, 29, 31, 33, 35, 37,
+ 39, 41, 43, 45, 47, 49, 51, 53, 55, 57,
+ 59, 61, 63, 65, 67, 69, 71, 73, 75, 77,
+ 79, 81, 83, 85, 87, 89, 91, 93, 95, 97,
+ 99, 101, 103, 105, 107, 109, 111, 113, 115, 117,
+ 119, 121, 123, 125, 127, 129, 131, 133, 135, 137,
+ 139, 141, 143, 145, 147, 149, 151, 153, 155, 157,
+ 159, 161, 164, 165, 167, 169, 171, 173, 175, 177,
+ 179, 180, 181, 183, 185, 187, 189, 191, 193, 196,
+ 197, 200, 201, 205, 208, 209, 211, 212, 216, 218,
+ 221, 223, 225, 227, 229, 231, 233, 235, 237, 239,
+ 241, 243, 245, 247, 249, 251, 253, 255, 257, 259,
+ 261, 264, 269, 275, 281, 285, 288, 294, 299, 302,
+ 304, 308, 310, 314, 316, 317, 322, 326, 330, 335,
+ 340, 344, 351, 357, 360, 363, 366, 369, 372, 375,
+ 378, 381, 384, 387, 394, 400, 409, 416, 423, 430,
+ 438, 446, 453, 460, 469, 478, 482, 484, 486, 488,
+ 490, 493, 496, 501, 504, 506, 511, 514, 519, 520,
+ 528, 529, 537, 538, 546, 547, 555, 559, 564, 565,
+ 567, 569, 571, 575, 579, 583, 587, 591, 595, 597,
+ 598, 600, 602, 604, 605, 608, 612, 614, 616, 620,
+ 622, 623, 632, 634, 636, 637, 642, 644, 646, 649,
+ 650, 652, 654, 655, 656, 662, 663, 665, 667, 669,
+ 671, 673, 675, 677, 679, 681, 685, 687, 693, 695,
+ 697, 699, 701, 704, 707, 710, 714, 717, 718, 720,
+ 722, 724, 727, 730, 734, 744, 754, 763, 777, 779,
+ 781, 788, 794, 797, 804, 812, 814, 818, 820, 821,
+ 824, 826, 832, 838, 844, 851, 858, 861, 866, 871,
+ 878, 883, 888, 893, 898, 905, 912, 915, 923, 925,
+ 928, 929, 931, 932, 936, 943, 947, 954, 957, 962,
+ 969
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const short int yyrhs[] =
+{
+ 200, 0, -1, 5, -1, 6, -1, 3, -1, 4,
+ -1, 79, -1, 80, -1, 81, -1, 82, -1, 83,
+ -1, 84, -1, 85, -1, 86, -1, 87, -1, 88,
+ -1, 89, -1, 90, -1, 91, -1, 92, -1, 97,
+ -1, 98, -1, 99, -1, 100, -1, 101, -1, 102,
+ -1, 119, -1, 120, -1, 121, -1, 122, -1, 123,
+ -1, 124, -1, 125, -1, 126, -1, 127, -1, 128,
+ -1, 129, -1, 130, -1, 131, -1, 132, -1, 133,
+ -1, 134, -1, 135, -1, 136, -1, 137, -1, 138,
+ -1, 125, -1, 126, -1, 127, -1, 128, -1, 27,
+ -1, 28, -1, 93, -1, 94, -1, 95, -1, 96,
+ -1, 140, -1, 141, -1, 142, -1, 143, -1, 144,
+ -1, 145, -1, 146, -1, 147, -1, 148, -1, 149,
+ -1, 150, -1, 151, -1, 139, -1, 16, -1, 14,
+ -1, 12, -1, 10, -1, 17, -1, 15, -1, 13,
+ -1, 11, -1, 176, -1, 177, -1, 18, -1, 19,
+ -1, 212, 152, -1, -1, 41, -1, 42, -1, 43,
+ -1, 44, -1, 45, -1, 46, -1, 47, -1, -1,
+ -1, 65, -1, 66, -1, 67, -1, 68, -1, 69,
+ -1, 70, -1, 64, 4, -1, -1, 57, 4, -1,
+ -1, 153, 57, 4, -1, 34, 24, -1, -1, 185,
+ -1, -1, 153, 188, 187, -1, 185, -1, 57, 4,
+ -1, 191, -1, 8, -1, 193, -1, 8, -1, 193,
+ -1, 9, -1, 10, -1, 11, -1, 12, -1, 13,
+ -1, 14, -1, 15, -1, 16, -1, 17, -1, 18,
+ -1, 19, -1, 21, -1, 192, -1, 48, -1, 229,
+ -1, 154, 4, -1, 190, 155, 195, 156, -1, 157,
+ 4, 158, 193, 159, -1, 160, 4, 158, 193, 161,
+ -1, 162, 194, 163, -1, 162, 163, -1, 160, 162,
+ 194, 163, 161, -1, 160, 162, 163, 161, -1, 193,
+ 164, -1, 193, -1, 194, 153, 193, -1, 194, -1,
+ 194, 153, 37, -1, 37, -1, -1, 191, 157, 198,
+ 159, -1, 191, 157, 159, -1, 191, 165, 24, -1,
+ 191, 160, 198, 161, -1, 191, 162, 198, 163, -1,
+ 191, 162, 163, -1, 191, 160, 162, 198, 163, 161,
+ -1, 191, 160, 162, 163, 161, -1, 191, 38, -1,
+ 191, 39, -1, 191, 229, -1, 191, 197, -1, 191,
+ 26, -1, 176, 168, -1, 177, 4, -1, 9, 27,
+ -1, 9, 28, -1, 179, 7, -1, 175, 155, 196,
+ 36, 191, 156, -1, 110, 155, 196, 244, 156, -1,
+ 112, 155, 196, 153, 196, 153, 196, 156, -1, 169,
+ 155, 196, 153, 196, 156, -1, 170, 155, 196, 153,
+ 196, 156, -1, 171, 155, 196, 153, 196, 156, -1,
+ 103, 172, 155, 196, 153, 196, 156, -1, 104, 173,
+ 155, 196, 153, 196, 156, -1, 174, 155, 196, 153,
+ 196, 156, -1, 114, 155, 196, 153, 196, 156, -1,
+ 115, 155, 196, 153, 196, 153, 196, 156, -1, 116,
+ 155, 196, 153, 196, 153, 196, 156, -1, 198, 153,
+ 196, -1, 196, -1, 32, -1, 33, -1, 201, -1,
+ 201, 222, -1, 201, 224, -1, 201, 62, 61, 207,
+ -1, 201, 25, -1, 202, -1, 202, 180, 20, 189,
+ -1, 202, 224, -1, 202, 62, 61, 207, -1, -1,
+ 202, 180, 181, 199, 196, 203, 187, -1, -1, 202,
+ 180, 50, 199, 191, 204, 187, -1, -1, 202, 180,
+ 45, 199, 191, 205, 187, -1, -1, 202, 180, 47,
+ 199, 191, 206, 187, -1, 202, 51, 209, -1, 202,
+ 58, 152, 210, -1, -1, 24, -1, 56, -1, 55,
+ -1, 53, 152, 208, -1, 54, 152, 4, -1, 52,
+ 152, 24, -1, 71, 152, 24, -1, 157, 211, 159,
+ -1, 211, 153, 24, -1, 24, -1, -1, 22, -1,
+ 24, -1, 212, -1, -1, 191, 213, -1, 215, 153,
+ 214, -1, 214, -1, 215, -1, 215, 153, 37, -1,
+ 37, -1, -1, 182, 189, 212, 155, 216, 156, 186,
+ 183, -1, 29, -1, 162, -1, -1, 181, 220, 217,
+ 218, -1, 30, -1, 163, -1, 232, 221, -1, -1,
+ 45, -1, 47, -1, -1, -1, 31, 225, 223, 226,
+ 217, -1, -1, 63, -1, 3, -1, 4, -1, 7,
+ -1, 27, -1, 28, -1, 38, -1, 39, -1, 26,
+ -1, 160, 198, 161, -1, 197, -1, 61, 227, 24,
+ 153, 24, -1, 167, -1, 212, -1, 229, -1, 228,
+ -1, 191, 230, -1, 232, 233, -1, 219, 233, -1,
+ 234, 180, 236, -1, 234, 238, -1, -1, 23, -1,
+ 77, -1, 78, -1, 72, 231, -1, 72, 8, -1,
+ 73, 21, 230, -1, 73, 9, 230, 153, 21, 230,
+ 153, 21, 230, -1, 74, 178, 230, 153, 21, 230,
+ 157, 237, 159, -1, 74, 178, 230, 153, 21, 230,
+ 157, 159, -1, 75, 182, 189, 230, 155, 241, 156,
+ 36, 21, 230, 235, 21, 230, -1, 235, -1, 76,
+ -1, 237, 178, 228, 153, 21, 230, -1, 178, 228,
+ 153, 21, 230, -1, 180, 243, -1, 191, 157, 230,
+ 153, 230, 159, -1, 239, 153, 157, 230, 153, 230,
+ 159, -1, 231, -1, 240, 153, 231, -1, 240, -1,
+ -1, 60, 59, -1, 59, -1, 169, 191, 230, 153,
+ 230, -1, 170, 191, 230, 153, 230, -1, 171, 191,
+ 230, 153, 230, -1, 103, 172, 191, 230, 153, 230,
+ -1, 104, 173, 191, 230, 153, 230, -1, 49, 231,
+ -1, 174, 231, 153, 231, -1, 175, 231, 36, 191,
+ -1, 112, 231, 153, 231, 153, 231, -1, 113, 231,
+ 153, 191, -1, 117, 231, 153, 191, -1, 118, 231,
+ 153, 191, -1, 114, 231, 153, 231, -1, 115, 231,
+ 153, 231, 153, 231, -1, 116, 231, 153, 231, 153,
+ 231, -1, 111, 239, -1, 242, 182, 189, 230, 155,
+ 241, 156, -1, 246, -1, 153, 240, -1, -1, 35,
+ -1, -1, 105, 191, 184, -1, 105, 191, 153, 15,
+ 230, 184, -1, 106, 191, 184, -1, 106, 191, 153,
+ 15, 230, 184, -1, 107, 231, -1, 245, 108, 191,
+ 230, -1, 245, 109, 231, 153, 191, 230, -1, 110,
+ 191, 230, 244, -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const unsigned short int yyrline[] =
+{
+ 0, 1915, 1915, 1916, 1924, 1925, 1935, 1935, 1935, 1935,
+ 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1939, 1939, 1939,
+ 1943, 1943, 1943, 1943, 1943, 1943, 1947, 1947, 1948, 1948,
+ 1949, 1949, 1950, 1950, 1951, 1951, 1955, 1955, 1956, 1956,
+ 1957, 1957, 1958, 1958, 1959, 1959, 1960, 1960, 1961, 1961,
+ 1962, 1963, 1966, 1966, 1966, 1966, 1970, 1970, 1970, 1970,
+ 1970, 1970, 1970, 1971, 1971, 1971, 1971, 1971, 1971, 1977,
+ 1977, 1977, 1977, 1981, 1981, 1981, 1981, 1985, 1985, 1989,
+ 1989, 1994, 1997, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
+ 2009, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2030,
+ 2031, 2039, 2040, 2048, 2057, 2058, 2065, 2066, 2070, 2074,
+ 2090, 2091, 2098, 2099, 2106, 2114, 2114, 2114, 2114, 2114,
+ 2114, 2114, 2115, 2115, 2115, 2115, 2115, 2120, 2124, 2128,
+ 2133, 2142, 2169, 2175, 2188, 2199, 2203, 2216, 2220, 2234,
+ 2238, 2245, 2246, 2252, 2259, 2271, 2301, 2314, 2337, 2365,
+ 2387, 2398, 2420, 2431, 2440, 2445, 2504, 2511, 2519, 2526,
+ 2533, 2537, 2541, 2550, 2565, 2577, 2586, 2614, 2627, 2636,
+ 2642, 2648, 2659, 2665, 2671, 2682, 2683, 2692, 2693, 2705,
+ 2714, 2715, 2716, 2717, 2718, 2734, 2754, 2756, 2758, 2758,
+ 2765, 2765, 2773, 2773, 2781, 2781, 2790, 2792, 2794, 2799,
+ 2813, 2814, 2818, 2821, 2829, 2833, 2840, 2844, 2848, 2852,
+ 2860, 2860, 2864, 2865, 2869, 2877, 2882, 2890, 2891, 2898,
+ 2905, 2909, 3099, 3099, 3103, 3103, 3113, 3113, 3117, 3122,
+ 3123, 3124, 3128, 3129, 3128, 3141, 3142, 3147, 3148, 3149,
+ 3150, 3154, 3158, 3159, 3160, 3161, 3182, 3186, 3200, 3201,
+ 3206, 3206, 3214, 3224, 3227, 3236, 3247, 3252, 3261, 3272,
+ 3272, 3275, 3279, 3283, 3288, 3298, 3316, 3325, 3398, 3402,
+ 3409, 3421, 3436, 3466, 3476, 3486, 3490, 3497, 3498, 3502,
+ 3505, 3511, 3530, 3548, 3564, 3578, 3592, 3603, 3621, 3630,
+ 3639, 3646, 3667, 3691, 3697, 3703, 3709, 3725, 3818, 3826,
+ 3827, 3831, 3832, 3836, 3842, 3849, 3855, 3862, 3869, 3882,
+ 3908
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ "$end", "error", "$undefined", "ESINT64VAL", "EUINT64VAL", "SINTVAL",
+ "UINTVAL", "FPVAL", "VOID", "BOOL", "SBYTE", "UBYTE", "SHORT", "USHORT",
+ "INT", "UINT", "LONG", "ULONG", "FLOAT", "DOUBLE", "TYPE", "LABEL",
+ "VAR_ID", "LABELSTR", "STRINGCONSTANT", "IMPLEMENTATION",
+ "ZEROINITIALIZER", "TRUETOK", "FALSETOK", "BEGINTOK", "ENDTOK",
+ "DECLARE", "GLOBAL", "CONSTANT", "SECTION", "VOLATILE", "TO",
+ "DOTDOTDOT", "NULL_TOK", "UNDEF", "CONST", "INTERNAL", "LINKONCE",
+ "WEAK", "APPENDING", "DLLIMPORT", "DLLEXPORT", "EXTERN_WEAK", "OPAQUE",
+ "NOT", "EXTERNAL", "TARGET", "TRIPLE", "ENDIAN", "POINTERSIZE", "LITTLE",
+ "BIG", "ALIGN", "DEPLIBS", "CALL", "TAIL", "ASM_TOK", "MODULE",
+ "SIDEEFFECT", "CC_TOK", "CCC_TOK", "CSRETCC_TOK", "FASTCC_TOK",
+ "COLDCC_TOK", "X86_STDCALLCC_TOK", "X86_FASTCALLCC_TOK", "DATALAYOUT",
+ "RET", "BR", "SWITCH", "INVOKE", "UNREACHABLE", "UNWIND", "EXCEPT",
+ "ADD", "SUB", "MUL", "DIV", "UDIV", "SDIV", "FDIV", "REM", "UREM",
+ "SREM", "FREM", "AND", "OR", "XOR", "SHL", "SHR", "ASHR", "LSHR",
+ "SETLE", "SETGE", "SETLT", "SETGT", "SETEQ", "SETNE", "ICMP", "FCMP",
+ "MALLOC", "ALLOCA", "FREE", "LOAD", "STORE", "GETELEMENTPTR", "PHI_TOK",
+ "SELECT", "VAARG", "EXTRACTELEMENT", "INSERTELEMENT", "SHUFFLEVECTOR",
+ "VAARG_old", "VANEXT_old", "EQ", "NE", "SLT", "SGT", "SLE", "SGE", "ULT",
+ "UGT", "ULE", "UGE", "OEQ", "ONE", "OLT", "OGT", "OLE", "OGE", "ORD",
+ "UNO", "UEQ", "UNE", "CAST", "TRUNC", "ZEXT", "SEXT", "FPTRUNC", "FPEXT",
+ "FPTOUI", "FPTOSI", "UITOFP", "SITOFP", "PTRTOINT", "INTTOPTR",
+ "BITCAST", "'='", "','", "'\\\\'", "'('", "')'", "'['", "'x'", "']'",
+ "'<'", "'>'", "'{'", "'}'", "'*'", "'c'", "$accept", "INTVAL",
+ "EINT64VAL", "ArithmeticOps", "LogicalOps", "SetCondOps", "IPredicates",
+ "FPredicates", "ShiftOps", "CastOps", "SIntType", "UIntType", "IntType",
+ "FPType", "OptAssign", "OptLinkage", "OptCallingConv", "OptAlign",
+ "OptCAlign", "SectionString", "OptSection", "GlobalVarAttributes",
+ "GlobalVarAttribute", "TypesV", "UpRTypesV", "Types", "PrimType",
+ "UpRTypes", "TypeListI", "ArgTypeListI", "ConstVal", "ConstExpr",
+ "ConstVector", "GlobalType", "Module", "FunctionList", "ConstPool", "@1",
+ "@2", "@3", "@4", "AsmBlock", "BigOrLittle", "TargetDefinition",
+ "LibrariesDefinition", "LibList", "Name", "OptName", "ArgVal",
+ "ArgListH", "ArgList", "FunctionHeaderH", "BEGIN", "FunctionHeader",
+ "@5", "END", "Function", "FnDeclareLinkage", "FunctionProto", "@6", "@7",
+ "OptSideEffect", "ConstValueRef", "SymbolicValueRef", "ValueRef",
+ "ResolvedVal", "BasicBlockList", "BasicBlock", "InstructionList",
+ "Unwind", "BBTerminatorInst", "JumpTable", "Inst", "PHIList",
+ "ValueRefList", "ValueRefListE", "OptTailCall", "InstVal", "IndexList",
+ "OptVolatile", "MemoryInst", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+ token YYLEX-NUM. */
+static const unsigned short int yytoknum[] =
+{
+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
+ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
+ 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
+ 295, 296, 297, 298, 299, 300, 301, 302, 303, 304,
+ 305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
+ 315, 316, 317, 318, 319, 320, 321, 322, 323, 324,
+ 325, 326, 327, 328, 329, 330, 331, 332, 333, 334,
+ 335, 336, 337, 338, 339, 340, 341, 342, 343, 344,
+ 345, 346, 347, 348, 349, 350, 351, 352, 353, 354,
+ 355, 356, 357, 358, 359, 360, 361, 362, 363, 364,
+ 365, 366, 367, 368, 369, 370, 371, 372, 373, 374,
+ 375, 376, 377, 378, 379, 380, 381, 382, 383, 384,
+ 385, 386, 387, 388, 389, 390, 391, 392, 393, 394,
+ 395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+ 405, 406, 61, 44, 92, 40, 41, 91, 120, 93,
+ 60, 62, 123, 125, 42, 99
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const unsigned char yyr1[] =
+{
+ 0, 166, 167, 167, 168, 168, 169, 169, 169, 169,
+ 169, 169, 169, 169, 169, 169, 169, 170, 170, 170,
+ 171, 171, 171, 171, 171, 171, 172, 172, 172, 172,
+ 172, 172, 172, 172, 172, 172, 173, 173, 173, 173,
+ 173, 173, 173, 173, 173, 173, 173, 173, 173, 173,
+ 173, 173, 174, 174, 174, 174, 175, 175, 175, 175,
+ 175, 175, 175, 175, 175, 175, 175, 175, 175, 176,
+ 176, 176, 176, 177, 177, 177, 177, 178, 178, 179,
+ 179, 180, 180, 181, 181, 181, 181, 181, 181, 181,
+ 181, 182, 182, 182, 182, 182, 182, 182, 182, 183,
+ 183, 184, 184, 185, 186, 186, 187, 187, 188, 188,
+ 189, 189, 190, 190, 191, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193, 193, 194,
+ 194, 195, 195, 195, 195, 196, 196, 196, 196, 196,
+ 196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+ 196, 196, 196, 197, 197, 197, 197, 197, 197, 197,
+ 197, 197, 197, 197, 197, 198, 198, 199, 199, 200,
+ 201, 201, 201, 201, 201, 202, 202, 202, 203, 202,
+ 204, 202, 205, 202, 206, 202, 202, 202, 202, 207,
+ 208, 208, 209, 209, 209, 209, 210, 211, 211, 211,
+ 212, 212, 213, 213, 214, 215, 215, 216, 216, 216,
+ 216, 217, 218, 218, 220, 219, 221, 221, 222, 223,
+ 223, 223, 225, 226, 224, 227, 227, 228, 228, 228,
+ 228, 228, 228, 228, 228, 228, 228, 228, 229, 229,
+ 230, 230, 231, 232, 232, 233, 234, 234, 234, 235,
+ 235, 236, 236, 236, 236, 236, 236, 236, 236, 236,
+ 237, 237, 238, 239, 239, 240, 240, 241, 241, 242,
+ 242, 243, 243, 243, 243, 243, 243, 243, 243, 243,
+ 243, 243, 243, 243, 243, 243, 243, 243, 243, 244,
+ 244, 245, 245, 246, 246, 246, 246, 246, 246, 246,
+ 246
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const unsigned char yyr2[] =
+{
+ 0, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 0, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 1, 1, 1, 1, 1, 1, 2, 0,
+ 2, 0, 3, 2, 0, 1, 0, 3, 1, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 4, 5, 5, 3, 2, 5, 4, 2, 1,
+ 3, 1, 3, 1, 0, 4, 3, 3, 4, 4,
+ 3, 6, 5, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 6, 5, 8, 6, 6, 6, 7,
+ 7, 6, 6, 8, 8, 3, 1, 1, 1, 1,
+ 2, 2, 4, 2, 1, 4, 2, 4, 0, 7,
+ 0, 7, 0, 7, 0, 7, 3, 4, 0, 1,
+ 1, 1, 3, 3, 3, 3, 3, 3, 1, 0,
+ 1, 1, 1, 0, 2, 3, 1, 1, 3, 1,
+ 0, 8, 1, 1, 0, 4, 1, 1, 2, 0,
+ 1, 1, 0, 0, 5, 0, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 3, 1, 5, 1, 1,
+ 1, 1, 2, 2, 2, 3, 2, 0, 1, 1,
+ 1, 2, 2, 3, 9, 9, 8, 13, 1, 1,
+ 6, 5, 2, 6, 7, 1, 3, 1, 0, 2,
+ 1, 5, 5, 5, 6, 6, 2, 4, 4, 6,
+ 4, 4, 4, 4, 6, 6, 2, 7, 1, 2,
+ 0, 1, 0, 3, 6, 3, 6, 2, 4, 6,
+ 4
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero
+ means the default is an error. */
+static const unsigned short int yydefact[] =
+{
+ 198, 0, 90, 184, 1, 183, 232, 83, 84, 85,
+ 86, 87, 88, 89, 0, 224, 257, 180, 181, 257,
+ 210, 211, 0, 0, 0, 90, 0, 186, 229, 0,
+ 91, 258, 254, 82, 226, 227, 228, 253, 0, 0,
+ 0, 0, 196, 0, 0, 0, 0, 0, 0, 0,
+ 81, 230, 231, 233, 199, 182, 0, 92, 93, 94,
+ 95, 96, 97, 0, 0, 302, 256, 0, 0, 0,
+ 0, 209, 197, 187, 2, 3, 111, 115, 116, 117,
+ 118, 119, 120, 121, 122, 123, 124, 125, 126, 128,
+ 0, 0, 0, 0, 248, 185, 0, 110, 127, 114,
+ 249, 129, 177, 178, 0, 0, 0, 0, 91, 98,
+ 0, 222, 223, 225, 301, 0, 280, 0, 0, 0,
+ 0, 91, 269, 259, 260, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 52,
+ 53, 54, 55, 20, 21, 22, 23, 24, 25, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 68, 56, 57, 58, 59, 60, 61,
+ 62, 63, 64, 65, 66, 67, 0, 0, 0, 0,
+ 0, 268, 255, 91, 272, 0, 298, 204, 201, 200,
+ 202, 203, 205, 208, 0, 130, 0, 0, 0, 113,
+ 135, 139, 0, 144, 138, 192, 194, 190, 115, 116,
+ 117, 118, 119, 120, 121, 122, 123, 124, 125, 0,
+ 0, 0, 0, 188, 234, 0, 0, 286, 279, 262,
+ 261, 0, 0, 72, 76, 71, 75, 70, 74, 69,
+ 73, 77, 78, 0, 0, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 0, 50, 51, 46, 47,
+ 48, 49, 36, 37, 38, 39, 40, 41, 42, 43,
+ 44, 45, 0, 101, 101, 307, 0, 0, 296, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 206, 0, 0, 0, 0,
+ 0, 134, 143, 141, 0, 106, 106, 106, 160, 161,
+ 4, 5, 158, 159, 162, 157, 153, 154, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 156, 155, 106, 220, 237, 238,
+ 239, 244, 240, 241, 242, 243, 235, 0, 246, 251,
+ 250, 252, 0, 263, 0, 0, 0, 0, 0, 303,
+ 0, 305, 300, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 207, 112, 112, 137, 0, 140, 0, 131, 0, 193,
+ 195, 191, 0, 0, 0, 0, 0, 0, 0, 146,
+ 176, 0, 0, 0, 150, 0, 147, 0, 0, 0,
+ 0, 0, 189, 219, 213, 216, 217, 0, 236, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 310, 0, 0, 0, 290, 293, 0, 0, 291, 292,
+ 0, 0, 0, 287, 288, 0, 308, 0, 132, 133,
+ 136, 142, 0, 0, 108, 106, 0, 0, 300, 0,
+ 0, 0, 0, 0, 145, 135, 114, 0, 148, 149,
+ 0, 0, 0, 0, 0, 212, 214, 0, 104, 0,
+ 245, 0, 0, 278, 0, 0, 101, 102, 101, 275,
+ 299, 0, 0, 0, 0, 0, 281, 282, 283, 278,
+ 0, 103, 109, 107, 0, 0, 0, 0, 0, 0,
+ 0, 175, 152, 0, 0, 0, 0, 0, 0, 218,
+ 215, 105, 99, 0, 0, 0, 277, 0, 284, 285,
+ 0, 304, 306, 0, 0, 0, 289, 294, 295, 0,
+ 309, 0, 0, 164, 0, 0, 0, 0, 151, 0,
+ 0, 0, 0, 0, 0, 221, 247, 0, 0, 0,
+ 276, 273, 0, 297, 0, 0, 0, 172, 0, 0,
+ 166, 167, 168, 171, 163, 100, 0, 266, 0, 0,
+ 0, 274, 169, 170, 0, 0, 0, 264, 0, 265,
+ 0, 0, 165, 173, 174, 0, 0, 0, 0, 0,
+ 0, 271, 0, 0, 270, 267
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const short int yydefgoto[] =
+{
+ -1, 94, 312, 329, 330, 331, 255, 272, 332, 333,
+ 219, 220, 243, 221, 25, 15, 63, 555, 359, 454,
+ 522, 389, 455, 95, 96, 222, 98, 99, 202, 304,
+ 400, 348, 401, 104, 1, 2, 3, 336, 307, 305,
+ 306, 55, 190, 42, 72, 194, 100, 476, 415, 416,
+ 417, 64, 113, 16, 30, 36, 17, 53, 18, 28,
+ 108, 419, 349, 101, 351, 489, 19, 32, 33, 181,
+ 182, 579, 66, 278, 526, 527, 183, 184, 430, 185,
+ 186
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+#define YYPACT_NINF -542
+static const short int yypact[] =
+{
+ -542, 13, 162, 567, -542, -542, -542, -542, -542, -542,
+ -542, -542, -542, -542, 83, -542, 19, -542, -542, -14,
+ -542, -542, 50, -87, 87, 233, 27, -542, 123, 141,
+ 175, -542, -542, 98, -542, -542, -542, -542, 33, 40,
+ 66, 68, -542, 14, 141, 1265, 156, 156, 156, 156,
+ -542, -542, -542, -542, -542, -542, 221, -542, -542, -542,
+ -542, -542, -542, 1265, -19, 1479, -542, 204, 135, 226,
+ 227, 235, -542, -542, -542, -542, 81, -542, -542, -542,
+ -542, -542, -542, -542, -542, -542, -542, -542, -542, -542,
+ 256, 257, 4, 15, -542, -542, 108, -542, -542, 12,
+ -542, -542, -542, -542, 1306, 1306, 1306, 1326, 175, -542,
+ 98, -542, -542, -542, -542, 1306, -542, 205, 1367, 116,
+ 479, 175, -542, -542, -542, -542, -542, -542, -542, -542,
+ -542, -542, -542, -542, -542, -542, -542, -542, -542, -542,
+ -542, -542, -542, -542, -542, -542, -542, -542, -542, 355,
+ 429, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306,
+ 1306, 1306, 1306, -542, -542, -542, -542, -542, -542, -542,
+ -542, -542, -542, -542, -542, -542, 1306, 1306, 1306, 1306,
+ 1306, -542, -542, 175, -542, 86, -542, -542, -542, -542,
+ -542, -542, -542, -542, -13, -542, 110, 111, 75, -542,
+ -542, 12, -81, 1046, -542, -542, -542, -542, 174, 208,
+ 266, 210, 267, 212, 268, 230, 277, 275, 278, 246,
+ 280, 279, 566, -542, -542, 136, 766, -542, -542, 81,
+ -542, 766, 766, -542, -542, -542, -542, -542, -542, -542,
+ -542, -542, -542, 766, 1265, -542, -542, -542, -542, -542,
+ -542, -542, -542, -542, -542, 1306, -542, -542, -542, -542,
+ -542, -542, -542, -542, -542, -542, -542, -542, -542, -542,
+ -542, -542, 1306, 137, 145, -542, 766, 132, 146, 147,
+ 148, 149, 151, 152, 158, 160, 766, 766, 766, 161,
+ 281, 1265, 1306, 1306, 291, -542, 1306, 1306, 155, -27,
+ 1306, -542, -542, 165, 163, 176, 176, 176, -542, -542,
+ -542, -542, -542, -542, -542, -542, -542, -542, 355, 429,
+ 172, 177, 178, 179, 182, 1087, 1387, 529, 311, 184,
+ 185, 186, 188, 189, -542, -542, 176, 1107, -542, -542,
+ -542, -542, -542, -542, -542, -542, 282, 1326, -542, -542,
+ -542, -542, 193, -542, 194, 766, 766, 766, 7, -542,
+ 20, -542, 195, 766, 192, 1306, 1306, 1306, 1306, 1306,
+ 1306, 1306, 200, 201, 206, 1306, 1306, 766, 766, 207,
+ -542, -59, -149, -542, 196, 12, 1148, -542, 44, -542,
+ -542, -542, 203, 211, 1326, 1326, 1326, 1326, 1326, -542,
+ -542, -8, 741, -82, -542, 10, -542, 1326, 1326, 1326,
+ 1326, 1326, -542, -542, 98, -542, 214, 209, -542, 337,
+ -34, 342, 348, 215, 218, 219, 766, 371, 766, 1306,
+ -542, 223, 766, 224, -542, -542, 225, 234, -542, -542,
+ 766, 766, 766, -542, -542, 228, -542, 1306, -542, -542,
+ -542, -542, 362, 375, -542, 176, 1326, 1326, 195, 236,
+ 237, 240, 243, 1326, -542, 238, -25, 11, -542, -542,
+ 244, 245, 247, 250, 352, -542, -542, 1205, 370, 252,
+ -542, 766, 766, 1306, 766, 766, 258, -542, 258, -542,
+ 259, 766, 264, 1306, 1306, 1306, -542, -542, -542, 1306,
+ 766, -542, -542, -542, 270, 271, 263, 1326, 1326, 1326,
+ 1326, -542, -542, 260, 1326, 1326, 1326, 1326, 1306, -542,
+ -542, -542, 368, 402, 274, 276, 259, 287, -542, -542,
+ 374, -542, -542, 1306, 285, 766, -542, -542, -542, 290,
+ -542, 1326, 1326, -542, 283, 295, 284, 294, -542, 296,
+ 297, 299, 302, 303, 430, -542, -542, 414, 41, 425,
+ -542, -542, 305, -542, 306, 310, 1326, -542, 1326, 1326,
+ -542, -542, -542, -542, -542, -542, 766, -542, 893, 144,
+ 448, -542, -542, -542, 314, 315, 316, -542, 331, -542,
+ 893, 766, -542, -542, -542, 464, 334, 180, 766, 481,
+ 482, -542, 766, 766, -542, -542
+};
+
+/* YYPGOTO[NTERM-NUM]. */
+static const short int yypgoto[] =
+{
+ -542, -542, -542, 435, 439, 441, 191, 197, 442, 445,
+ -119, -116, -541, -542, 478, 489, -107, -542, -267, 37,
+ -542, -238, -542, -60, -542, -45, -542, -74, -51, -542,
+ -101, 300, -252, 134, -542, -542, -542, -542, -542, -542,
+ -542, 473, -542, -542, -542, -542, 8, -542, 46, -542,
+ -542, 410, -542, -542, -542, -542, -542, -542, 518, -542,
+ -542, -542, -528, 142, -90, -113, -542, 505, -542, -72,
+ -542, -542, -542, -542, 97, 28, -542, -542, 70, -542,
+ -542
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule which
+ number is the opposite. If zero, do what YYDEFACT says.
+ If YYTABLE_NINF, syntax error. */
+#define YYTABLE_NINF -180
+static const short int yytable[] =
+{
+ 97, 241, 227, 110, 242, 230, 223, 361, 197, 31,
+ 111, 26, 449, 4, 244, 204, 34, 578, 97, 201,
+ 74, 75, 426, 199, 77, 78, 79, 80, 81, 82,
+ 83, 84, 85, 86, 87, 428, 88, 20, 590, 21,
+ 275, 26, 31, 279, 280, 281, 282, 283, 284, 285,
+ 588, 233, 234, 235, 236, 237, 238, 239, 240, 205,
+ 206, 207, 596, 89, 427, 43, 289, 290, 390, 391,
+ 226, 463, 300, 226, 403, 405, 291, 427, 452, 468,
+ 74, 75, 301, 199, 77, 78, 79, 80, 81, 82,
+ 83, 84, 85, 86, 87, 420, 88, 20, 412, 21,
+ 448, 453, 38, 39, 40, 204, 273, 274, 226, 276,
+ 277, 226, 226, 226, 226, 226, 226, 226, 225, 463,
+ 20, 41, 21, 89, 201, 231, 300, 480, -139, 201,
+ -112, 286, 287, 288, 226, 226, 384, 232, -139, 204,
+ 294, 352, 353, 112, 29, 463, 295, 299, 44, 35,
+ 467, 464, 303, 354, 233, 234, 235, 236, 237, 238,
+ 239, 240, -179, 463, 463, 54, 198, -112, 51, 90,
+ 52, 71, 91, 469, 513, 92, 204, 93, 200, 50,
+ 379, 105, 106, 107, 355, 67, 362, 5, 102, 103,
+ 188, 189, 68, 6, 292, 293, 372, 373, 374, 97,
+ 577, 308, 309, 7, 8, 9, 10, 11, 12, 13,
+ 356, -72, -72, -71, -71, -70, -70, 503, 69, 531,
+ 70, 532, 381, 382, 14, 109, 385, 357, 187, 90,
+ 191, 377, 91, -69, -69, 92, -113, 93, 298, 56,
+ 57, 58, 59, 60, 61, 62, 97, 378, 226, 310,
+ 311, 192, 433, 45, 435, 436, 437, 123, 124, 193,
+ 195, 196, 443, 203, 228, 423, 424, 425, 296, 297,
+ -76, -75, -74, 431, 7, 8, 9, 10, 46, 12,
+ 47, -73, -79, 48, 313, -80, 314, 445, 446, 363,
+ 358, 337, 414, 458, 459, 460, 461, 462, 360, 364,
+ 365, 366, 367, 589, 368, 369, 470, 471, 472, 473,
+ 474, 370, 385, 371, 375, 380, 383, 376, 386, 387,
+ 226, 434, 226, 226, 226, 438, 439, 394, 466, 388,
+ 226, 444, 395, 396, 397, 406, 486, 398, 488, 407,
+ 408, 409, 492, 410, 411, 418, 421, 422, 429, 432,
+ 496, 497, 498, 440, 441, 504, 505, 450, 456, 442,
+ 447, 479, 511, 481, 335, 478, 457, 477, 350, 482,
+ 483, 484, 485, 350, 350, 487, 491, 493, 494, 502,
+ 536, 537, 538, 499, 226, 350, 501, 495, 518, 507,
+ 508, 524, 525, 509, 528, 529, 510, 514, 515, 512,
+ 516, 534, 500, 517, 452, 523, 544, 545, 546, 547,
+ 540, 530, 533, 549, 550, 551, 552, 535, 350, 543,
+ 560, 548, 475, 541, 542, 554, 556, 557, 350, 350,
+ 350, 427, 414, 558, 575, 576, 566, 568, 226, 241,
+ 564, 565, 242, 559, 561, 562, 563, 569, 226, 226,
+ 226, 567, 570, 571, 226, 572, 256, 257, 573, 574,
+ 241, 580, 582, 242, 581, 584, 583, 585, 586, 591,
+ 592, 593, 594, 553, 245, 246, 247, 248, 249, 250,
+ 251, 252, 253, 254, 595, 598, 587, 599, 226, 233,
+ 234, 235, 236, 237, 238, 239, 240, 350, 350, 350,
+ 176, 597, 602, 603, 177, 350, 178, 179, 601, 392,
+ 180, 65, 604, 605, 49, 521, 393, 73, 224, 350,
+ 350, 27, 334, 520, 37, 600, 490, 539, 506, 0,
+ 0, 0, 0, 0, 74, 75, 0, 199, 208, 209,
+ 210, 211, 212, 213, 214, 215, 216, 217, 218, 0,
+ 88, 20, 0, 21, 258, 259, 260, 261, 262, 263,
+ 264, 265, 266, 267, 268, 269, 270, 271, 350, 0,
+ 350, 74, 75, 0, 350, 0, 0, 89, 0, 0,
+ 0, 0, 350, 350, 350, 0, 0, -82, 20, 20,
+ 21, 21, 315, 0, 0, 0, 0, 0, 6, -82,
+ -82, 0, 0, 0, 316, 317, 0, 0, -82, -82,
+ -82, -82, -82, -82, -82, 0, 0, -82, 22, 0,
+ 0, 0, 0, 350, 350, 23, 350, 350, 0, 24,
+ 0, 0, 0, 350, 0, 0, 0, 0, 0, 0,
+ 0, 0, 350, 0, 0, 125, 126, 127, 128, 129,
+ 130, 131, 132, 133, 134, 135, 136, 137, 138, 139,
+ 140, 141, 142, 143, 144, 145, 146, 147, 148, 318,
+ 319, 0, 0, 0, 0, 0, 320, 350, 321, 0,
+ 322, 323, 324, 90, 0, 0, 91, 0, 0, 92,
+ 0, 93, 404, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 163, 164, 165, 166, 167,
+ 168, 169, 170, 171, 172, 173, 174, 175, 350, 0,
+ 0, 0, 0, 325, 0, 0, 326, 0, 327, 0,
+ 0, 328, 0, 350, 0, 0, 0, 0, 0, 0,
+ 350, 0, 0, 0, 350, 350, 74, 75, 0, 199,
+ 208, 209, 210, 211, 212, 213, 214, 215, 216, 217,
+ 218, 0, 88, 20, 0, 21, 0, 0, 0, 338,
+ 339, 74, 75, 340, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 20, 89,
+ 21, 0, 341, 342, 343, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 344, 345, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 346, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 125, 126, 127, 128, 129,
+ 130, 131, 132, 133, 134, 135, 136, 137, 138, 139,
+ 140, 141, 142, 143, 144, 145, 146, 147, 148, 318,
+ 319, 0, 0, 0, 0, 0, 320, 0, 321, 0,
+ 322, 323, 324, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 90, 338, 339, 91, 0,
+ 340, 92, 0, 93, 465, 163, 164, 165, 166, 167,
+ 168, 169, 170, 171, 172, 173, 174, 175, 0, 341,
+ 342, 343, 0, 0, 0, 0, 347, 0, 0, 0,
+ 0, 344, 345, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 346, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 125, 126, 127, 128, 129, 130, 131, 132,
+ 133, 134, 135, 136, 137, 138, 139, 140, 141, 142,
+ 143, 144, 145, 146, 147, 148, 318, 319, 0, 0,
+ 0, 0, 0, 320, 0, 321, 0, 322, 323, 324,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 163, 164, 165, 166, 167, 168, 169, 170,
+ 171, 172, 173, 174, 175, 0, 0, 0, 0, 0,
+ 0, 74, 75, 347, 199, 77, 78, 79, 80, 81,
+ 82, 83, 84, 85, 86, 87, 0, 88, 20, 0,
+ 21, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 302, 0, 0, 0, 0, 0, 0,
+ 0, 0, 74, 75, 89, 199, 208, 209, 210, 211,
+ 212, 213, 214, 215, 216, 217, 218, 0, 88, 20,
+ 0, 21, 74, 75, 0, 199, 77, 78, 79, 80,
+ 81, 82, 83, 84, 85, 86, 87, 0, 88, 20,
+ 0, 21, 0, 0, 0, 89, 0, 0, 0, 0,
+ 0, 0, 0, 0, 413, 0, 0, 0, 0, 0,
+ 0, 0, 0, 74, 75, 89, 199, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87, 0, 88,
+ 20, 0, 21, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 451, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 89, 0, 0, 0,
+ 90, 0, 0, 91, 0, 0, 92, 0, 93, 0,
+ 74, 75, 0, 199, 77, 78, 79, 80, 81, 82,
+ 83, 84, 85, 86, 87, 0, 88, 20, 0, 21,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 90, 519, 0, 91, 0, 399, 92, 0, 93,
+ 0, 0, 0, 89, 0, 0, 0, 0, 0, 0,
+ 0, 90, 0, 0, 91, 0, 0, 92, 0, 93,
+ 74, 75, 0, 76, 77, 78, 79, 80, 81, 82,
+ 83, 84, 85, 86, 87, 0, 88, 20, 0, 21,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 90, 0, 0, 91, 0, 0, 92, 0,
+ 93, 74, 75, 89, 199, 77, 78, 79, 80, 81,
+ 82, 83, 84, 85, 86, 87, 0, 88, 20, 0,
+ 21, 74, 75, 0, 199, 208, 209, 210, 211, 212,
+ 213, 214, 215, 216, 217, 218, 0, 88, 20, 0,
+ 21, 0, 0, 0, 89, 0, 0, 0, 0, 90,
+ 0, 0, 91, 0, 0, 92, 0, 93, 0, 0,
+ 0, 0, 74, 75, 89, 229, 77, 78, 79, 80,
+ 81, 82, 83, 84, 85, 86, 87, 0, 88, 20,
+ 0, 21, 74, 75, 0, 199, 208, 209, 210, 211,
+ 212, 213, 214, 215, 216, 217, 218, 0, 88, 20,
+ 0, 21, 0, 0, 0, 89, 0, 0, 0, 90,
+ 0, 0, 91, 0, 0, 92, 0, 93, 0, 0,
+ 0, 0, 0, 0, 0, 89, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 90, 0, 0, 91, 0, 0, 92, 0, 93, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 90, 0, 0, 91, 0, 0, 92, 0, 93, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 114, 0, 0, 0, 0, 0,
+ 0, 90, 0, 0, 91, 0, 0, 92, 115, 93,
+ 0, 0, 0, 0, 0, 0, 0, 0, 116, 117,
+ 0, 90, 0, 0, 91, 0, 0, 92, 0, 402,
+ 0, 118, 119, 120, 121, 122, 123, 124, 125, 126,
+ 127, 128, 129, 130, 131, 132, 133, 134, 135, 136,
+ 137, 138, 139, 140, 141, 142, 143, 144, 145, 146,
+ 147, 148, 149, 150, 151, 152, 153, 0, 0, 154,
+ 155, 156, 157, 158, 159, 160, 161, 162, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 163, 164,
+ 165, 166, 167, 168, 169, 170, 171, 172, 173, 174,
+ 175
+};
+
+static const short int yycheck[] =
+{
+ 45, 120, 115, 63, 120, 118, 107, 274, 4, 23,
+ 29, 3, 161, 0, 121, 164, 30, 558, 63, 93,
+ 5, 6, 15, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 15, 21, 22, 579, 24,
+ 153, 33, 23, 156, 157, 158, 159, 160, 161, 162,
+ 578, 10, 11, 12, 13, 14, 15, 16, 17, 104,
+ 105, 106, 590, 48, 57, 152, 179, 180, 306, 307,
+ 115, 153, 153, 118, 326, 327, 183, 57, 34, 161,
+ 5, 6, 163, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 347, 21, 22, 336, 24,
+ 159, 57, 52, 53, 54, 164, 151, 152, 153, 154,
+ 155, 156, 157, 158, 159, 160, 161, 162, 110, 153,
+ 22, 71, 24, 48, 198, 9, 153, 161, 153, 203,
+ 155, 176, 177, 178, 179, 180, 163, 21, 163, 164,
+ 153, 231, 232, 162, 61, 153, 159, 198, 61, 163,
+ 402, 159, 203, 243, 10, 11, 12, 13, 14, 15,
+ 16, 17, 0, 153, 153, 24, 162, 155, 45, 154,
+ 47, 157, 157, 163, 163, 160, 164, 162, 163, 152,
+ 293, 47, 48, 49, 244, 152, 276, 25, 32, 33,
+ 55, 56, 152, 31, 108, 109, 286, 287, 288, 244,
+ 159, 27, 28, 41, 42, 43, 44, 45, 46, 47,
+ 255, 3, 4, 3, 4, 3, 4, 455, 152, 486,
+ 152, 488, 296, 297, 62, 4, 300, 272, 24, 154,
+ 4, 291, 157, 3, 4, 160, 155, 162, 163, 64,
+ 65, 66, 67, 68, 69, 70, 291, 292, 293, 3,
+ 4, 24, 365, 20, 367, 368, 369, 77, 78, 24,
+ 4, 4, 375, 155, 59, 355, 356, 357, 158, 158,
+ 4, 4, 4, 363, 41, 42, 43, 44, 45, 46,
+ 47, 4, 7, 50, 4, 7, 7, 377, 378, 157,
+ 153, 155, 337, 394, 395, 396, 397, 398, 153, 153,
+ 153, 153, 153, 159, 153, 153, 407, 408, 409, 410,
+ 411, 153, 386, 153, 153, 24, 161, 36, 153, 156,
+ 365, 366, 367, 368, 369, 370, 371, 155, 402, 153,
+ 375, 376, 155, 155, 155, 24, 426, 155, 428, 155,
+ 155, 155, 432, 155, 155, 63, 153, 153, 153, 157,
+ 440, 441, 442, 153, 153, 456, 457, 161, 155, 153,
+ 153, 24, 463, 21, 222, 156, 155, 153, 226, 21,
+ 155, 153, 153, 231, 232, 4, 153, 153, 153, 4,
+ 493, 494, 495, 155, 429, 243, 24, 153, 36, 153,
+ 153, 481, 482, 153, 484, 485, 153, 153, 153, 161,
+ 153, 491, 447, 153, 34, 153, 507, 508, 509, 510,
+ 500, 153, 153, 514, 515, 516, 517, 153, 276, 156,
+ 533, 161, 414, 153, 153, 57, 24, 153, 286, 287,
+ 288, 57, 477, 157, 4, 21, 153, 153, 483, 558,
+ 541, 542, 558, 156, 159, 535, 156, 153, 493, 494,
+ 495, 156, 156, 156, 499, 156, 27, 28, 156, 156,
+ 579, 36, 156, 579, 159, 566, 156, 568, 569, 21,
+ 156, 156, 156, 518, 119, 120, 121, 122, 123, 124,
+ 125, 126, 127, 128, 153, 21, 576, 153, 533, 10,
+ 11, 12, 13, 14, 15, 16, 17, 355, 356, 357,
+ 65, 591, 21, 21, 65, 363, 65, 65, 598, 318,
+ 65, 33, 602, 603, 25, 478, 319, 44, 108, 377,
+ 378, 3, 222, 477, 19, 597, 429, 499, 458, -1,
+ -1, -1, -1, -1, 5, 6, -1, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, -1,
+ 21, 22, -1, 24, 125, 126, 127, 128, 129, 130,
+ 131, 132, 133, 134, 135, 136, 137, 138, 426, -1,
+ 428, 5, 6, -1, 432, -1, -1, 48, -1, -1,
+ -1, -1, 440, 441, 442, -1, -1, 20, 22, 22,
+ 24, 24, 26, -1, -1, -1, -1, -1, 31, 32,
+ 33, -1, -1, -1, 38, 39, -1, -1, 41, 42,
+ 43, 44, 45, 46, 47, -1, -1, 50, 51, -1,
+ -1, -1, -1, 481, 482, 58, 484, 485, -1, 62,
+ -1, -1, -1, 491, -1, -1, -1, -1, -1, -1,
+ -1, -1, 500, -1, -1, 79, 80, 81, 82, 83,
+ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
+ 94, 95, 96, 97, 98, 99, 100, 101, 102, 103,
+ 104, -1, -1, -1, -1, -1, 110, 535, 112, -1,
+ 114, 115, 116, 154, -1, -1, 157, -1, -1, 160,
+ -1, 162, 163, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 139, 140, 141, 142, 143,
+ 144, 145, 146, 147, 148, 149, 150, 151, 576, -1,
+ -1, -1, -1, 157, -1, -1, 160, -1, 162, -1,
+ -1, 165, -1, 591, -1, -1, -1, -1, -1, -1,
+ 598, -1, -1, -1, 602, 603, 5, 6, -1, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
+ 19, -1, 21, 22, -1, 24, -1, -1, -1, 3,
+ 4, 5, 6, 7, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 22, 48,
+ 24, -1, 26, 27, 28, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 38, 39, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 61, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 79, 80, 81, 82, 83,
+ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
+ 94, 95, 96, 97, 98, 99, 100, 101, 102, 103,
+ 104, -1, -1, -1, -1, -1, 110, -1, 112, -1,
+ 114, 115, 116, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 154, 3, 4, 157, -1,
+ 7, 160, -1, 162, 163, 139, 140, 141, 142, 143,
+ 144, 145, 146, 147, 148, 149, 150, 151, -1, 26,
+ 27, 28, -1, -1, -1, -1, 160, -1, -1, -1,
+ -1, 38, 39, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 61, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 79, 80, 81, 82, 83, 84, 85, 86,
+ 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
+ 97, 98, 99, 100, 101, 102, 103, 104, -1, -1,
+ -1, -1, -1, 110, -1, 112, -1, 114, 115, 116,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 139, 140, 141, 142, 143, 144, 145, 146,
+ 147, 148, 149, 150, 151, -1, -1, -1, -1, -1,
+ -1, 5, 6, 160, 8, 9, 10, 11, 12, 13,
+ 14, 15, 16, 17, 18, 19, -1, 21, 22, -1,
+ 24, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 37, -1, -1, -1, -1, -1, -1,
+ -1, -1, 5, 6, 48, 8, 9, 10, 11, 12,
+ 13, 14, 15, 16, 17, 18, 19, -1, 21, 22,
+ -1, 24, 5, 6, -1, 8, 9, 10, 11, 12,
+ 13, 14, 15, 16, 17, 18, 19, -1, 21, 22,
+ -1, 24, -1, -1, -1, 48, -1, -1, -1, -1,
+ -1, -1, -1, -1, 37, -1, -1, -1, -1, -1,
+ -1, -1, -1, 5, 6, 48, 8, 9, 10, 11,
+ 12, 13, 14, 15, 16, 17, 18, 19, -1, 21,
+ 22, -1, 24, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 37, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 48, -1, -1, -1,
+ 154, -1, -1, 157, -1, -1, 160, -1, 162, -1,
+ 5, 6, -1, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, -1, 21, 22, -1, 24,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 154, 37, -1, 157, -1, 159, 160, -1, 162,
+ -1, -1, -1, 48, -1, -1, -1, -1, -1, -1,
+ -1, 154, -1, -1, 157, -1, -1, 160, -1, 162,
+ 5, 6, -1, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, -1, 21, 22, -1, 24,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 154, -1, -1, 157, -1, -1, 160, -1,
+ 162, 5, 6, 48, 8, 9, 10, 11, 12, 13,
+ 14, 15, 16, 17, 18, 19, -1, 21, 22, -1,
+ 24, 5, 6, -1, 8, 9, 10, 11, 12, 13,
+ 14, 15, 16, 17, 18, 19, -1, 21, 22, -1,
+ 24, -1, -1, -1, 48, -1, -1, -1, -1, 154,
+ -1, -1, 157, -1, -1, 160, -1, 162, -1, -1,
+ -1, -1, 5, 6, 48, 8, 9, 10, 11, 12,
+ 13, 14, 15, 16, 17, 18, 19, -1, 21, 22,
+ -1, 24, 5, 6, -1, 8, 9, 10, 11, 12,
+ 13, 14, 15, 16, 17, 18, 19, -1, 21, 22,
+ -1, 24, -1, -1, -1, 48, -1, -1, -1, 154,
+ -1, -1, 157, -1, -1, 160, -1, 162, -1, -1,
+ -1, -1, -1, -1, -1, 48, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 154, -1, -1, 157, -1, -1, 160, -1, 162, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 154, -1, -1, 157, -1, -1, 160, -1, 162, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 35, -1, -1, -1, -1, -1,
+ -1, 154, -1, -1, 157, -1, -1, 160, 49, 162,
+ -1, -1, -1, -1, -1, -1, -1, -1, 59, 60,
+ -1, 154, -1, -1, 157, -1, -1, 160, -1, 162,
+ -1, 72, 73, 74, 75, 76, 77, 78, 79, 80,
+ 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
+ 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,
+ 101, 102, 103, 104, 105, 106, 107, -1, -1, 110,
+ 111, 112, 113, 114, 115, 116, 117, 118, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 139, 140,
+ 141, 142, 143, 144, 145, 146, 147, 148, 149, 150,
+ 151
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const unsigned char yystos[] =
+{
+ 0, 200, 201, 202, 0, 25, 31, 41, 42, 43,
+ 44, 45, 46, 47, 62, 181, 219, 222, 224, 232,
+ 22, 24, 51, 58, 62, 180, 212, 224, 225, 61,
+ 220, 23, 233, 234, 30, 163, 221, 233, 52, 53,
+ 54, 71, 209, 152, 61, 20, 45, 47, 50, 181,
+ 152, 45, 47, 223, 24, 207, 64, 65, 66, 67,
+ 68, 69, 70, 182, 217, 180, 238, 152, 152, 152,
+ 152, 157, 210, 207, 5, 6, 8, 9, 10, 11,
+ 12, 13, 14, 15, 16, 17, 18, 19, 21, 48,
+ 154, 157, 160, 162, 167, 189, 190, 191, 192, 193,
+ 212, 229, 32, 33, 199, 199, 199, 199, 226, 4,
+ 189, 29, 162, 218, 35, 49, 59, 60, 72, 73,
+ 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
+ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
+ 94, 95, 96, 97, 98, 99, 100, 101, 102, 103,
+ 104, 105, 106, 107, 110, 111, 112, 113, 114, 115,
+ 116, 117, 118, 139, 140, 141, 142, 143, 144, 145,
+ 146, 147, 148, 149, 150, 151, 169, 170, 171, 174,
+ 175, 235, 236, 242, 243, 245, 246, 24, 55, 56,
+ 208, 4, 24, 24, 211, 4, 4, 4, 162, 8,
+ 163, 193, 194, 155, 164, 191, 191, 191, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 176,
+ 177, 179, 191, 196, 217, 212, 191, 231, 59, 8,
+ 231, 9, 21, 10, 11, 12, 13, 14, 15, 16,
+ 17, 176, 177, 178, 182, 119, 120, 121, 122, 123,
+ 124, 125, 126, 127, 128, 172, 27, 28, 125, 126,
+ 127, 128, 129, 130, 131, 132, 133, 134, 135, 136,
+ 137, 138, 173, 191, 191, 231, 191, 191, 239, 231,
+ 231, 231, 231, 231, 231, 231, 191, 191, 191, 231,
+ 231, 182, 108, 109, 153, 159, 158, 158, 163, 194,
+ 153, 163, 37, 194, 195, 205, 206, 204, 27, 28,
+ 3, 4, 168, 4, 7, 26, 38, 39, 103, 104,
+ 110, 112, 114, 115, 116, 157, 160, 162, 165, 169,
+ 170, 171, 174, 175, 197, 229, 203, 155, 3, 4,
+ 7, 26, 27, 28, 38, 39, 61, 160, 197, 228,
+ 229, 230, 230, 230, 230, 189, 191, 191, 153, 184,
+ 153, 184, 230, 157, 153, 153, 153, 153, 153, 153,
+ 153, 153, 230, 230, 230, 153, 36, 189, 191, 231,
+ 24, 193, 193, 161, 163, 193, 153, 156, 153, 187,
+ 187, 187, 172, 173, 155, 155, 155, 155, 155, 159,
+ 196, 198, 162, 198, 163, 198, 24, 155, 155, 155,
+ 155, 155, 187, 37, 191, 214, 215, 216, 63, 227,
+ 198, 153, 153, 230, 230, 230, 15, 57, 15, 153,
+ 244, 230, 157, 231, 191, 231, 231, 231, 191, 191,
+ 153, 153, 153, 231, 191, 230, 230, 153, 159, 161,
+ 161, 37, 34, 57, 185, 188, 155, 155, 196, 196,
+ 196, 196, 196, 153, 159, 163, 193, 198, 161, 163,
+ 196, 196, 196, 196, 196, 212, 213, 153, 156, 24,
+ 161, 21, 21, 155, 153, 153, 230, 4, 230, 231,
+ 240, 153, 230, 153, 153, 153, 230, 230, 230, 155,
+ 191, 24, 4, 187, 196, 196, 244, 153, 153, 153,
+ 153, 196, 161, 163, 153, 153, 153, 153, 36, 37,
+ 214, 185, 186, 153, 230, 230, 240, 241, 230, 230,
+ 153, 184, 184, 153, 230, 153, 231, 231, 231, 241,
+ 230, 153, 153, 156, 196, 196, 196, 196, 161, 196,
+ 196, 196, 196, 191, 57, 183, 24, 153, 157, 156,
+ 231, 159, 230, 156, 196, 196, 153, 156, 153, 153,
+ 156, 156, 156, 156, 156, 4, 21, 159, 178, 237,
+ 36, 159, 156, 156, 196, 196, 196, 230, 228, 159,
+ 178, 21, 156, 156, 156, 153, 228, 230, 21, 153,
+ 235, 230, 21, 21, 230, 230
+};
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY (-2)
+#define YYEOF 0
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror. This remains here temporarily
+ to ease the transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. */
+
+#define YYFAIL goto yyerrlab
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ yytoken = YYTRANSLATE (yychar); \
+ YYPOPSTACK; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror (YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+while (0)
+
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+ If N is 0, then set CURRENT to the empty location which ends
+ the previous symbol: RHS[0] (always defined). */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do \
+ if (N) \
+ { \
+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
+ } \
+ else \
+ { \
+ (Current).first_line = (Current).last_line = \
+ YYRHSLOC (Rhs, 0).last_line; \
+ (Current).first_column = (Current).last_column = \
+ YYRHSLOC (Rhs, 0).last_column; \
+ } \
+ while (0)
+#endif
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+ This macro was not mandated originally: define only if we know
+ we won't break user code: when these are the locations we know. */
+
+#ifndef YY_LOCATION_PRINT
+# if YYLTYPE_IS_TRIVIAL
+# define YY_LOCATION_PRINT(File, Loc) \
+ fprintf (File, "%d.%d-%d.%d", \
+ (Loc).first_line, (Loc).first_column, \
+ (Loc).last_line, (Loc).last_column)
+# else
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments. */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (YYLEX_PARAM)
+#else
+# define YYLEX yylex ()
+#endif
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (0)
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yysymprint (stderr, \
+ Type, Value); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (0)
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included). |
+`------------------------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_stack_print (short int *bottom, short int *top)
+#else
+static void
+yy_stack_print (bottom, top)
+ short int *bottom;
+ short int *top;
+#endif
+{
+ YYFPRINTF (stderr, "Stack now");
+ for (/* Nothing. */; bottom <= top; ++bottom)
+ YYFPRINTF (stderr, " %d", *bottom);
+ YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top) \
+do { \
+ if (yydebug) \
+ yy_stack_print ((Bottom), (Top)); \
+} while (0)
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced. |
+`------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_reduce_print (int yyrule)
+#else
+static void
+yy_reduce_print (yyrule)
+ int yyrule;
+#endif
+{
+ int yyi;
+ unsigned long int yylno = yyrline[yyrule];
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu), ",
+ yyrule - 1, yylno);
+ /* Print the symbols being reduced, and their result. */
+ for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
+ YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]);
+ YYFPRINTF (stderr, "-> %s\n", yytname[yyr1[yyrule]]);
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (Rule); \
+} while (0)
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+# if defined (__GLIBC__) && defined (_STRING_H)
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+static YYSIZE_T
+# if defined (__STDC__) || defined (__cplusplus)
+yystrlen (const char *yystr)
+# else
+yystrlen (yystr)
+ const char *yystr;
+# endif
+{
+ const char *yys = yystr;
+
+ while (*yys++ != '\0')
+ continue;
+
+ return yys - yystr - 1;
+}
+# endif
+# endif
+
+# ifndef yystpcpy
+# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+static char *
+# if defined (__STDC__) || defined (__cplusplus)
+yystpcpy (char *yydest, const char *yysrc)
+# else
+yystpcpy (yydest, yysrc)
+ char *yydest;
+ const char *yysrc;
+# endif
+{
+ char *yyd = yydest;
+ const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+ quotes and backslashes, so that it's suitable for yyerror. The
+ heuristic is that double-quoting is unnecessary unless the string
+ contains an apostrophe, a comma, or backslash (other than
+ backslash-backslash). YYSTR is taken from yytname. If YYRES is
+ null, do not copy; instead, return the length of what the result
+ would have been. */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+ if (*yystr == '"')
+ {
+ size_t yyn = 0;
+ char const *yyp = yystr;
+
+ for (;;)
+ switch (*++yyp)
+ {
+ case '\'':
+ case ',':
+ goto do_not_strip_quotes;
+
+ case '\\':
+ if (*++yyp != '\\')
+ goto do_not_strip_quotes;
+ /* Fall through. */
+ default:
+ if (yyres)
+ yyres[yyn] = *yyp;
+ yyn++;
+ break;
+
+ case '"':
+ if (yyres)
+ yyres[yyn] = '\0';
+ return yyn;
+ }
+ do_not_strip_quotes: ;
+ }
+
+ if (! yyres)
+ return yystrlen (yystr);
+
+ return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+#endif /* YYERROR_VERBOSE */
+
+
+
+#if YYDEBUG
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yysymprint (yyoutput, yytype, yyvaluep)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE *yyvaluep;
+#endif
+{
+ /* Pacify ``unused variable'' warnings. */
+ (void) yyvaluep;
+
+ if (yytype < YYNTOKENS)
+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+ else
+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+
+# ifdef YYPRINT
+ if (yytype < YYNTOKENS)
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# endif
+ switch (yytype)
+ {
+ default:
+ break;
+ }
+ YYFPRINTF (yyoutput, ")");
+}
+
+#endif /* ! YYDEBUG */
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep)
+ const char *yymsg;
+ int yytype;
+ YYSTYPE *yyvaluep;
+#endif
+{
+ /* Pacify ``unused variable'' warnings. */
+ (void) yyvaluep;
+
+ if (!yymsg)
+ yymsg = "Deleting";
+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+ switch (yytype)
+ {
+
+ default:
+ break;
+ }
+}
+
+
+/* Prevent warnings from -Wmissing-prototypes. */
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void *YYPARSE_PARAM);
+# else
+int yyparse ();
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+/* The look-ahead symbol. */
+int yychar;
+
+/* The semantic value of the look-ahead symbol. */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far. */
+int yynerrs;
+
+
+
+/*----------.
+| yyparse. |
+`----------*/
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void *YYPARSE_PARAM)
+# else
+int yyparse (YYPARSE_PARAM)
+ void *YYPARSE_PARAM;
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+int
+yyparse (void)
+#else
+int
+yyparse ()
+
+#endif
+#endif
+{
+
+ int yystate;
+ int yyn;
+ int yyresult;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+ /* Look-ahead token as an internal (translated) token number. */
+ int yytoken = 0;
+
+ /* Three stacks and their tools:
+ `yyss': related to states,
+ `yyvs': related to semantic values,
+ `yyls': related to locations.
+
+ Refer to the stacks thru separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ short int yyssa[YYINITDEPTH];
+ short int *yyss = yyssa;
+ short int *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs = yyvsa;
+ YYSTYPE *yyvsp;
+
+
+
+#define YYPOPSTACK (yyvsp--, yyssp--)
+
+ YYSIZE_T yystacksize = YYINITDEPTH;
+
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+
+
+ /* When reducing, the number of symbols on the RHS of the reduced
+ rule. */
+ int yylen;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack.
+ The wasted elements are never initialized. */
+
+ yyssp = yyss;
+ yyvsp = yyvs;
+
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+ yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. so pushing a state here evens the stacks.
+ */
+ yyssp++;
+
+ yysetstate:
+ *yyssp = yystate;
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ short int *yyss1 = yyss;
+
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow (YY_("memory exhausted"),
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+
+ &yystacksize);
+
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyexhaustedlab;
+# else
+ /* Extend the stack our own way. */
+ if (YYMAXDEPTH <= yystacksize)
+ goto yyexhaustedlab;
+ yystacksize *= 2;
+ if (YYMAXDEPTH < yystacksize)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ short int *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyexhaustedlab;
+ YYSTACK_RELOCATE (yyss);
+ YYSTACK_RELOCATE (yyvs);
+
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+
+
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+ (unsigned long int) yystacksize));
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+ goto yybackup;
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+
+/* Do appropriate processing given the current state. */
+/* Read a look-ahead token if we need one and don't already have one. */
+/* yyresume: */
+
+ /* First try to decide what to do without reference to look-ahead token. */
+
+ yyn = yypact[yystate];
+ if (yyn == YYPACT_NINF)
+ goto yydefault;
+
+ /* Not known => get a look-ahead token if don't already have one. */
+
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = YYLEX;
+ }
+
+ if (yychar <= YYEOF)
+ {
+ yychar = yytoken = YYEOF;
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else
+ {
+ yytoken = YYTRANSLATE (yychar);
+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+ }
+
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
+ detect an error, take that action. */
+ yyn += yytoken;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+ goto yydefault;
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yyn == 0 || yyn == YYTABLE_NINF)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ /* Shift the look-ahead token. */
+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+ /* Discard the token being shifted unless it is eof. */
+ if (yychar != YYEOF)
+ yychar = YYEMPTY;
+
+ *++yyvsp = yylval;
+
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ `$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1-yylen];
+
+
+ YY_REDUCE_PRINT (yyn);
+ switch (yyn)
+ {
+ case 3:
+#line 1916 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ if ((yyvsp[0].UIntVal) > (uint32_t)INT32_MAX) // Outside of my range!
+ error("Value too large for type");
+ (yyval.SIntVal) = (int32_t)(yyvsp[0].UIntVal);
+ ;}
+ break;
+
+ case 5:
+#line 1925 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ if ((yyvsp[0].UInt64Val) > (uint64_t)INT64_MAX) // Outside of my range!
+ error("Value too large for type");
+ (yyval.SInt64Val) = (int64_t)(yyvsp[0].UInt64Val);
+ ;}
+ break;
+
+ case 26:
+#line 1947 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.IPred) = ICmpInst::ICMP_EQ; ;}
+ break;
+
+ case 27:
+#line 1947 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.IPred) = ICmpInst::ICMP_NE; ;}
+ break;
+
+ case 28:
+#line 1948 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.IPred) = ICmpInst::ICMP_SLT; ;}
+ break;
+
+ case 29:
+#line 1948 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.IPred) = ICmpInst::ICMP_SGT; ;}
+ break;
+
+ case 30:
+#line 1949 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.IPred) = ICmpInst::ICMP_SLE; ;}
+ break;
+
+ case 31:
+#line 1949 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.IPred) = ICmpInst::ICMP_SGE; ;}
+ break;
+
+ case 32:
+#line 1950 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.IPred) = ICmpInst::ICMP_ULT; ;}
+ break;
+
+ case 33:
+#line 1950 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.IPred) = ICmpInst::ICMP_UGT; ;}
+ break;
+
+ case 34:
+#line 1951 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.IPred) = ICmpInst::ICMP_ULE; ;}
+ break;
+
+ case 35:
+#line 1951 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.IPred) = ICmpInst::ICMP_UGE; ;}
+ break;
+
+ case 36:
+#line 1955 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.FPred) = FCmpInst::FCMP_OEQ; ;}
+ break;
+
+ case 37:
+#line 1955 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.FPred) = FCmpInst::FCMP_ONE; ;}
+ break;
+
+ case 38:
+#line 1956 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.FPred) = FCmpInst::FCMP_OLT; ;}
+ break;
+
+ case 39:
+#line 1956 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.FPred) = FCmpInst::FCMP_OGT; ;}
+ break;
+
+ case 40:
+#line 1957 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.FPred) = FCmpInst::FCMP_OLE; ;}
+ break;
+
+ case 41:
+#line 1957 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.FPred) = FCmpInst::FCMP_OGE; ;}
+ break;
+
+ case 42:
+#line 1958 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.FPred) = FCmpInst::FCMP_ORD; ;}
+ break;
+
+ case 43:
+#line 1958 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.FPred) = FCmpInst::FCMP_UNO; ;}
+ break;
+
+ case 44:
+#line 1959 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.FPred) = FCmpInst::FCMP_UEQ; ;}
+ break;
+
+ case 45:
+#line 1959 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.FPred) = FCmpInst::FCMP_UNE; ;}
+ break;
+
+ case 46:
+#line 1960 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.FPred) = FCmpInst::FCMP_ULT; ;}
+ break;
+
+ case 47:
+#line 1960 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.FPred) = FCmpInst::FCMP_UGT; ;}
+ break;
+
+ case 48:
+#line 1961 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.FPred) = FCmpInst::FCMP_ULE; ;}
+ break;
+
+ case 49:
+#line 1961 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.FPred) = FCmpInst::FCMP_UGE; ;}
+ break;
+
+ case 50:
+#line 1962 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.FPred) = FCmpInst::FCMP_TRUE; ;}
+ break;
+
+ case 51:
+#line 1963 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.FPred) = FCmpInst::FCMP_FALSE; ;}
+ break;
+
+ case 81:
+#line 1994 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyval.StrVal) = (yyvsp[-1].StrVal);
+ ;}
+ break;
+
+ case 82:
+#line 1997 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyval.StrVal) = 0;
+ ;}
+ break;
+
+ case 83:
+#line 2002 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.Linkage) = GlobalValue::InternalLinkage; ;}
+ break;
+
+ case 84:
+#line 2003 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.Linkage) = GlobalValue::LinkOnceLinkage; ;}
+ break;
+
+ case 85:
+#line 2004 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.Linkage) = GlobalValue::WeakLinkage; ;}
+ break;
+
+ case 86:
+#line 2005 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.Linkage) = GlobalValue::AppendingLinkage; ;}
+ break;
+
+ case 87:
+#line 2006 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.Linkage) = GlobalValue::DLLImportLinkage; ;}
+ break;
+
+ case 88:
+#line 2007 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.Linkage) = GlobalValue::DLLExportLinkage; ;}
+ break;
+
+ case 89:
+#line 2008 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.Linkage) = GlobalValue::ExternalWeakLinkage; ;}
+ break;
+
+ case 90:
+#line 2009 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.Linkage) = GlobalValue::ExternalLinkage; ;}
+ break;
+
+ case 91:
+#line 2013 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.UIntVal) = lastCallingConv = OldCallingConv::C; ;}
+ break;
+
+ case 92:
+#line 2014 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.UIntVal) = lastCallingConv = OldCallingConv::C; ;}
+ break;
+
+ case 93:
+#line 2015 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.UIntVal) = lastCallingConv = OldCallingConv::CSRet; ;}
+ break;
+
+ case 94:
+#line 2016 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.UIntVal) = lastCallingConv = OldCallingConv::Fast; ;}
+ break;
+
+ case 95:
+#line 2017 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.UIntVal) = lastCallingConv = OldCallingConv::Cold; ;}
+ break;
+
+ case 96:
+#line 2018 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.UIntVal) = lastCallingConv = OldCallingConv::X86_StdCall; ;}
+ break;
+
+ case 97:
+#line 2019 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.UIntVal) = lastCallingConv = OldCallingConv::X86_FastCall; ;}
+ break;
+
+ case 98:
+#line 2020 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ if ((unsigned)(yyvsp[0].UInt64Val) != (yyvsp[0].UInt64Val))
+ error("Calling conv too large");
+ (yyval.UIntVal) = lastCallingConv = (yyvsp[0].UInt64Val);
+ ;}
+ break;
+
+ case 99:
+#line 2030 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.UIntVal) = 0; ;}
+ break;
+
+ case 100:
+#line 2031 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyval.UIntVal) = (yyvsp[0].UInt64Val);
+ if ((yyval.UIntVal) != 0 && !isPowerOf2_32((yyval.UIntVal)))
+ error("Alignment must be a power of two");
+ ;}
+ break;
+
+ case 101:
+#line 2039 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.UIntVal) = 0; ;}
+ break;
+
+ case 102:
+#line 2040 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyval.UIntVal) = (yyvsp[0].UInt64Val);
+ if ((yyval.UIntVal) != 0 && !isPowerOf2_32((yyval.UIntVal)))
+ error("Alignment must be a power of two");
+ ;}
+ break;
+
+ case 103:
+#line 2048 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ for (unsigned i = 0, e = strlen((yyvsp[0].StrVal)); i != e; ++i)
+ if ((yyvsp[0].StrVal)[i] == '"' || (yyvsp[0].StrVal)[i] == '\\')
+ error("Invalid character in section name");
+ (yyval.StrVal) = (yyvsp[0].StrVal);
+ ;}
+ break;
+
+ case 104:
+#line 2057 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.StrVal) = 0; ;}
+ break;
+
+ case 105:
+#line 2058 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.StrVal) = (yyvsp[0].StrVal); ;}
+ break;
+
+ case 106:
+#line 2065 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {;}
+ break;
+
+ case 107:
+#line 2066 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {;}
+ break;
+
+ case 108:
+#line 2070 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ CurGV->setSection((yyvsp[0].StrVal));
+ free((yyvsp[0].StrVal));
+ ;}
+ break;
+
+ case 109:
+#line 2074 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ if ((yyvsp[0].UInt64Val) != 0 && !isPowerOf2_32((yyvsp[0].UInt64Val)))
+ error("Alignment must be a power of two");
+ CurGV->setAlignment((yyvsp[0].UInt64Val));
+
+ ;}
+ break;
+
+ case 111:
+#line 2091 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyval.TypeVal).PAT = new PATypeHolder((yyvsp[0].PrimType).T);
+ (yyval.TypeVal).S.makeSignless();
+ ;}
+ break;
+
+ case 113:
+#line 2099 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyval.TypeVal).PAT = new PATypeHolder((yyvsp[0].PrimType).T);
+ (yyval.TypeVal).S.makeSignless();
+ ;}
+ break;
+
+ case 114:
+#line 2106 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ if (!UpRefs.empty())
+ error("Invalid upreference in type: " + (*(yyvsp[0].TypeVal).PAT)->getDescription());
+ (yyval.TypeVal) = (yyvsp[0].TypeVal);
+ ;}
+ break;
+
+ case 127:
+#line 2120 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyval.TypeVal).PAT = new PATypeHolder((yyvsp[0].PrimType).T);
+ (yyval.TypeVal).S.copy((yyvsp[0].PrimType).S);
+ ;}
+ break;
+
+ case 128:
+#line 2124 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyval.TypeVal).PAT = new PATypeHolder(OpaqueType::get());
+ (yyval.TypeVal).S.makeSignless();
+ ;}
+ break;
+
+ case 129:
+#line 2128 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { // Named types are also simple types...
+ (yyval.TypeVal).S.copy(getTypeSign((yyvsp[0].ValIDVal)));
+ const Type* tmp = getType((yyvsp[0].ValIDVal));
+ (yyval.TypeVal).PAT = new PATypeHolder(tmp);
+ ;}
+ break;
+
+ case 130:
+#line 2133 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { // Type UpReference
+ if ((yyvsp[0].UInt64Val) > (uint64_t)~0U)
+ error("Value out of range");
+ OpaqueType *OT = OpaqueType::get(); // Use temporary placeholder
+ UpRefs.push_back(UpRefRecord((unsigned)(yyvsp[0].UInt64Val), OT)); // Add to vector...
+ (yyval.TypeVal).PAT = new PATypeHolder(OT);
+ (yyval.TypeVal).S.makeSignless();
+ UR_OUT("New Upreference!\n");
+ ;}
+ break;
+
+ case 131:
+#line 2142 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { // Function derived type?
+ (yyval.TypeVal).S.makeComposite((yyvsp[-3].TypeVal).S);
+ std::vector<const Type*> Params;
+ for (std::list<llvm::PATypeInfo>::iterator I = (yyvsp[-1].TypeList)->begin(),
+ E = (yyvsp[-1].TypeList)->end(); I != E; ++I) {
+ Params.push_back(I->PAT->get());
+ (yyval.TypeVal).S.add(I->S);
+ }
+ bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
+ if (isVarArg) Params.pop_back();
+
+ ParamAttrsList *PAL = 0;
+ if (lastCallingConv == OldCallingConv::CSRet) {
+ ParamAttrsVector Attrs;
+ ParamAttrsWithIndex PAWI;
+ PAWI.index = 1; PAWI.attrs = ParamAttr::StructRet; // first arg
+ Attrs.push_back(PAWI);
+ PAL = ParamAttrsList::get(Attrs);
+ }
+
+ const FunctionType *FTy =
+ FunctionType::get((yyvsp[-3].TypeVal).PAT->get(), Params, isVarArg, PAL);
+
+ (yyval.TypeVal).PAT = new PATypeHolder( HandleUpRefs(FTy, (yyval.TypeVal).S) );
+ delete (yyvsp[-3].TypeVal).PAT; // Delete the return type handle
+ delete (yyvsp[-1].TypeList); // Delete the argument list
+ ;}
+ break;
+
+ case 132:
+#line 2169 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { // Sized array type?
+ (yyval.TypeVal).S.makeComposite((yyvsp[-1].TypeVal).S);
+ (yyval.TypeVal).PAT = new PATypeHolder(HandleUpRefs(ArrayType::get((yyvsp[-1].TypeVal).PAT->get(),
+ (unsigned)(yyvsp[-3].UInt64Val)), (yyval.TypeVal).S));
+ delete (yyvsp[-1].TypeVal).PAT;
+ ;}
+ break;
+
+ case 133:
+#line 2175 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { // Vector type?
+ const llvm::Type* ElemTy = (yyvsp[-1].TypeVal).PAT->get();
+ if ((unsigned)(yyvsp[-3].UInt64Val) != (yyvsp[-3].UInt64Val))
+ error("Unsigned result not equal to signed result");
+ if (!(ElemTy->isInteger() || ElemTy->isFloatingPoint()))
+ error("Elements of a VectorType must be integer or floating point");
+ if (!isPowerOf2_32((yyvsp[-3].UInt64Val)))
+ error("VectorType length should be a power of 2");
+ (yyval.TypeVal).S.makeComposite((yyvsp[-1].TypeVal).S);
+ (yyval.TypeVal).PAT = new PATypeHolder(HandleUpRefs(VectorType::get(ElemTy,
+ (unsigned)(yyvsp[-3].UInt64Val)), (yyval.TypeVal).S));
+ delete (yyvsp[-1].TypeVal).PAT;
+ ;}
+ break;
+
+ case 134:
+#line 2188 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { // Structure type?
+ std::vector<const Type*> Elements;
+ (yyval.TypeVal).S.makeComposite();
+ for (std::list<llvm::PATypeInfo>::iterator I = (yyvsp[-1].TypeList)->begin(),
+ E = (yyvsp[-1].TypeList)->end(); I != E; ++I) {
+ Elements.push_back(I->PAT->get());
+ (yyval.TypeVal).S.add(I->S);
+ }
+ (yyval.TypeVal).PAT = new PATypeHolder(HandleUpRefs(StructType::get(Elements), (yyval.TypeVal).S));
+ delete (yyvsp[-1].TypeList);
+ ;}
+ break;
+
+ case 135:
+#line 2199 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { // Empty structure type?
+ (yyval.TypeVal).PAT = new PATypeHolder(StructType::get(std::vector<const Type*>()));
+ (yyval.TypeVal).S.makeComposite();
+ ;}
+ break;
+
+ case 136:
+#line 2203 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { // Packed Structure type?
+ (yyval.TypeVal).S.makeComposite();
+ std::vector<const Type*> Elements;
+ for (std::list<llvm::PATypeInfo>::iterator I = (yyvsp[-2].TypeList)->begin(),
+ E = (yyvsp[-2].TypeList)->end(); I != E; ++I) {
+ Elements.push_back(I->PAT->get());
+ (yyval.TypeVal).S.add(I->S);
+ delete I->PAT;
+ }
+ (yyval.TypeVal).PAT = new PATypeHolder(HandleUpRefs(StructType::get(Elements, true),
+ (yyval.TypeVal).S));
+ delete (yyvsp[-2].TypeList);
+ ;}
+ break;
+
+ case 137:
+#line 2216 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { // Empty packed structure type?
+ (yyval.TypeVal).PAT = new PATypeHolder(StructType::get(std::vector<const Type*>(),true));
+ (yyval.TypeVal).S.makeComposite();
+ ;}
+ break;
+
+ case 138:
+#line 2220 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { // Pointer type?
+ if ((yyvsp[-1].TypeVal).PAT->get() == Type::LabelTy)
+ error("Cannot form a pointer to a basic block");
+ (yyval.TypeVal).S.makeComposite((yyvsp[-1].TypeVal).S);
+ (yyval.TypeVal).PAT = new PATypeHolder(HandleUpRefs(PointerType::get((yyvsp[-1].TypeVal).PAT->get()),
+ (yyval.TypeVal).S));
+ delete (yyvsp[-1].TypeVal).PAT;
+ ;}
+ break;
+
+ case 139:
+#line 2234 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyval.TypeList) = new std::list<PATypeInfo>();
+ (yyval.TypeList)->push_back((yyvsp[0].TypeVal));
+ ;}
+ break;
+
+ case 140:
+#line 2238 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ ((yyval.TypeList)=(yyvsp[-2].TypeList))->push_back((yyvsp[0].TypeVal));
+ ;}
+ break;
+
+ case 142:
+#line 2246 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ PATypeInfo VoidTI;
+ VoidTI.PAT = new PATypeHolder(Type::VoidTy);
+ VoidTI.S.makeSignless();
+ ((yyval.TypeList)=(yyvsp[-2].TypeList))->push_back(VoidTI);
+ ;}
+ break;
+
+ case 143:
+#line 2252 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyval.TypeList) = new std::list<PATypeInfo>();
+ PATypeInfo VoidTI;
+ VoidTI.PAT = new PATypeHolder(Type::VoidTy);
+ VoidTI.S.makeSignless();
+ (yyval.TypeList)->push_back(VoidTI);
+ ;}
+ break;
+
+ case 144:
+#line 2259 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyval.TypeList) = new std::list<PATypeInfo>();
+ ;}
+ break;
+
+ case 145:
+#line 2271 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { // Nonempty unsized arr
+ const ArrayType *ATy = dyn_cast<ArrayType>((yyvsp[-3].TypeVal).PAT->get());
+ if (ATy == 0)
+ error("Cannot make array constant with type: '" +
+ (yyvsp[-3].TypeVal).PAT->get()->getDescription() + "'");
+ const Type *ETy = ATy->getElementType();
+ int NumElements = ATy->getNumElements();
+
+ // Verify that we have the correct size...
+ if (NumElements != -1 && NumElements != (int)(yyvsp[-1].ConstVector)->size())
+ error("Type mismatch: constant sized array initialized with " +
+ utostr((yyvsp[-1].ConstVector)->size()) + " arguments, but has size of " +
+ itostr(NumElements) + "");
+
+ // Verify all elements are correct type!
+ std::vector<Constant*> Elems;
+ for (unsigned i = 0; i < (yyvsp[-1].ConstVector)->size(); i++) {
+ Constant *C = (*(yyvsp[-1].ConstVector))[i].C;
+ const Type* ValTy = C->getType();
+ if (ETy != ValTy)
+ error("Element #" + utostr(i) + " is not of type '" +
+ ETy->getDescription() +"' as required!\nIt is of type '"+
+ ValTy->getDescription() + "'");
+ Elems.push_back(C);
+ }
+ (yyval.ConstVal).C = ConstantArray::get(ATy, Elems);
+ (yyval.ConstVal).S.copy((yyvsp[-3].TypeVal).S);
+ delete (yyvsp[-3].TypeVal).PAT;
+ delete (yyvsp[-1].ConstVector);
+ ;}
+ break;
+
+ case 146:
+#line 2301 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ const ArrayType *ATy = dyn_cast<ArrayType>((yyvsp[-2].TypeVal).PAT->get());
+ if (ATy == 0)
+ error("Cannot make array constant with type: '" +
+ (yyvsp[-2].TypeVal).PAT->get()->getDescription() + "'");
+ int NumElements = ATy->getNumElements();
+ if (NumElements != -1 && NumElements != 0)
+ error("Type mismatch: constant sized array initialized with 0"
+ " arguments, but has size of " + itostr(NumElements) +"");
+ (yyval.ConstVal).C = ConstantArray::get(ATy, std::vector<Constant*>());
+ (yyval.ConstVal).S.copy((yyvsp[-2].TypeVal).S);
+ delete (yyvsp[-2].TypeVal).PAT;
+ ;}
+ break;
+
+ case 147:
+#line 2314 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ const ArrayType *ATy = dyn_cast<ArrayType>((yyvsp[-2].TypeVal).PAT->get());
+ if (ATy == 0)
+ error("Cannot make array constant with type: '" +
+ (yyvsp[-2].TypeVal).PAT->get()->getDescription() + "'");
+ int NumElements = ATy->getNumElements();
+ const Type *ETy = dyn_cast<IntegerType>(ATy->getElementType());
+ if (!ETy || cast<IntegerType>(ETy)->getBitWidth() != 8)
+ error("String arrays require type i8, not '" + ETy->getDescription() +
+ "'");
+ char *EndStr = UnEscapeLexed((yyvsp[0].StrVal), true);
+ if (NumElements != -1 && NumElements != (EndStr-(yyvsp[0].StrVal)))
+ error("Can't build string constant of size " +
+ itostr((int)(EndStr-(yyvsp[0].StrVal))) + " when array has size " +
+ itostr(NumElements) + "");
+ std::vector<Constant*> Vals;
+ for (char *C = (char *)(yyvsp[0].StrVal); C != (char *)EndStr; ++C)
+ Vals.push_back(ConstantInt::get(ETy, *C));
+ free((yyvsp[0].StrVal));
+ (yyval.ConstVal).C = ConstantArray::get(ATy, Vals);
+ (yyval.ConstVal).S.copy((yyvsp[-2].TypeVal).S);
+ delete (yyvsp[-2].TypeVal).PAT;
+ ;}
+ break;
+
+ case 148:
+#line 2337 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { // Nonempty unsized arr
+ const VectorType *PTy = dyn_cast<VectorType>((yyvsp[-3].TypeVal).PAT->get());
+ if (PTy == 0)
+ error("Cannot make packed constant with type: '" +
+ (yyvsp[-3].TypeVal).PAT->get()->getDescription() + "'");
+ const Type *ETy = PTy->getElementType();
+ int NumElements = PTy->getNumElements();
+ // Verify that we have the correct size...
+ if (NumElements != -1 && NumElements != (int)(yyvsp[-1].ConstVector)->size())
+ error("Type mismatch: constant sized packed initialized with " +
+ utostr((yyvsp[-1].ConstVector)->size()) + " arguments, but has size of " +
+ itostr(NumElements) + "");
+ // Verify all elements are correct type!
+ std::vector<Constant*> Elems;
+ for (unsigned i = 0; i < (yyvsp[-1].ConstVector)->size(); i++) {
+ Constant *C = (*(yyvsp[-1].ConstVector))[i].C;
+ const Type* ValTy = C->getType();
+ if (ETy != ValTy)
+ error("Element #" + utostr(i) + " is not of type '" +
+ ETy->getDescription() +"' as required!\nIt is of type '"+
+ ValTy->getDescription() + "'");
+ Elems.push_back(C);
+ }
+ (yyval.ConstVal).C = ConstantVector::get(PTy, Elems);
+ (yyval.ConstVal).S.copy((yyvsp[-3].TypeVal).S);
+ delete (yyvsp[-3].TypeVal).PAT;
+ delete (yyvsp[-1].ConstVector);
+ ;}
+ break;
+
+ case 149:
+#line 2365 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ const StructType *STy = dyn_cast<StructType>((yyvsp[-3].TypeVal).PAT->get());
+ if (STy == 0)
+ error("Cannot make struct constant with type: '" +
+ (yyvsp[-3].TypeVal).PAT->get()->getDescription() + "'");
+ if ((yyvsp[-1].ConstVector)->size() != STy->getNumContainedTypes())
+ error("Illegal number of initializers for structure type");
+
+ // Check to ensure that constants are compatible with the type initializer!
+ std::vector<Constant*> Fields;
+ for (unsigned i = 0, e = (yyvsp[-1].ConstVector)->size(); i != e; ++i) {
+ Constant *C = (*(yyvsp[-1].ConstVector))[i].C;
+ if (C->getType() != STy->getElementType(i))
+ error("Expected type '" + STy->getElementType(i)->getDescription() +
+ "' for element #" + utostr(i) + " of structure initializer");
+ Fields.push_back(C);
+ }
+ (yyval.ConstVal).C = ConstantStruct::get(STy, Fields);
+ (yyval.ConstVal).S.copy((yyvsp[-3].TypeVal).S);
+ delete (yyvsp[-3].TypeVal).PAT;
+ delete (yyvsp[-1].ConstVector);
+ ;}
+ break;
+
+ case 150:
+#line 2387 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ const StructType *STy = dyn_cast<StructType>((yyvsp[-2].TypeVal).PAT->get());
+ if (STy == 0)
+ error("Cannot make struct constant with type: '" +
+ (yyvsp[-2].TypeVal).PAT->get()->getDescription() + "'");
+ if (STy->getNumContainedTypes() != 0)
+ error("Illegal number of initializers for structure type");
+ (yyval.ConstVal).C = ConstantStruct::get(STy, std::vector<Constant*>());
+ (yyval.ConstVal).S.copy((yyvsp[-2].TypeVal).S);
+ delete (yyvsp[-2].TypeVal).PAT;
+ ;}
+ break;
+
+ case 151:
+#line 2398 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ const StructType *STy = dyn_cast<StructType>((yyvsp[-5].TypeVal).PAT->get());
+ if (STy == 0)
+ error("Cannot make packed struct constant with type: '" +
+ (yyvsp[-5].TypeVal).PAT->get()->getDescription() + "'");
+ if ((yyvsp[-2].ConstVector)->size() != STy->getNumContainedTypes())
+ error("Illegal number of initializers for packed structure type");
+
+ // Check to ensure that constants are compatible with the type initializer!
+ std::vector<Constant*> Fields;
+ for (unsigned i = 0, e = (yyvsp[-2].ConstVector)->size(); i != e; ++i) {
+ Constant *C = (*(yyvsp[-2].ConstVector))[i].C;
+ if (C->getType() != STy->getElementType(i))
+ error("Expected type '" + STy->getElementType(i)->getDescription() +
+ "' for element #" + utostr(i) + " of packed struct initializer");
+ Fields.push_back(C);
+ }
+ (yyval.ConstVal).C = ConstantStruct::get(STy, Fields);
+ (yyval.ConstVal).S.copy((yyvsp[-5].TypeVal).S);
+ delete (yyvsp[-5].TypeVal).PAT;
+ delete (yyvsp[-2].ConstVector);
+ ;}
+ break;
+
+ case 152:
+#line 2420 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ const StructType *STy = dyn_cast<StructType>((yyvsp[-4].TypeVal).PAT->get());
+ if (STy == 0)
+ error("Cannot make packed struct constant with type: '" +
+ (yyvsp[-4].TypeVal).PAT->get()->getDescription() + "'");
+ if (STy->getNumContainedTypes() != 0)
+ error("Illegal number of initializers for packed structure type");
+ (yyval.ConstVal).C = ConstantStruct::get(STy, std::vector<Constant*>());
+ (yyval.ConstVal).S.copy((yyvsp[-4].TypeVal).S);
+ delete (yyvsp[-4].TypeVal).PAT;
+ ;}
+ break;
+
+ case 153:
+#line 2431 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ const PointerType *PTy = dyn_cast<PointerType>((yyvsp[-1].TypeVal).PAT->get());
+ if (PTy == 0)
+ error("Cannot make null pointer constant with type: '" +
+ (yyvsp[-1].TypeVal).PAT->get()->getDescription() + "'");
+ (yyval.ConstVal).C = ConstantPointerNull::get(PTy);
+ (yyval.ConstVal).S.copy((yyvsp[-1].TypeVal).S);
+ delete (yyvsp[-1].TypeVal).PAT;
+ ;}
+ break;
+
+ case 154:
+#line 2440 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyval.ConstVal).C = UndefValue::get((yyvsp[-1].TypeVal).PAT->get());
+ (yyval.ConstVal).S.copy((yyvsp[-1].TypeVal).S);
+ delete (yyvsp[-1].TypeVal).PAT;
+ ;}
+ break;
+
+ case 155:
+#line 2445 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ const PointerType *Ty = dyn_cast<PointerType>((yyvsp[-1].TypeVal).PAT->get());
+ if (Ty == 0)
+ error("Global const reference must be a pointer type, not" +
+ (yyvsp[-1].TypeVal).PAT->get()->getDescription());
+
+ // ConstExprs can exist in the body of a function, thus creating
+ // GlobalValues whenever they refer to a variable. Because we are in
+ // the context of a function, getExistingValue will search the functions
+ // symbol table instead of the module symbol table for the global symbol,
+ // which throws things all off. To get around this, we just tell
+ // getExistingValue that we are at global scope here.
+ //
+ Function *SavedCurFn = CurFun.CurrentFunction;
+ CurFun.CurrentFunction = 0;
+ (yyvsp[0].ValIDVal).S.copy((yyvsp[-1].TypeVal).S);
+ Value *V = getExistingValue(Ty, (yyvsp[0].ValIDVal));
+ CurFun.CurrentFunction = SavedCurFn;
+
+ // If this is an initializer for a constant pointer, which is referencing a
+ // (currently) undefined variable, create a stub now that shall be replaced
+ // in the future with the right type of variable.
+ //
+ if (V == 0) {
+ assert(isa<PointerType>(Ty) && "Globals may only be used as pointers");
+ const PointerType *PT = cast<PointerType>(Ty);
+
+ // First check to see if the forward references value is already created!
+ PerModuleInfo::GlobalRefsType::iterator I =
+ CurModule.GlobalRefs.find(std::make_pair(PT, (yyvsp[0].ValIDVal)));
+
+ if (I != CurModule.GlobalRefs.end()) {
+ V = I->second; // Placeholder already exists, use it...
+ (yyvsp[0].ValIDVal).destroy();
+ } else {
+ std::string Name;
+ if ((yyvsp[0].ValIDVal).Type == ValID::NameVal) Name = (yyvsp[0].ValIDVal).Name;
+
+ // Create the forward referenced global.
+ GlobalValue *GV;
+ if (const FunctionType *FTy =
+ dyn_cast<FunctionType>(PT->getElementType())) {
+ GV = new Function(FTy, GlobalValue::ExternalLinkage, Name,
+ CurModule.CurrentModule);
+ } else {
+ GV = new GlobalVariable(PT->getElementType(), false,
+ GlobalValue::ExternalLinkage, 0,
+ Name, CurModule.CurrentModule);
+ }
+
+ // Keep track of the fact that we have a forward ref to recycle it
+ CurModule.GlobalRefs.insert(std::make_pair(std::make_pair(PT, (yyvsp[0].ValIDVal)), GV));
+ V = GV;
+ }
+ }
+ (yyval.ConstVal).C = cast<GlobalValue>(V);
+ (yyval.ConstVal).S.copy((yyvsp[-1].TypeVal).S);
+ delete (yyvsp[-1].TypeVal).PAT; // Free the type handle
+ ;}
+ break;
+
+ case 156:
+#line 2504 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ if ((yyvsp[-1].TypeVal).PAT->get() != (yyvsp[0].ConstVal).C->getType())
+ error("Mismatched types for constant expression");
+ (yyval.ConstVal) = (yyvsp[0].ConstVal);
+ (yyval.ConstVal).S.copy((yyvsp[-1].TypeVal).S);
+ delete (yyvsp[-1].TypeVal).PAT;
+ ;}
+ break;
+
+ case 157:
+#line 2511 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ const Type *Ty = (yyvsp[-1].TypeVal).PAT->get();
+ if (isa<FunctionType>(Ty) || Ty == Type::LabelTy || isa<OpaqueType>(Ty))
+ error("Cannot create a null initialized value of this type");
+ (yyval.ConstVal).C = Constant::getNullValue(Ty);
+ (yyval.ConstVal).S.copy((yyvsp[-1].TypeVal).S);
+ delete (yyvsp[-1].TypeVal).PAT;
+ ;}
+ break;
+
+ case 158:
+#line 2519 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { // integral constants
+ const Type *Ty = (yyvsp[-1].PrimType).T;
+ if (!ConstantInt::isValueValidForType(Ty, (yyvsp[0].SInt64Val)))
+ error("Constant value doesn't fit in type");
+ (yyval.ConstVal).C = ConstantInt::get(Ty, (yyvsp[0].SInt64Val));
+ (yyval.ConstVal).S.makeSigned();
+ ;}
+ break;
+
+ case 159:
+#line 2526 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { // integral constants
+ const Type *Ty = (yyvsp[-1].PrimType).T;
+ if (!ConstantInt::isValueValidForType(Ty, (yyvsp[0].UInt64Val)))
+ error("Constant value doesn't fit in type");
+ (yyval.ConstVal).C = ConstantInt::get(Ty, (yyvsp[0].UInt64Val));
+ (yyval.ConstVal).S.makeUnsigned();
+ ;}
+ break;
+
+ case 160:
+#line 2533 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { // Boolean constants
+ (yyval.ConstVal).C = ConstantInt::get(Type::Int1Ty, true);
+ (yyval.ConstVal).S.makeUnsigned();
+ ;}
+ break;
+
+ case 161:
+#line 2537 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { // Boolean constants
+ (yyval.ConstVal).C = ConstantInt::get(Type::Int1Ty, false);
+ (yyval.ConstVal).S.makeUnsigned();
+ ;}
+ break;
+
+ case 162:
+#line 2541 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { // Float & Double constants
+ if (!ConstantFP::isValueValidForType((yyvsp[-1].PrimType).T, (yyvsp[0].FPVal)))
+ error("Floating point constant invalid for type");
+ (yyval.ConstVal).C = ConstantFP::get((yyvsp[-1].PrimType).T, (yyvsp[0].FPVal));
+ (yyval.ConstVal).S.makeSignless();
+ ;}
+ break;
+
+ case 163:
+#line 2550 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ const Type* SrcTy = (yyvsp[-3].ConstVal).C->getType();
+ const Type* DstTy = (yyvsp[-1].TypeVal).PAT->get();
+ Signedness SrcSign((yyvsp[-3].ConstVal).S);
+ Signedness DstSign((yyvsp[-1].TypeVal).S);
+ if (!SrcTy->isFirstClassType())
+ error("cast constant expression from a non-primitive type: '" +
+ SrcTy->getDescription() + "'");
+ if (!DstTy->isFirstClassType())
+ error("cast constant expression to a non-primitive type: '" +
+ DstTy->getDescription() + "'");
+ (yyval.ConstVal).C = cast<Constant>(getCast((yyvsp[-5].CastOpVal), (yyvsp[-3].ConstVal).C, SrcSign, DstTy, DstSign));
+ (yyval.ConstVal).S.copy(DstSign);
+ delete (yyvsp[-1].TypeVal).PAT;
+ ;}
+ break;
+
+ case 164:
+#line 2565 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ const Type *Ty = (yyvsp[-2].ConstVal).C->getType();
+ if (!isa<PointerType>(Ty))
+ error("GetElementPtr requires a pointer operand");
+
+ std::vector<Constant*> CIndices;
+ upgradeGEPCEIndices((yyvsp[-2].ConstVal).C->getType(), (yyvsp[-1].ValueList), CIndices);
+
+ delete (yyvsp[-1].ValueList);
+ (yyval.ConstVal).C = ConstantExpr::getGetElementPtr((yyvsp[-2].ConstVal).C, &CIndices[0], CIndices.size());
+ (yyval.ConstVal).S.copy(getElementSign((yyvsp[-2].ConstVal), CIndices));
+ ;}
+ break;
+
+ case 165:
+#line 2577 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ if (!(yyvsp[-5].ConstVal).C->getType()->isInteger() ||
+ cast<IntegerType>((yyvsp[-5].ConstVal).C->getType())->getBitWidth() != 1)
+ error("Select condition must be bool type");
+ if ((yyvsp[-3].ConstVal).C->getType() != (yyvsp[-1].ConstVal).C->getType())
+ error("Select operand types must match");
+ (yyval.ConstVal).C = ConstantExpr::getSelect((yyvsp[-5].ConstVal).C, (yyvsp[-3].ConstVal).C, (yyvsp[-1].ConstVal).C);
+ (yyval.ConstVal).S.copy((yyvsp[-3].ConstVal).S);
+ ;}
+ break;
+
+ case 166:
+#line 2586 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ const Type *Ty = (yyvsp[-3].ConstVal).C->getType();
+ if (Ty != (yyvsp[-1].ConstVal).C->getType())
+ error("Binary operator types must match");
+ // First, make sure we're dealing with the right opcode by upgrading from
+ // obsolete versions.
+ Instruction::BinaryOps Opcode = getBinaryOp((yyvsp[-5].BinaryOpVal), Ty, (yyvsp[-3].ConstVal).S);
+
+ // HACK: llvm 1.3 and earlier used to emit invalid pointer constant exprs.
+ // To retain backward compatibility with these early compilers, we emit a
+ // cast to the appropriate integer type automatically if we are in the
+ // broken case. See PR424 for more information.
+ if (!isa<PointerType>(Ty)) {
+ (yyval.ConstVal).C = ConstantExpr::get(Opcode, (yyvsp[-3].ConstVal).C, (yyvsp[-1].ConstVal).C);
+ } else {
+ const Type *IntPtrTy = 0;
+ switch (CurModule.CurrentModule->getPointerSize()) {
+ case Module::Pointer32: IntPtrTy = Type::Int32Ty; break;
+ case Module::Pointer64: IntPtrTy = Type::Int64Ty; break;
+ default: error("invalid pointer binary constant expr");
+ }
+ (yyval.ConstVal).C = ConstantExpr::get(Opcode,
+ ConstantExpr::getCast(Instruction::PtrToInt, (yyvsp[-3].ConstVal).C, IntPtrTy),
+ ConstantExpr::getCast(Instruction::PtrToInt, (yyvsp[-1].ConstVal).C, IntPtrTy));
+ (yyval.ConstVal).C = ConstantExpr::getCast(Instruction::IntToPtr, (yyval.ConstVal).C, Ty);
+ }
+ (yyval.ConstVal).S.copy((yyvsp[-3].ConstVal).S);
+ ;}
+ break;
+
+ case 167:
+#line 2614 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ const Type* Ty = (yyvsp[-3].ConstVal).C->getType();
+ if (Ty != (yyvsp[-1].ConstVal).C->getType())
+ error("Logical operator types must match");
+ if (!Ty->isInteger()) {
+ if (!isa<VectorType>(Ty) ||
+ !cast<VectorType>(Ty)->getElementType()->isInteger())
+ error("Logical operator requires integer operands");
+ }
+ Instruction::BinaryOps Opcode = getBinaryOp((yyvsp[-5].BinaryOpVal), Ty, (yyvsp[-3].ConstVal).S);
+ (yyval.ConstVal).C = ConstantExpr::get(Opcode, (yyvsp[-3].ConstVal).C, (yyvsp[-1].ConstVal).C);
+ (yyval.ConstVal).S.copy((yyvsp[-3].ConstVal).S);
+ ;}
+ break;
+
+ case 168:
+#line 2627 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ const Type* Ty = (yyvsp[-3].ConstVal).C->getType();
+ if (Ty != (yyvsp[-1].ConstVal).C->getType())
+ error("setcc operand types must match");
+ unsigned short pred;
+ Instruction::OtherOps Opcode = getCompareOp((yyvsp[-5].BinaryOpVal), pred, Ty, (yyvsp[-3].ConstVal).S);
+ (yyval.ConstVal).C = ConstantExpr::getCompare(Opcode, (yyvsp[-3].ConstVal).C, (yyvsp[-1].ConstVal).C);
+ (yyval.ConstVal).S.makeUnsigned();
+ ;}
+ break;
+
+ case 169:
+#line 2636 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ if ((yyvsp[-3].ConstVal).C->getType() != (yyvsp[-1].ConstVal).C->getType())
+ error("icmp operand types must match");
+ (yyval.ConstVal).C = ConstantExpr::getCompare((yyvsp[-5].IPred), (yyvsp[-3].ConstVal).C, (yyvsp[-1].ConstVal).C);
+ (yyval.ConstVal).S.makeUnsigned();
+ ;}
+ break;
+
+ case 170:
+#line 2642 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ if ((yyvsp[-3].ConstVal).C->getType() != (yyvsp[-1].ConstVal).C->getType())
+ error("fcmp operand types must match");
+ (yyval.ConstVal).C = ConstantExpr::getCompare((yyvsp[-5].FPred), (yyvsp[-3].ConstVal).C, (yyvsp[-1].ConstVal).C);
+ (yyval.ConstVal).S.makeUnsigned();
+ ;}
+ break;
+
+ case 171:
+#line 2648 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ if (!(yyvsp[-1].ConstVal).C->getType()->isInteger() ||
+ cast<IntegerType>((yyvsp[-1].ConstVal).C->getType())->getBitWidth() != 8)
+ error("Shift count for shift constant must be unsigned byte");
+ const Type* Ty = (yyvsp[-3].ConstVal).C->getType();
+ if (!(yyvsp[-3].ConstVal).C->getType()->isInteger())
+ error("Shift constant expression requires integer operand");
+ Constant *ShiftAmt = ConstantExpr::getZExt((yyvsp[-1].ConstVal).C, Ty);
+ (yyval.ConstVal).C = ConstantExpr::get(getBinaryOp((yyvsp[-5].BinaryOpVal), Ty, (yyvsp[-3].ConstVal).S), (yyvsp[-3].ConstVal).C, ShiftAmt);
+ (yyval.ConstVal).S.copy((yyvsp[-3].ConstVal).S);
+ ;}
+ break;
+
+ case 172:
+#line 2659 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ if (!ExtractElementInst::isValidOperands((yyvsp[-3].ConstVal).C, (yyvsp[-1].ConstVal).C))
+ error("Invalid extractelement operands");
+ (yyval.ConstVal).C = ConstantExpr::getExtractElement((yyvsp[-3].ConstVal).C, (yyvsp[-1].ConstVal).C);
+ (yyval.ConstVal).S.copy((yyvsp[-3].ConstVal).S.get(0));
+ ;}
+ break;
+
+ case 173:
+#line 2665 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ if (!InsertElementInst::isValidOperands((yyvsp[-5].ConstVal).C, (yyvsp[-3].ConstVal).C, (yyvsp[-1].ConstVal).C))
+ error("Invalid insertelement operands");
+ (yyval.ConstVal).C = ConstantExpr::getInsertElement((yyvsp[-5].ConstVal).C, (yyvsp[-3].ConstVal).C, (yyvsp[-1].ConstVal).C);
+ (yyval.ConstVal).S.copy((yyvsp[-5].ConstVal).S);
+ ;}
+ break;
+
+ case 174:
+#line 2671 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ if (!ShuffleVectorInst::isValidOperands((yyvsp[-5].ConstVal).C, (yyvsp[-3].ConstVal).C, (yyvsp[-1].ConstVal).C))
+ error("Invalid shufflevector operands");
+ (yyval.ConstVal).C = ConstantExpr::getShuffleVector((yyvsp[-5].ConstVal).C, (yyvsp[-3].ConstVal).C, (yyvsp[-1].ConstVal).C);
+ (yyval.ConstVal).S.copy((yyvsp[-5].ConstVal).S);
+ ;}
+ break;
+
+ case 175:
+#line 2682 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { ((yyval.ConstVector) = (yyvsp[-2].ConstVector))->push_back((yyvsp[0].ConstVal)); ;}
+ break;
+
+ case 176:
+#line 2683 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyval.ConstVector) = new std::vector<ConstInfo>();
+ (yyval.ConstVector)->push_back((yyvsp[0].ConstVal));
+ ;}
+ break;
+
+ case 177:
+#line 2692 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.BoolVal) = false; ;}
+ break;
+
+ case 178:
+#line 2693 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.BoolVal) = true; ;}
+ break;
+
+ case 179:
+#line 2705 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyval.ModuleVal) = ParserResult = (yyvsp[0].ModuleVal);
+ CurModule.ModuleDone();
+ ;}
+ break;
+
+ case 180:
+#line 2714 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.ModuleVal) = (yyvsp[-1].ModuleVal); CurFun.FunctionDone(); ;}
+ break;
+
+ case 181:
+#line 2715 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.ModuleVal) = (yyvsp[-1].ModuleVal); ;}
+ break;
+
+ case 182:
+#line 2716 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.ModuleVal) = (yyvsp[-3].ModuleVal); ;}
+ break;
+
+ case 183:
+#line 2717 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.ModuleVal) = (yyvsp[-1].ModuleVal); ;}
+ break;
+
+ case 184:
+#line 2718 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyval.ModuleVal) = CurModule.CurrentModule;
+ // Emit an error if there are any unresolved types left.
+ if (!CurModule.LateResolveTypes.empty()) {
+ const ValID &DID = CurModule.LateResolveTypes.begin()->first;
+ if (DID.Type == ValID::NameVal) {
+ error("Reference to an undefined type: '"+DID.getName() + "'");
+ } else {
+ error("Reference to an undefined type: #" + itostr(DID.Num));
+ }
+ }
+ ;}
+ break;
+
+ case 185:
+#line 2734 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ // Eagerly resolve types. This is not an optimization, this is a
+ // requirement that is due to the fact that we could have this:
+ //
+ // %list = type { %list * }
+ // %list = type { %list * } ; repeated type decl
+ //
+ // If types are not resolved eagerly, then the two types will not be
+ // determined to be the same type!
+ //
+ ResolveTypeTo((yyvsp[-2].StrVal), (yyvsp[0].TypeVal).PAT->get(), (yyvsp[0].TypeVal).S);
+
+ if (!setTypeName((yyvsp[0].TypeVal), (yyvsp[-2].StrVal)) && !(yyvsp[-2].StrVal)) {
+ // If this is a numbered type that is not a redefinition, add it to the
+ // slot table.
+ CurModule.Types.push_back((yyvsp[0].TypeVal).PAT->get());
+ CurModule.TypeSigns.push_back((yyvsp[0].TypeVal).S);
+ }
+ delete (yyvsp[0].TypeVal).PAT;
+ ;}
+ break;
+
+ case 186:
+#line 2754 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { // Function prototypes can be in const pool
+ ;}
+ break;
+
+ case 187:
+#line 2756 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { // Asm blocks can be in the const pool
+ ;}
+ break;
+
+ case 188:
+#line 2758 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ if ((yyvsp[0].ConstVal).C == 0)
+ error("Global value initializer is not a constant");
+ CurGV = ParseGlobalVariable((yyvsp[-3].StrVal), (yyvsp[-2].Linkage), (yyvsp[-1].BoolVal), (yyvsp[0].ConstVal).C->getType(), (yyvsp[0].ConstVal).C, (yyvsp[0].ConstVal).S);
+ ;}
+ break;
+
+ case 189:
+#line 2762 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ CurGV = 0;
+ ;}
+ break;
+
+ case 190:
+#line 2765 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ const Type *Ty = (yyvsp[0].TypeVal).PAT->get();
+ CurGV = ParseGlobalVariable((yyvsp[-3].StrVal), GlobalValue::ExternalLinkage, (yyvsp[-1].BoolVal), Ty, 0,
+ (yyvsp[0].TypeVal).S);
+ delete (yyvsp[0].TypeVal).PAT;
+ ;}
+ break;
+
+ case 191:
+#line 2770 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ CurGV = 0;
+ ;}
+ break;
+
+ case 192:
+#line 2773 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ const Type *Ty = (yyvsp[0].TypeVal).PAT->get();
+ CurGV = ParseGlobalVariable((yyvsp[-3].StrVal), GlobalValue::DLLImportLinkage, (yyvsp[-1].BoolVal), Ty, 0,
+ (yyvsp[0].TypeVal).S);
+ delete (yyvsp[0].TypeVal).PAT;
+ ;}
+ break;
+
+ case 193:
+#line 2778 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ CurGV = 0;
+ ;}
+ break;
+
+ case 194:
+#line 2781 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ const Type *Ty = (yyvsp[0].TypeVal).PAT->get();
+ CurGV =
+ ParseGlobalVariable((yyvsp[-3].StrVal), GlobalValue::ExternalWeakLinkage, (yyvsp[-1].BoolVal), Ty, 0,
+ (yyvsp[0].TypeVal).S);
+ delete (yyvsp[0].TypeVal).PAT;
+ ;}
+ break;
+
+ case 195:
+#line 2787 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ CurGV = 0;
+ ;}
+ break;
+
+ case 196:
+#line 2790 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ ;}
+ break;
+
+ case 197:
+#line 2792 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ ;}
+ break;
+
+ case 198:
+#line 2794 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ ;}
+ break;
+
+ case 199:
+#line 2799 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ const std::string &AsmSoFar = CurModule.CurrentModule->getModuleInlineAsm();
+ char *EndStr = UnEscapeLexed((yyvsp[0].StrVal), true);
+ std::string NewAsm((yyvsp[0].StrVal), EndStr);
+ free((yyvsp[0].StrVal));
+
+ if (AsmSoFar.empty())
+ CurModule.CurrentModule->setModuleInlineAsm(NewAsm);
+ else
+ CurModule.CurrentModule->setModuleInlineAsm(AsmSoFar+"\n"+NewAsm);
+ ;}
+ break;
+
+ case 200:
+#line 2813 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.Endianness) = Module::BigEndian; ;}
+ break;
+
+ case 201:
+#line 2814 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.Endianness) = Module::LittleEndian; ;}
+ break;
+
+ case 202:
+#line 2818 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ CurModule.setEndianness((yyvsp[0].Endianness));
+ ;}
+ break;
+
+ case 203:
+#line 2821 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ if ((yyvsp[0].UInt64Val) == 32)
+ CurModule.setPointerSize(Module::Pointer32);
+ else if ((yyvsp[0].UInt64Val) == 64)
+ CurModule.setPointerSize(Module::Pointer64);
+ else
+ error("Invalid pointer size: '" + utostr((yyvsp[0].UInt64Val)) + "'");
+ ;}
+ break;
+
+ case 204:
+#line 2829 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ CurModule.CurrentModule->setTargetTriple((yyvsp[0].StrVal));
+ free((yyvsp[0].StrVal));
+ ;}
+ break;
+
+ case 205:
+#line 2833 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ CurModule.CurrentModule->setDataLayout((yyvsp[0].StrVal));
+ free((yyvsp[0].StrVal));
+ ;}
+ break;
+
+ case 207:
+#line 2844 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ CurModule.CurrentModule->addLibrary((yyvsp[0].StrVal));
+ free((yyvsp[0].StrVal));
+ ;}
+ break;
+
+ case 208:
+#line 2848 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ CurModule.CurrentModule->addLibrary((yyvsp[0].StrVal));
+ free((yyvsp[0].StrVal));
+ ;}
+ break;
+
+ case 209:
+#line 2852 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { ;}
+ break;
+
+ case 213:
+#line 2865 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.StrVal) = 0; ;}
+ break;
+
+ case 214:
+#line 2869 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ if ((yyvsp[-1].TypeVal).PAT->get() == Type::VoidTy)
+ error("void typed arguments are invalid");
+ (yyval.ArgVal) = new std::pair<PATypeInfo, char*>((yyvsp[-1].TypeVal), (yyvsp[0].StrVal));
+ ;}
+ break;
+
+ case 215:
+#line 2877 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyval.ArgList) = (yyvsp[-2].ArgList);
+ (yyval.ArgList)->push_back(*(yyvsp[0].ArgVal));
+ delete (yyvsp[0].ArgVal);
+ ;}
+ break;
+
+ case 216:
+#line 2882 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyval.ArgList) = new std::vector<std::pair<PATypeInfo,char*> >();
+ (yyval.ArgList)->push_back(*(yyvsp[0].ArgVal));
+ delete (yyvsp[0].ArgVal);
+ ;}
+ break;
+
+ case 217:
+#line 2890 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.ArgList) = (yyvsp[0].ArgList); ;}
+ break;
+
+ case 218:
+#line 2891 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyval.ArgList) = (yyvsp[-2].ArgList);
+ PATypeInfo VoidTI;
+ VoidTI.PAT = new PATypeHolder(Type::VoidTy);
+ VoidTI.S.makeSignless();
+ (yyval.ArgList)->push_back(std::pair<PATypeInfo, char*>(VoidTI, 0));
+ ;}
+ break;
+
+ case 219:
+#line 2898 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyval.ArgList) = new std::vector<std::pair<PATypeInfo,char*> >();
+ PATypeInfo VoidTI;
+ VoidTI.PAT = new PATypeHolder(Type::VoidTy);
+ VoidTI.S.makeSignless();
+ (yyval.ArgList)->push_back(std::pair<PATypeInfo, char*>(VoidTI, 0));
+ ;}
+ break;
+
+ case 220:
+#line 2905 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.ArgList) = 0; ;}
+ break;
+
+ case 221:
+#line 2909 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ UnEscapeLexed((yyvsp[-5].StrVal));
+ std::string FunctionName((yyvsp[-5].StrVal));
+ free((yyvsp[-5].StrVal)); // Free strdup'd memory!
+
+ const Type* RetTy = (yyvsp[-6].TypeVal).PAT->get();
+
+ if (!RetTy->isFirstClassType() && RetTy != Type::VoidTy)
+ error("LLVM functions cannot return aggregate types");
+
+ Signedness FTySign;
+ FTySign.makeComposite((yyvsp[-6].TypeVal).S);
+ std::vector<const Type*> ParamTyList;
+
+ // In LLVM 2.0 the signatures of three varargs intrinsics changed to take
+ // i8*. We check here for those names and override the parameter list
+ // types to ensure the prototype is correct.
+ if (FunctionName == "llvm.va_start" || FunctionName == "llvm.va_end") {
+ ParamTyList.push_back(PointerType::get(Type::Int8Ty));
+ } else if (FunctionName == "llvm.va_copy") {
+ ParamTyList.push_back(PointerType::get(Type::Int8Ty));
+ ParamTyList.push_back(PointerType::get(Type::Int8Ty));
+ } else if ((yyvsp[-3].ArgList)) { // If there are arguments...
+ for (std::vector<std::pair<PATypeInfo,char*> >::iterator
+ I = (yyvsp[-3].ArgList)->begin(), E = (yyvsp[-3].ArgList)->end(); I != E; ++I) {
+ const Type *Ty = I->first.PAT->get();
+ ParamTyList.push_back(Ty);
+ FTySign.add(I->first.S);
+ }
+ }
+
+ bool isVarArg = ParamTyList.size() && ParamTyList.back() == Type::VoidTy;
+ if (isVarArg)
+ ParamTyList.pop_back();
+
+ // Convert the CSRet calling convention into the corresponding parameter
+ // attribute.
+ ParamAttrsList *PAL = 0;
+ if ((yyvsp[-7].UIntVal) == OldCallingConv::CSRet) {
+ ParamAttrsVector Attrs;
+ ParamAttrsWithIndex PAWI;
+ PAWI.index = 1; PAWI.attrs = ParamAttr::StructRet; // first arg
+ Attrs.push_back(PAWI);
+ PAL = ParamAttrsList::get(Attrs);
+ }
+
+ const FunctionType *FT =
+ FunctionType::get(RetTy, ParamTyList, isVarArg, PAL);
+ const PointerType *PFT = PointerType::get(FT);
+ delete (yyvsp[-6].TypeVal).PAT;
+
+ ValID ID;
+ if (!FunctionName.empty()) {
+ ID = ValID::create((char*)FunctionName.c_str());
+ } else {
+ ID = ValID::create((int)CurModule.Values[PFT].size());
+ }
+ ID.S.makeComposite(FTySign);
+
+ Function *Fn = 0;
+ Module* M = CurModule.CurrentModule;
+
+ // See if this function was forward referenced. If so, recycle the object.
+ if (GlobalValue *FWRef = CurModule.GetForwardRefForGlobal(PFT, ID)) {
+ // Move the function to the end of the list, from whereever it was
+ // previously inserted.
+ Fn = cast<Function>(FWRef);
+ M->getFunctionList().remove(Fn);
+ M->getFunctionList().push_back(Fn);
+ } else if (!FunctionName.empty()) {
+ GlobalValue *Conflict = M->getFunction(FunctionName);
+ if (!Conflict)
+ Conflict = M->getNamedGlobal(FunctionName);
+ if (Conflict && PFT == Conflict->getType()) {
+ if (!CurFun.isDeclare && !Conflict->isDeclaration()) {
+ // We have two function definitions that conflict, same type, same
+ // name. We should really check to make sure that this is the result
+ // of integer type planes collapsing and generate an error if it is
+ // not, but we'll just rename on the assumption that it is. However,
+ // let's do it intelligently and rename the internal linkage one
+ // if there is one.
+ std::string NewName(makeNameUnique(FunctionName));
+ if (Conflict->hasInternalLinkage()) {
+ Conflict->setName(NewName);
+ RenameMapKey Key =
+ makeRenameMapKey(FunctionName, Conflict->getType(), ID.S);
+ CurModule.RenameMap[Key] = NewName;
+ Fn = new Function(FT, CurFun.Linkage, FunctionName, M);
+ InsertValue(Fn, CurModule.Values);
+ } else {
+ Fn = new Function(FT, CurFun.Linkage, NewName, M);
+ InsertValue(Fn, CurModule.Values);
+ RenameMapKey Key =
+ makeRenameMapKey(FunctionName, PFT, ID.S);
+ CurModule.RenameMap[Key] = NewName;
+ }
+ } else {
+ // If they are not both definitions, then just use the function we
+ // found since the types are the same.
+ Fn = cast<Function>(Conflict);
+
+ // Make sure to strip off any argument names so we can't get
+ // conflicts.
+ if (Fn->isDeclaration())
+ for (Function::arg_iterator AI = Fn->arg_begin(),
+ AE = Fn->arg_end(); AI != AE; ++AI)
+ AI->setName("");
+ }
+ } else if (Conflict) {
+ // We have two globals with the same name and different types.
+ // Previously, this was permitted because the symbol table had
+ // "type planes" and names only needed to be distinct within a
+ // type plane. After PR411 was fixed, this is no loner the case.
+ // To resolve this we must rename one of the two.
+ if (Conflict->hasInternalLinkage()) {
+ // We can safely rename the Conflict.
+ RenameMapKey Key =
+ makeRenameMapKey(Conflict->getName(), Conflict->getType(),
+ CurModule.NamedValueSigns[Conflict->getName()]);
+ Conflict->setName(makeNameUnique(Conflict->getName()));
+ CurModule.RenameMap[Key] = Conflict->getName();
+ Fn = new Function(FT, CurFun.Linkage, FunctionName, M);
+ InsertValue(Fn, CurModule.Values);
+ } else {
+ // We can't quietly rename either of these things, but we must
+ // rename one of them. Only if the function's linkage is internal can
+ // we forgo a warning message about the renamed function.
+ std::string NewName = makeNameUnique(FunctionName);
+ if (CurFun.Linkage != GlobalValue::InternalLinkage) {
+ warning("Renaming function '" + FunctionName + "' as '" + NewName +
+ "' may cause linkage errors");
+ }
+ // Elect to rename the thing we're now defining.
+ Fn = new Function(FT, CurFun.Linkage, NewName, M);
+ InsertValue(Fn, CurModule.Values);
+ RenameMapKey Key = makeRenameMapKey(FunctionName, PFT, ID.S);
+ CurModule.RenameMap[Key] = NewName;
+ }
+ } else {
+ // There's no conflict, just define the function
+ Fn = new Function(FT, CurFun.Linkage, FunctionName, M);
+ InsertValue(Fn, CurModule.Values);
+ }
+ } else {
+ // There's no conflict, just define the function
+ Fn = new Function(FT, CurFun.Linkage, FunctionName, M);
+ InsertValue(Fn, CurModule.Values);
+ }
+
+
+ CurFun.FunctionStart(Fn);
+
+ if (CurFun.isDeclare) {
+ // If we have declaration, always overwrite linkage. This will allow us
+ // to correctly handle cases, when pointer to function is passed as
+ // argument to another function.
+ Fn->setLinkage(CurFun.Linkage);
+ }
+ Fn->setCallingConv(upgradeCallingConv((yyvsp[-7].UIntVal)));
+ Fn->setAlignment((yyvsp[0].UIntVal));
+ if ((yyvsp[-1].StrVal)) {
+ Fn->setSection((yyvsp[-1].StrVal));
+ free((yyvsp[-1].StrVal));
+ }
+
+ // Add all of the arguments we parsed to the function...
+ if ((yyvsp[-3].ArgList)) { // Is null if empty...
+ if (isVarArg) { // Nuke the last entry
+ assert((yyvsp[-3].ArgList)->back().first.PAT->get() == Type::VoidTy &&
+ (yyvsp[-3].ArgList)->back().second == 0 && "Not a varargs marker");
+ delete (yyvsp[-3].ArgList)->back().first.PAT;
+ (yyvsp[-3].ArgList)->pop_back(); // Delete the last entry
+ }
+ Function::arg_iterator ArgIt = Fn->arg_begin();
+ Function::arg_iterator ArgEnd = Fn->arg_end();
+ std::vector<std::pair<PATypeInfo,char*> >::iterator I = (yyvsp[-3].ArgList)->begin();
+ std::vector<std::pair<PATypeInfo,char*> >::iterator E = (yyvsp[-3].ArgList)->end();
+ for ( ; I != E && ArgIt != ArgEnd; ++I, ++ArgIt) {
+ delete I->first.PAT; // Delete the typeholder...
+ ValueInfo VI; VI.V = ArgIt; VI.S.copy(I->first.S);
+ setValueName(VI, I->second); // Insert arg into symtab...
+ InsertValue(ArgIt);
+ }
+ delete (yyvsp[-3].ArgList); // We're now done with the argument list
+ }
+ lastCallingConv = OldCallingConv::C;
+ ;}
+ break;
+
+ case 224:
+#line 3103 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { CurFun.Linkage = (yyvsp[0].Linkage); ;}
+ break;
+
+ case 225:
+#line 3103 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyval.FunctionVal) = CurFun.CurrentFunction;
+
+ // Make sure that we keep track of the linkage type even if there was a
+ // previous "declare".
+ (yyval.FunctionVal)->setLinkage((yyvsp[-3].Linkage));
+ ;}
+ break;
+
+ case 228:
+#line 3117 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyval.FunctionVal) = (yyvsp[-1].FunctionVal);
+ ;}
+ break;
+
+ case 229:
+#line 3122 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.Linkage) = GlobalValue::ExternalLinkage; ;}
+ break;
+
+ case 230:
+#line 3123 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.Linkage) = GlobalValue::DLLImportLinkage; ;}
+ break;
+
+ case 231:
+#line 3124 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.Linkage) = GlobalValue::ExternalWeakLinkage; ;}
+ break;
+
+ case 232:
+#line 3128 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { CurFun.isDeclare = true; ;}
+ break;
+
+ case 233:
+#line 3129 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { CurFun.Linkage = (yyvsp[0].Linkage); ;}
+ break;
+
+ case 234:
+#line 3129 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyval.FunctionVal) = CurFun.CurrentFunction;
+ CurFun.FunctionDone();
+
+ ;}
+ break;
+
+ case 235:
+#line 3141 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.BoolVal) = false; ;}
+ break;
+
+ case 236:
+#line 3142 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.BoolVal) = true; ;}
+ break;
+
+ case 237:
+#line 3147 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.ValIDVal) = ValID::create((yyvsp[0].SInt64Val)); ;}
+ break;
+
+ case 238:
+#line 3148 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.ValIDVal) = ValID::create((yyvsp[0].UInt64Val)); ;}
+ break;
+
+ case 239:
+#line 3149 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.ValIDVal) = ValID::create((yyvsp[0].FPVal)); ;}
+ break;
+
+ case 240:
+#line 3150 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyval.ValIDVal) = ValID::create(ConstantInt::get(Type::Int1Ty, true));
+ (yyval.ValIDVal).S.makeUnsigned();
+ ;}
+ break;
+
+ case 241:
+#line 3154 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyval.ValIDVal) = ValID::create(ConstantInt::get(Type::Int1Ty, false));
+ (yyval.ValIDVal).S.makeUnsigned();
+ ;}
+ break;
+
+ case 242:
+#line 3158 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.ValIDVal) = ValID::createNull(); ;}
+ break;
+
+ case 243:
+#line 3159 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.ValIDVal) = ValID::createUndef(); ;}
+ break;
+
+ case 244:
+#line 3160 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.ValIDVal) = ValID::createZeroInit(); ;}
+ break;
+
+ case 245:
+#line 3161 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { // Nonempty unsized packed vector
+ const Type *ETy = (*(yyvsp[-1].ConstVector))[0].C->getType();
+ int NumElements = (yyvsp[-1].ConstVector)->size();
+ VectorType* pt = VectorType::get(ETy, NumElements);
+ (yyval.ValIDVal).S.makeComposite((*(yyvsp[-1].ConstVector))[0].S);
+ PATypeHolder* PTy = new PATypeHolder(HandleUpRefs(pt, (yyval.ValIDVal).S));
+
+ // Verify all elements are correct type!
+ std::vector<Constant*> Elems;
+ for (unsigned i = 0; i < (yyvsp[-1].ConstVector)->size(); i++) {
+ Constant *C = (*(yyvsp[-1].ConstVector))[i].C;
+ const Type *CTy = C->getType();
+ if (ETy != CTy)
+ error("Element #" + utostr(i) + " is not of type '" +
+ ETy->getDescription() +"' as required!\nIt is of type '" +
+ CTy->getDescription() + "'");
+ Elems.push_back(C);
+ }
+ (yyval.ValIDVal) = ValID::create(ConstantVector::get(pt, Elems));
+ delete PTy; delete (yyvsp[-1].ConstVector);
+ ;}
+ break;
+
+ case 246:
+#line 3182 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyval.ValIDVal) = ValID::create((yyvsp[0].ConstVal).C);
+ (yyval.ValIDVal).S.copy((yyvsp[0].ConstVal).S);
+ ;}
+ break;
+
+ case 247:
+#line 3186 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ char *End = UnEscapeLexed((yyvsp[-2].StrVal), true);
+ std::string AsmStr = std::string((yyvsp[-2].StrVal), End);
+ End = UnEscapeLexed((yyvsp[0].StrVal), true);
+ std::string Constraints = std::string((yyvsp[0].StrVal), End);
+ (yyval.ValIDVal) = ValID::createInlineAsm(AsmStr, Constraints, (yyvsp[-3].BoolVal));
+ free((yyvsp[-2].StrVal));
+ free((yyvsp[0].StrVal));
+ ;}
+ break;
+
+ case 248:
+#line 3200 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.ValIDVal) = ValID::create((yyvsp[0].SIntVal)); (yyval.ValIDVal).S.makeSignless(); ;}
+ break;
+
+ case 249:
+#line 3201 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.ValIDVal) = ValID::create((yyvsp[0].StrVal)); (yyval.ValIDVal).S.makeSignless(); ;}
+ break;
+
+ case 252:
+#line 3214 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ const Type *Ty = (yyvsp[-1].TypeVal).PAT->get();
+ (yyvsp[0].ValIDVal).S.copy((yyvsp[-1].TypeVal).S);
+ (yyval.ValueVal).V = getVal(Ty, (yyvsp[0].ValIDVal));
+ (yyval.ValueVal).S.copy((yyvsp[-1].TypeVal).S);
+ delete (yyvsp[-1].TypeVal).PAT;
+ ;}
+ break;
+
+ case 253:
+#line 3224 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyval.FunctionVal) = (yyvsp[-1].FunctionVal);
+ ;}
+ break;
+
+ case 254:
+#line 3227 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { // Do not allow functions with 0 basic blocks
+ (yyval.FunctionVal) = (yyvsp[-1].FunctionVal);
+ ;}
+ break;
+
+ case 255:
+#line 3236 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ ValueInfo VI; VI.V = (yyvsp[0].TermInstVal).TI; VI.S.copy((yyvsp[0].TermInstVal).S);
+ setValueName(VI, (yyvsp[-1].StrVal));
+ InsertValue((yyvsp[0].TermInstVal).TI);
+ (yyvsp[-2].BasicBlockVal)->getInstList().push_back((yyvsp[0].TermInstVal).TI);
+ InsertValue((yyvsp[-2].BasicBlockVal));
+ (yyval.BasicBlockVal) = (yyvsp[-2].BasicBlockVal);
+ ;}
+ break;
+
+ case 256:
+#line 3247 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ if ((yyvsp[0].InstVal).I)
+ (yyvsp[-1].BasicBlockVal)->getInstList().push_back((yyvsp[0].InstVal).I);
+ (yyval.BasicBlockVal) = (yyvsp[-1].BasicBlockVal);
+ ;}
+ break;
+
+ case 257:
+#line 3252 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyval.BasicBlockVal) = CurBB = getBBVal(ValID::create((int)CurFun.NextBBNum++),true);
+ // Make sure to move the basic block to the correct location in the
+ // function, instead of leaving it inserted wherever it was first
+ // referenced.
+ Function::BasicBlockListType &BBL =
+ CurFun.CurrentFunction->getBasicBlockList();
+ BBL.splice(BBL.end(), BBL, (yyval.BasicBlockVal));
+ ;}
+ break;
+
+ case 258:
+#line 3261 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyval.BasicBlockVal) = CurBB = getBBVal(ValID::create((yyvsp[0].StrVal)), true);
+ // Make sure to move the basic block to the correct location in the
+ // function, instead of leaving it inserted wherever it was first
+ // referenced.
+ Function::BasicBlockListType &BBL =
+ CurFun.CurrentFunction->getBasicBlockList();
+ BBL.splice(BBL.end(), BBL, (yyval.BasicBlockVal));
+ ;}
+ break;
+
+ case 261:
+#line 3275 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { // Return with a result...
+ (yyval.TermInstVal).TI = new ReturnInst((yyvsp[0].ValueVal).V);
+ (yyval.TermInstVal).S.makeSignless();
+ ;}
+ break;
+
+ case 262:
+#line 3279 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { // Return with no result...
+ (yyval.TermInstVal).TI = new ReturnInst();
+ (yyval.TermInstVal).S.makeSignless();
+ ;}
+ break;
+
+ case 263:
+#line 3283 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { // Unconditional Branch...
+ BasicBlock* tmpBB = getBBVal((yyvsp[0].ValIDVal));
+ (yyval.TermInstVal).TI = new BranchInst(tmpBB);
+ (yyval.TermInstVal).S.makeSignless();
+ ;}
+ break;
+
+ case 264:
+#line 3288 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyvsp[-3].ValIDVal).S.makeSignless();
+ (yyvsp[0].ValIDVal).S.makeSignless();
+ BasicBlock* tmpBBA = getBBVal((yyvsp[-3].ValIDVal));
+ BasicBlock* tmpBBB = getBBVal((yyvsp[0].ValIDVal));
+ (yyvsp[-6].ValIDVal).S.makeUnsigned();
+ Value* tmpVal = getVal(Type::Int1Ty, (yyvsp[-6].ValIDVal));
+ (yyval.TermInstVal).TI = new BranchInst(tmpBBA, tmpBBB, tmpVal);
+ (yyval.TermInstVal).S.makeSignless();
+ ;}
+ break;
+
+ case 265:
+#line 3298 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyvsp[-6].ValIDVal).S.copy((yyvsp[-7].PrimType).S);
+ Value* tmpVal = getVal((yyvsp[-7].PrimType).T, (yyvsp[-6].ValIDVal));
+ (yyvsp[-3].ValIDVal).S.makeSignless();
+ BasicBlock* tmpBB = getBBVal((yyvsp[-3].ValIDVal));
+ SwitchInst *S = new SwitchInst(tmpVal, tmpBB, (yyvsp[-1].JumpTable)->size());
+ (yyval.TermInstVal).TI = S;
+ (yyval.TermInstVal).S.makeSignless();
+ std::vector<std::pair<Constant*,BasicBlock*> >::iterator I = (yyvsp[-1].JumpTable)->begin(),
+ E = (yyvsp[-1].JumpTable)->end();
+ for (; I != E; ++I) {
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(I->first))
+ S->addCase(CI, I->second);
+ else
+ error("Switch case is constant, but not a simple integer");
+ }
+ delete (yyvsp[-1].JumpTable);
+ ;}
+ break;
+
+ case 266:
+#line 3316 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyvsp[-5].ValIDVal).S.copy((yyvsp[-6].PrimType).S);
+ Value* tmpVal = getVal((yyvsp[-6].PrimType).T, (yyvsp[-5].ValIDVal));
+ (yyvsp[-2].ValIDVal).S.makeSignless();
+ BasicBlock* tmpBB = getBBVal((yyvsp[-2].ValIDVal));
+ SwitchInst *S = new SwitchInst(tmpVal, tmpBB, 0);
+ (yyval.TermInstVal).TI = S;
+ (yyval.TermInstVal).S.makeSignless();
+ ;}
+ break;
+
+ case 267:
+#line 3326 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ const PointerType *PFTy;
+ const FunctionType *Ty;
+ Signedness FTySign;
+
+ if (!(PFTy = dyn_cast<PointerType>((yyvsp[-10].TypeVal).PAT->get())) ||
+ !(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) {
+ // Pull out the types of all of the arguments...
+ std::vector<const Type*> ParamTypes;
+ FTySign.makeComposite((yyvsp[-10].TypeVal).S);
+ if ((yyvsp[-7].ValueList)) {
+ for (std::vector<ValueInfo>::iterator I = (yyvsp[-7].ValueList)->begin(), E = (yyvsp[-7].ValueList)->end();
+ I != E; ++I) {
+ ParamTypes.push_back((*I).V->getType());
+ FTySign.add(I->S);
+ }
+ }
+ ParamAttrsList *PAL = 0;
+ if ((yyvsp[-11].UIntVal) == OldCallingConv::CSRet) {
+ ParamAttrsVector Attrs;
+ ParamAttrsWithIndex PAWI;
+ PAWI.index = 1; PAWI.attrs = ParamAttr::StructRet; // first arg
+ Attrs.push_back(PAWI);
+ PAL = ParamAttrsList::get(Attrs);
+ }
+ bool isVarArg = ParamTypes.size() && ParamTypes.back() == Type::VoidTy;
+ if (isVarArg) ParamTypes.pop_back();
+ Ty = FunctionType::get((yyvsp[-10].TypeVal).PAT->get(), ParamTypes, isVarArg, PAL);
+ PFTy = PointerType::get(Ty);
+ (yyval.TermInstVal).S.copy((yyvsp[-10].TypeVal).S);
+ } else {
+ FTySign = (yyvsp[-10].TypeVal).S;
+ // Get the signedness of the result type. $3 is the pointer to the
+ // function type so we get the 0th element to extract the function type,
+ // and then the 0th element again to get the result type.
+ (yyval.TermInstVal).S.copy((yyvsp[-10].TypeVal).S.get(0).get(0));
+ }
+
+ (yyvsp[-9].ValIDVal).S.makeComposite(FTySign);
+ Value *V = getVal(PFTy, (yyvsp[-9].ValIDVal)); // Get the function we're calling...
+ BasicBlock *Normal = getBBVal((yyvsp[-3].ValIDVal));
+ BasicBlock *Except = getBBVal((yyvsp[0].ValIDVal));
+
+ // Create the call node...
+ if (!(yyvsp[-7].ValueList)) { // Has no arguments?
+ (yyval.TermInstVal).TI = new InvokeInst(V, Normal, Except, 0, 0);
+ } else { // Has arguments?
+ // Loop through FunctionType's arguments and ensure they are specified
+ // correctly!
+ //
+ FunctionType::param_iterator I = Ty->param_begin();
+ FunctionType::param_iterator E = Ty->param_end();
+ std::vector<ValueInfo>::iterator ArgI = (yyvsp[-7].ValueList)->begin(), ArgE = (yyvsp[-7].ValueList)->end();
+
+ std::vector<Value*> Args;
+ for (; ArgI != ArgE && I != E; ++ArgI, ++I) {
+ if ((*ArgI).V->getType() != *I)
+ error("Parameter " +(*ArgI).V->getName()+ " is not of type '" +
+ (*I)->getDescription() + "'");
+ Args.push_back((*ArgI).V);
+ }
+
+ if (I != E || (ArgI != ArgE && !Ty->isVarArg()))
+ error("Invalid number of parameters detected");
+
+ (yyval.TermInstVal).TI = new InvokeInst(V, Normal, Except, &Args[0], Args.size());
+ }
+ cast<InvokeInst>((yyval.TermInstVal).TI)->setCallingConv(upgradeCallingConv((yyvsp[-11].UIntVal)));
+ delete (yyvsp[-10].TypeVal).PAT;
+ delete (yyvsp[-7].ValueList);
+ lastCallingConv = OldCallingConv::C;
+ ;}
+ break;
+
+ case 268:
+#line 3398 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyval.TermInstVal).TI = new UnwindInst();
+ (yyval.TermInstVal).S.makeSignless();
+ ;}
+ break;
+
+ case 269:
+#line 3402 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyval.TermInstVal).TI = new UnreachableInst();
+ (yyval.TermInstVal).S.makeSignless();
+ ;}
+ break;
+
+ case 270:
+#line 3409 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyval.JumpTable) = (yyvsp[-5].JumpTable);
+ (yyvsp[-3].ValIDVal).S.copy((yyvsp[-4].PrimType).S);
+ Constant *V = cast<Constant>(getExistingValue((yyvsp[-4].PrimType).T, (yyvsp[-3].ValIDVal)));
+
+ if (V == 0)
+ error("May only switch on a constant pool value");
+
+ (yyvsp[0].ValIDVal).S.makeSignless();
+ BasicBlock* tmpBB = getBBVal((yyvsp[0].ValIDVal));
+ (yyval.JumpTable)->push_back(std::make_pair(V, tmpBB));
+ ;}
+ break;
+
+ case 271:
+#line 3421 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyval.JumpTable) = new std::vector<std::pair<Constant*, BasicBlock*> >();
+ (yyvsp[-3].ValIDVal).S.copy((yyvsp[-4].PrimType).S);
+ Constant *V = cast<Constant>(getExistingValue((yyvsp[-4].PrimType).T, (yyvsp[-3].ValIDVal)));
+
+ if (V == 0)
+ error("May only switch on a constant pool value");
+
+ (yyvsp[0].ValIDVal).S.makeSignless();
+ BasicBlock* tmpBB = getBBVal((yyvsp[0].ValIDVal));
+ (yyval.JumpTable)->push_back(std::make_pair(V, tmpBB));
+ ;}
+ break;
+
+ case 272:
+#line 3436 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ bool omit = false;
+ if ((yyvsp[-1].StrVal))
+ if (BitCastInst *BCI = dyn_cast<BitCastInst>((yyvsp[0].InstVal).I))
+ if (BCI->getSrcTy() == BCI->getDestTy() &&
+ BCI->getOperand(0)->getName() == (yyvsp[-1].StrVal))
+ // This is a useless bit cast causing a name redefinition. It is
+ // a bit cast from a type to the same type of an operand with the
+ // same name as the name we would give this instruction. Since this
+ // instruction results in no code generation, it is safe to omit
+ // the instruction. This situation can occur because of collapsed
+ // type planes. For example:
+ // %X = add int %Y, %Z
+ // %X = cast int %Y to uint
+ // After upgrade, this looks like:
+ // %X = add i32 %Y, %Z
+ // %X = bitcast i32 to i32
+ // The bitcast is clearly useless so we omit it.
+ omit = true;
+ if (omit) {
+ (yyval.InstVal).I = 0;
+ (yyval.InstVal).S.makeSignless();
+ } else {
+ ValueInfo VI; VI.V = (yyvsp[0].InstVal).I; VI.S.copy((yyvsp[0].InstVal).S);
+ setValueName(VI, (yyvsp[-1].StrVal));
+ InsertValue((yyvsp[0].InstVal).I);
+ (yyval.InstVal) = (yyvsp[0].InstVal);
+ }
+ ;}
+ break;
+
+ case 273:
+#line 3466 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { // Used for PHI nodes
+ (yyval.PHIList).P = new std::list<std::pair<Value*, BasicBlock*> >();
+ (yyval.PHIList).S.copy((yyvsp[-5].TypeVal).S);
+ (yyvsp[-3].ValIDVal).S.copy((yyvsp[-5].TypeVal).S);
+ Value* tmpVal = getVal((yyvsp[-5].TypeVal).PAT->get(), (yyvsp[-3].ValIDVal));
+ (yyvsp[-1].ValIDVal).S.makeSignless();
+ BasicBlock* tmpBB = getBBVal((yyvsp[-1].ValIDVal));
+ (yyval.PHIList).P->push_back(std::make_pair(tmpVal, tmpBB));
+ delete (yyvsp[-5].TypeVal).PAT;
+ ;}
+ break;
+
+ case 274:
+#line 3476 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyval.PHIList) = (yyvsp[-6].PHIList);
+ (yyvsp[-3].ValIDVal).S.copy((yyvsp[-6].PHIList).S);
+ Value* tmpVal = getVal((yyvsp[-6].PHIList).P->front().first->getType(), (yyvsp[-3].ValIDVal));
+ (yyvsp[-1].ValIDVal).S.makeSignless();
+ BasicBlock* tmpBB = getBBVal((yyvsp[-1].ValIDVal));
+ (yyvsp[-6].PHIList).P->push_back(std::make_pair(tmpVal, tmpBB));
+ ;}
+ break;
+
+ case 275:
+#line 3486 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { // Used for call statements, and memory insts...
+ (yyval.ValueList) = new std::vector<ValueInfo>();
+ (yyval.ValueList)->push_back((yyvsp[0].ValueVal));
+ ;}
+ break;
+
+ case 276:
+#line 3490 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyval.ValueList) = (yyvsp[-2].ValueList);
+ (yyvsp[-2].ValueList)->push_back((yyvsp[0].ValueVal));
+ ;}
+ break;
+
+ case 278:
+#line 3498 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.ValueList) = 0; ;}
+ break;
+
+ case 279:
+#line 3502 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyval.BoolVal) = true;
+ ;}
+ break;
+
+ case 280:
+#line 3505 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyval.BoolVal) = false;
+ ;}
+ break;
+
+ case 281:
+#line 3511 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyvsp[-2].ValIDVal).S.copy((yyvsp[-3].TypeVal).S);
+ (yyvsp[0].ValIDVal).S.copy((yyvsp[-3].TypeVal).S);
+ const Type* Ty = (yyvsp[-3].TypeVal).PAT->get();
+ if (!Ty->isInteger() && !Ty->isFloatingPoint() && !isa<VectorType>(Ty))
+ error("Arithmetic operator requires integer, FP, or packed operands");
+ if (isa<VectorType>(Ty) &&
+ ((yyvsp[-4].BinaryOpVal) == URemOp || (yyvsp[-4].BinaryOpVal) == SRemOp || (yyvsp[-4].BinaryOpVal) == FRemOp || (yyvsp[-4].BinaryOpVal) == RemOp))
+ error("Remainder not supported on vector types");
+ // Upgrade the opcode from obsolete versions before we do anything with it.
+ Instruction::BinaryOps Opcode = getBinaryOp((yyvsp[-4].BinaryOpVal), Ty, (yyvsp[-3].TypeVal).S);
+ Value* val1 = getVal(Ty, (yyvsp[-2].ValIDVal));
+ Value* val2 = getVal(Ty, (yyvsp[0].ValIDVal));
+ (yyval.InstVal).I = BinaryOperator::create(Opcode, val1, val2);
+ if ((yyval.InstVal).I == 0)
+ error("binary operator returned null");
+ (yyval.InstVal).S.copy((yyvsp[-3].TypeVal).S);
+ delete (yyvsp[-3].TypeVal).PAT;
+ ;}
+ break;
+
+ case 282:
+#line 3530 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyvsp[-2].ValIDVal).S.copy((yyvsp[-3].TypeVal).S);
+ (yyvsp[0].ValIDVal).S.copy((yyvsp[-3].TypeVal).S);
+ const Type *Ty = (yyvsp[-3].TypeVal).PAT->get();
+ if (!Ty->isInteger()) {
+ if (!isa<VectorType>(Ty) ||
+ !cast<VectorType>(Ty)->getElementType()->isInteger())
+ error("Logical operator requires integral operands");
+ }
+ Instruction::BinaryOps Opcode = getBinaryOp((yyvsp[-4].BinaryOpVal), Ty, (yyvsp[-3].TypeVal).S);
+ Value* tmpVal1 = getVal(Ty, (yyvsp[-2].ValIDVal));
+ Value* tmpVal2 = getVal(Ty, (yyvsp[0].ValIDVal));
+ (yyval.InstVal).I = BinaryOperator::create(Opcode, tmpVal1, tmpVal2);
+ if ((yyval.InstVal).I == 0)
+ error("binary operator returned null");
+ (yyval.InstVal).S.copy((yyvsp[-3].TypeVal).S);
+ delete (yyvsp[-3].TypeVal).PAT;
+ ;}
+ break;
+
+ case 283:
+#line 3548 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyvsp[-2].ValIDVal).S.copy((yyvsp[-3].TypeVal).S);
+ (yyvsp[0].ValIDVal).S.copy((yyvsp[-3].TypeVal).S);
+ const Type* Ty = (yyvsp[-3].TypeVal).PAT->get();
+ if(isa<VectorType>(Ty))
+ error("VectorTypes currently not supported in setcc instructions");
+ unsigned short pred;
+ Instruction::OtherOps Opcode = getCompareOp((yyvsp[-4].BinaryOpVal), pred, Ty, (yyvsp[-3].TypeVal).S);
+ Value* tmpVal1 = getVal(Ty, (yyvsp[-2].ValIDVal));
+ Value* tmpVal2 = getVal(Ty, (yyvsp[0].ValIDVal));
+ (yyval.InstVal).I = CmpInst::create(Opcode, pred, tmpVal1, tmpVal2);
+ if ((yyval.InstVal).I == 0)
+ error("binary operator returned null");
+ (yyval.InstVal).S.makeUnsigned();
+ delete (yyvsp[-3].TypeVal).PAT;
+ ;}
+ break;
+
+ case 284:
+#line 3564 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyvsp[-2].ValIDVal).S.copy((yyvsp[-3].TypeVal).S);
+ (yyvsp[0].ValIDVal).S.copy((yyvsp[-3].TypeVal).S);
+ const Type *Ty = (yyvsp[-3].TypeVal).PAT->get();
+ if (isa<VectorType>(Ty))
+ error("VectorTypes currently not supported in icmp instructions");
+ else if (!Ty->isInteger() && !isa<PointerType>(Ty))
+ error("icmp requires integer or pointer typed operands");
+ Value* tmpVal1 = getVal(Ty, (yyvsp[-2].ValIDVal));
+ Value* tmpVal2 = getVal(Ty, (yyvsp[0].ValIDVal));
+ (yyval.InstVal).I = new ICmpInst((yyvsp[-4].IPred), tmpVal1, tmpVal2);
+ (yyval.InstVal).S.makeUnsigned();
+ delete (yyvsp[-3].TypeVal).PAT;
+ ;}
+ break;
+
+ case 285:
+#line 3578 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyvsp[-2].ValIDVal).S.copy((yyvsp[-3].TypeVal).S);
+ (yyvsp[0].ValIDVal).S.copy((yyvsp[-3].TypeVal).S);
+ const Type *Ty = (yyvsp[-3].TypeVal).PAT->get();
+ if (isa<VectorType>(Ty))
+ error("VectorTypes currently not supported in fcmp instructions");
+ else if (!Ty->isFloatingPoint())
+ error("fcmp instruction requires floating point operands");
+ Value* tmpVal1 = getVal(Ty, (yyvsp[-2].ValIDVal));
+ Value* tmpVal2 = getVal(Ty, (yyvsp[0].ValIDVal));
+ (yyval.InstVal).I = new FCmpInst((yyvsp[-4].FPred), tmpVal1, tmpVal2);
+ (yyval.InstVal).S.makeUnsigned();
+ delete (yyvsp[-3].TypeVal).PAT;
+ ;}
+ break;
+
+ case 286:
+#line 3592 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ warning("Use of obsolete 'not' instruction: Replacing with 'xor");
+ const Type *Ty = (yyvsp[0].ValueVal).V->getType();
+ Value *Ones = ConstantInt::getAllOnesValue(Ty);
+ if (Ones == 0)
+ error("Expected integral type for not instruction");
+ (yyval.InstVal).I = BinaryOperator::create(Instruction::Xor, (yyvsp[0].ValueVal).V, Ones);
+ if ((yyval.InstVal).I == 0)
+ error("Could not create a xor instruction");
+ (yyval.InstVal).S.copy((yyvsp[0].ValueVal).S);
+ ;}
+ break;
+
+ case 287:
+#line 3603 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ if (!(yyvsp[0].ValueVal).V->getType()->isInteger() ||
+ cast<IntegerType>((yyvsp[0].ValueVal).V->getType())->getBitWidth() != 8)
+ error("Shift amount must be int8");
+ const Type* Ty = (yyvsp[-2].ValueVal).V->getType();
+ if (!Ty->isInteger())
+ error("Shift constant expression requires integer operand");
+ Value* ShiftAmt = 0;
+ if (cast<IntegerType>(Ty)->getBitWidth() > Type::Int8Ty->getBitWidth())
+ if (Constant *C = dyn_cast<Constant>((yyvsp[0].ValueVal).V))
+ ShiftAmt = ConstantExpr::getZExt(C, Ty);
+ else
+ ShiftAmt = new ZExtInst((yyvsp[0].ValueVal).V, Ty, makeNameUnique("shift"), CurBB);
+ else
+ ShiftAmt = (yyvsp[0].ValueVal).V;
+ (yyval.InstVal).I = BinaryOperator::create(getBinaryOp((yyvsp[-3].BinaryOpVal), Ty, (yyvsp[-2].ValueVal).S), (yyvsp[-2].ValueVal).V, ShiftAmt);
+ (yyval.InstVal).S.copy((yyvsp[-2].ValueVal).S);
+ ;}
+ break;
+
+ case 288:
+#line 3621 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ const Type *DstTy = (yyvsp[0].TypeVal).PAT->get();
+ if (!DstTy->isFirstClassType())
+ error("cast instruction to a non-primitive type: '" +
+ DstTy->getDescription() + "'");
+ (yyval.InstVal).I = cast<Instruction>(getCast((yyvsp[-3].CastOpVal), (yyvsp[-2].ValueVal).V, (yyvsp[-2].ValueVal).S, DstTy, (yyvsp[0].TypeVal).S, true));
+ (yyval.InstVal).S.copy((yyvsp[0].TypeVal).S);
+ delete (yyvsp[0].TypeVal).PAT;
+ ;}
+ break;
+
+ case 289:
+#line 3630 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ if (!(yyvsp[-4].ValueVal).V->getType()->isInteger() ||
+ cast<IntegerType>((yyvsp[-4].ValueVal).V->getType())->getBitWidth() != 1)
+ error("select condition must be bool");
+ if ((yyvsp[-2].ValueVal).V->getType() != (yyvsp[0].ValueVal).V->getType())
+ error("select value types should match");
+ (yyval.InstVal).I = new SelectInst((yyvsp[-4].ValueVal).V, (yyvsp[-2].ValueVal).V, (yyvsp[0].ValueVal).V);
+ (yyval.InstVal).S.copy((yyvsp[-2].ValueVal).S);
+ ;}
+ break;
+
+ case 290:
+#line 3639 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ const Type *Ty = (yyvsp[0].TypeVal).PAT->get();
+ NewVarArgs = true;
+ (yyval.InstVal).I = new VAArgInst((yyvsp[-2].ValueVal).V, Ty);
+ (yyval.InstVal).S.copy((yyvsp[0].TypeVal).S);
+ delete (yyvsp[0].TypeVal).PAT;
+ ;}
+ break;
+
+ case 291:
+#line 3646 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ const Type* ArgTy = (yyvsp[-2].ValueVal).V->getType();
+ const Type* DstTy = (yyvsp[0].TypeVal).PAT->get();
+ ObsoleteVarArgs = true;
+ Function* NF = cast<Function>(CurModule.CurrentModule->
+ getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, (Type *)0));
+
+ //b = vaarg a, t ->
+ //foo = alloca 1 of t
+ //bar = vacopy a
+ //store bar -> foo
+ //b = vaarg foo, t
+ AllocaInst* foo = new AllocaInst(ArgTy, 0, "vaarg.fix");
+ CurBB->getInstList().push_back(foo);
+ CallInst* bar = new CallInst(NF, (yyvsp[-2].ValueVal).V);
+ CurBB->getInstList().push_back(bar);
+ CurBB->getInstList().push_back(new StoreInst(bar, foo));
+ (yyval.InstVal).I = new VAArgInst(foo, DstTy);
+ (yyval.InstVal).S.copy((yyvsp[0].TypeVal).S);
+ delete (yyvsp[0].TypeVal).PAT;
+ ;}
+ break;
+
+ case 292:
+#line 3667 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ const Type* ArgTy = (yyvsp[-2].ValueVal).V->getType();
+ const Type* DstTy = (yyvsp[0].TypeVal).PAT->get();
+ ObsoleteVarArgs = true;
+ Function* NF = cast<Function>(CurModule.CurrentModule->
+ getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, (Type *)0));
+
+ //b = vanext a, t ->
+ //foo = alloca 1 of t
+ //bar = vacopy a
+ //store bar -> foo
+ //tmp = vaarg foo, t
+ //b = load foo
+ AllocaInst* foo = new AllocaInst(ArgTy, 0, "vanext.fix");
+ CurBB->getInstList().push_back(foo);
+ CallInst* bar = new CallInst(NF, (yyvsp[-2].ValueVal).V);
+ CurBB->getInstList().push_back(bar);
+ CurBB->getInstList().push_back(new StoreInst(bar, foo));
+ Instruction* tmp = new VAArgInst(foo, DstTy);
+ CurBB->getInstList().push_back(tmp);
+ (yyval.InstVal).I = new LoadInst(foo);
+ (yyval.InstVal).S.copy((yyvsp[0].TypeVal).S);
+ delete (yyvsp[0].TypeVal).PAT;
+ ;}
+ break;
+
+ case 293:
+#line 3691 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ if (!ExtractElementInst::isValidOperands((yyvsp[-2].ValueVal).V, (yyvsp[0].ValueVal).V))
+ error("Invalid extractelement operands");
+ (yyval.InstVal).I = new ExtractElementInst((yyvsp[-2].ValueVal).V, (yyvsp[0].ValueVal).V);
+ (yyval.InstVal).S.copy((yyvsp[-2].ValueVal).S.get(0));
+ ;}
+ break;
+
+ case 294:
+#line 3697 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ if (!InsertElementInst::isValidOperands((yyvsp[-4].ValueVal).V, (yyvsp[-2].ValueVal).V, (yyvsp[0].ValueVal).V))
+ error("Invalid insertelement operands");
+ (yyval.InstVal).I = new InsertElementInst((yyvsp[-4].ValueVal).V, (yyvsp[-2].ValueVal).V, (yyvsp[0].ValueVal).V);
+ (yyval.InstVal).S.copy((yyvsp[-4].ValueVal).S);
+ ;}
+ break;
+
+ case 295:
+#line 3703 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ if (!ShuffleVectorInst::isValidOperands((yyvsp[-4].ValueVal).V, (yyvsp[-2].ValueVal).V, (yyvsp[0].ValueVal).V))
+ error("Invalid shufflevector operands");
+ (yyval.InstVal).I = new ShuffleVectorInst((yyvsp[-4].ValueVal).V, (yyvsp[-2].ValueVal).V, (yyvsp[0].ValueVal).V);
+ (yyval.InstVal).S.copy((yyvsp[-4].ValueVal).S);
+ ;}
+ break;
+
+ case 296:
+#line 3709 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ const Type *Ty = (yyvsp[0].PHIList).P->front().first->getType();
+ if (!Ty->isFirstClassType())
+ error("PHI node operands must be of first class type");
+ PHINode *PHI = new PHINode(Ty);
+ PHI->reserveOperandSpace((yyvsp[0].PHIList).P->size());
+ while ((yyvsp[0].PHIList).P->begin() != (yyvsp[0].PHIList).P->end()) {
+ if ((yyvsp[0].PHIList).P->front().first->getType() != Ty)
+ error("All elements of a PHI node must be of the same type");
+ PHI->addIncoming((yyvsp[0].PHIList).P->front().first, (yyvsp[0].PHIList).P->front().second);
+ (yyvsp[0].PHIList).P->pop_front();
+ }
+ (yyval.InstVal).I = PHI;
+ (yyval.InstVal).S.copy((yyvsp[0].PHIList).S);
+ delete (yyvsp[0].PHIList).P; // Free the list...
+ ;}
+ break;
+
+ case 297:
+#line 3725 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ // Handle the short call syntax
+ const PointerType *PFTy;
+ const FunctionType *FTy;
+ Signedness FTySign;
+ if (!(PFTy = dyn_cast<PointerType>((yyvsp[-4].TypeVal).PAT->get())) ||
+ !(FTy = dyn_cast<FunctionType>(PFTy->getElementType()))) {
+ // Pull out the types of all of the arguments...
+ std::vector<const Type*> ParamTypes;
+ FTySign.makeComposite((yyvsp[-4].TypeVal).S);
+ if ((yyvsp[-1].ValueList)) {
+ for (std::vector<ValueInfo>::iterator I = (yyvsp[-1].ValueList)->begin(), E = (yyvsp[-1].ValueList)->end();
+ I != E; ++I) {
+ ParamTypes.push_back((*I).V->getType());
+ FTySign.add(I->S);
+ }
+ }
+
+ bool isVarArg = ParamTypes.size() && ParamTypes.back() == Type::VoidTy;
+ if (isVarArg) ParamTypes.pop_back();
+
+ const Type *RetTy = (yyvsp[-4].TypeVal).PAT->get();
+ if (!RetTy->isFirstClassType() && RetTy != Type::VoidTy)
+ error("Functions cannot return aggregate types");
+
+ // Deal with CSRetCC
+ ParamAttrsList *PAL = 0;
+ if ((yyvsp[-5].UIntVal) == OldCallingConv::CSRet) {
+ ParamAttrsVector Attrs;
+ ParamAttrsWithIndex PAWI;
+ PAWI.index = 1; PAWI.attrs = ParamAttr::StructRet; // first arg
+ Attrs.push_back(PAWI);
+ PAL = ParamAttrsList::get(Attrs);
+ }
+
+ FTy = FunctionType::get(RetTy, ParamTypes, isVarArg, PAL);
+ PFTy = PointerType::get(FTy);
+ (yyval.InstVal).S.copy((yyvsp[-4].TypeVal).S);
+ } else {
+ FTySign = (yyvsp[-4].TypeVal).S;
+ // Get the signedness of the result type. $3 is the pointer to the
+ // function type so we get the 0th element to extract the function type,
+ // and then the 0th element again to get the result type.
+ (yyval.InstVal).S.copy((yyvsp[-4].TypeVal).S.get(0).get(0));
+ }
+ (yyvsp[-3].ValIDVal).S.makeComposite(FTySign);
+
+ // First upgrade any intrinsic calls.
+ std::vector<Value*> Args;
+ if ((yyvsp[-1].ValueList))
+ for (unsigned i = 0, e = (yyvsp[-1].ValueList)->size(); i < e; ++i)
+ Args.push_back((*(yyvsp[-1].ValueList))[i].V);
+ Instruction *Inst = upgradeIntrinsicCall(FTy->getReturnType(), (yyvsp[-3].ValIDVal), Args);
+
+ // If we got an upgraded intrinsic
+ if (Inst) {
+ (yyval.InstVal).I = Inst;
+ } else {
+ // Get the function we're calling
+ Value *V = getVal(PFTy, (yyvsp[-3].ValIDVal));
+
+ // Check the argument values match
+ if (!(yyvsp[-1].ValueList)) { // Has no arguments?
+ // Make sure no arguments is a good thing!
+ if (FTy->getNumParams() != 0)
+ error("No arguments passed to a function that expects arguments");
+ } else { // Has arguments?
+ // Loop through FunctionType's arguments and ensure they are specified
+ // correctly!
+ //
+ FunctionType::param_iterator I = FTy->param_begin();
+ FunctionType::param_iterator E = FTy->param_end();
+ std::vector<ValueInfo>::iterator ArgI = (yyvsp[-1].ValueList)->begin(), ArgE = (yyvsp[-1].ValueList)->end();
+
+ for (; ArgI != ArgE && I != E; ++ArgI, ++I)
+ if ((*ArgI).V->getType() != *I)
+ error("Parameter " +(*ArgI).V->getName()+ " is not of type '" +
+ (*I)->getDescription() + "'");
+
+ if (I != E || (ArgI != ArgE && !FTy->isVarArg()))
+ error("Invalid number of parameters detected");
+ }
+
+ // Create the call instruction
+ CallInst *CI = new CallInst(V, &Args[0], Args.size());
+ CI->setTailCall((yyvsp[-6].BoolVal));
+ CI->setCallingConv(upgradeCallingConv((yyvsp[-5].UIntVal)));
+ (yyval.InstVal).I = CI;
+ }
+ delete (yyvsp[-4].TypeVal).PAT;
+ delete (yyvsp[-1].ValueList);
+ lastCallingConv = OldCallingConv::C;
+ ;}
+ break;
+
+ case 298:
+#line 3818 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyval.InstVal) = (yyvsp[0].InstVal);
+ ;}
+ break;
+
+ case 299:
+#line 3826 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.ValueList) = (yyvsp[0].ValueList); ;}
+ break;
+
+ case 300:
+#line 3827 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.ValueList) = new std::vector<ValueInfo>(); ;}
+ break;
+
+ case 301:
+#line 3831 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.BoolVal) = true; ;}
+ break;
+
+ case 302:
+#line 3832 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ { (yyval.BoolVal) = false; ;}
+ break;
+
+ case 303:
+#line 3836 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ const Type *Ty = (yyvsp[-1].TypeVal).PAT->get();
+ (yyval.InstVal).S.makeComposite((yyvsp[-1].TypeVal).S);
+ (yyval.InstVal).I = new MallocInst(Ty, 0, (yyvsp[0].UIntVal));
+ delete (yyvsp[-1].TypeVal).PAT;
+ ;}
+ break;
+
+ case 304:
+#line 3842 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ const Type *Ty = (yyvsp[-4].TypeVal).PAT->get();
+ (yyvsp[-1].ValIDVal).S.makeUnsigned();
+ (yyval.InstVal).S.makeComposite((yyvsp[-4].TypeVal).S);
+ (yyval.InstVal).I = new MallocInst(Ty, getVal((yyvsp[-2].PrimType).T, (yyvsp[-1].ValIDVal)), (yyvsp[0].UIntVal));
+ delete (yyvsp[-4].TypeVal).PAT;
+ ;}
+ break;
+
+ case 305:
+#line 3849 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ const Type *Ty = (yyvsp[-1].TypeVal).PAT->get();
+ (yyval.InstVal).S.makeComposite((yyvsp[-1].TypeVal).S);
+ (yyval.InstVal).I = new AllocaInst(Ty, 0, (yyvsp[0].UIntVal));
+ delete (yyvsp[-1].TypeVal).PAT;
+ ;}
+ break;
+
+ case 306:
+#line 3855 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ const Type *Ty = (yyvsp[-4].TypeVal).PAT->get();
+ (yyvsp[-1].ValIDVal).S.makeUnsigned();
+ (yyval.InstVal).S.makeComposite((yyvsp[-2].PrimType).S);
+ (yyval.InstVal).I = new AllocaInst(Ty, getVal((yyvsp[-2].PrimType).T, (yyvsp[-1].ValIDVal)), (yyvsp[0].UIntVal));
+ delete (yyvsp[-4].TypeVal).PAT;
+ ;}
+ break;
+
+ case 307:
+#line 3862 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ const Type *PTy = (yyvsp[0].ValueVal).V->getType();
+ if (!isa<PointerType>(PTy))
+ error("Trying to free nonpointer type '" + PTy->getDescription() + "'");
+ (yyval.InstVal).I = new FreeInst((yyvsp[0].ValueVal).V);
+ (yyval.InstVal).S.makeSignless();
+ ;}
+ break;
+
+ case 308:
+#line 3869 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ const Type* Ty = (yyvsp[-1].TypeVal).PAT->get();
+ (yyvsp[0].ValIDVal).S.copy((yyvsp[-1].TypeVal).S);
+ if (!isa<PointerType>(Ty))
+ error("Can't load from nonpointer type: " + Ty->getDescription());
+ if (!cast<PointerType>(Ty)->getElementType()->isFirstClassType())
+ error("Can't load from pointer of non-first-class type: " +
+ Ty->getDescription());
+ Value* tmpVal = getVal(Ty, (yyvsp[0].ValIDVal));
+ (yyval.InstVal).I = new LoadInst(tmpVal, "", (yyvsp[-3].BoolVal));
+ (yyval.InstVal).S.copy((yyvsp[-1].TypeVal).S.get(0));
+ delete (yyvsp[-1].TypeVal).PAT;
+ ;}
+ break;
+
+ case 309:
+#line 3882 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyvsp[0].ValIDVal).S.copy((yyvsp[-1].TypeVal).S);
+ const PointerType *PTy = dyn_cast<PointerType>((yyvsp[-1].TypeVal).PAT->get());
+ if (!PTy)
+ error("Can't store to a nonpointer type: " +
+ (yyvsp[-1].TypeVal).PAT->get()->getDescription());
+ const Type *ElTy = PTy->getElementType();
+ Value *StoreVal = (yyvsp[-3].ValueVal).V;
+ Value* tmpVal = getVal(PTy, (yyvsp[0].ValIDVal));
+ if (ElTy != (yyvsp[-3].ValueVal).V->getType()) {
+ StoreVal = handleSRetFuncTypeMerge((yyvsp[-3].ValueVal).V, ElTy);
+ if (!StoreVal)
+ error("Can't store '" + (yyvsp[-3].ValueVal).V->getType()->getDescription() +
+ "' into space of type '" + ElTy->getDescription() + "'");
+ else {
+ PTy = PointerType::get(StoreVal->getType());
+ if (Constant *C = dyn_cast<Constant>(tmpVal))
+ tmpVal = ConstantExpr::getBitCast(C, PTy);
+ else
+ tmpVal = new BitCastInst(tmpVal, PTy, "upgrd.cast", CurBB);
+ }
+ }
+ (yyval.InstVal).I = new StoreInst(StoreVal, tmpVal, (yyvsp[-5].BoolVal));
+ (yyval.InstVal).S.makeSignless();
+ delete (yyvsp[-1].TypeVal).PAT;
+ ;}
+ break;
+
+ case 310:
+#line 3908 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+ {
+ (yyvsp[-1].ValIDVal).S.copy((yyvsp[-2].TypeVal).S);
+ const Type* Ty = (yyvsp[-2].TypeVal).PAT->get();
+ if (!isa<PointerType>(Ty))
+ error("getelementptr insn requires pointer operand");
+
+ std::vector<Value*> VIndices;
+ upgradeGEPInstIndices(Ty, (yyvsp[0].ValueList), VIndices);
+
+ Value* tmpVal = getVal(Ty, (yyvsp[-1].ValIDVal));
+ (yyval.InstVal).I = new GetElementPtrInst(tmpVal, &VIndices[0], VIndices.size());
+ ValueInfo VI; VI.V = tmpVal; VI.S.copy((yyvsp[-2].TypeVal).S);
+ (yyval.InstVal).S.copy(getElementSign(VI, VIndices));
+ delete (yyvsp[-2].TypeVal).PAT;
+ delete (yyvsp[0].ValueList);
+ ;}
+ break;
+
+
+ default: break;
+ }
+
+/* Line 1126 of yacc.c. */
+#line 6644 "UpgradeParser.tab.c"
+
+ yyvsp -= yylen;
+ yyssp -= yylen;
+
+
+ YY_STACK_PRINT (yyss, yyssp);
+
+ *++yyvsp = yyval;
+
+
+ /* Now `shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTOKENS];
+
+ goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+#if YYERROR_VERBOSE
+ yyn = yypact[yystate];
+
+ if (YYPACT_NINF < yyn && yyn < YYLAST)
+ {
+ int yytype = YYTRANSLATE (yychar);
+ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+ YYSIZE_T yysize = yysize0;
+ YYSIZE_T yysize1;
+ int yysize_overflow = 0;
+ char *yymsg = 0;
+# define YYERROR_VERBOSE_ARGS_MAXIMUM 5
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ int yyx;
+
+#if 0
+ /* This is so xgettext sees the translatable formats that are
+ constructed on the fly. */
+ YY_("syntax error, unexpected %s");
+ YY_("syntax error, unexpected %s, expecting %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+#endif
+ char *yyfmt;
+ char const *yyf;
+ static char const yyunexpected[] = "syntax error, unexpected %s";
+ static char const yyexpecting[] = ", expecting %s";
+ static char const yyor[] = " or %s";
+ char yyformat[sizeof yyunexpected
+ + sizeof yyexpecting - 1
+ + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+ * (sizeof yyor - 1))];
+ char const *yyprefix = yyexpecting;
+
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yycount = 1;
+
+ yyarg[0] = yytname[yytype];
+ yyfmt = yystpcpy (yyformat, yyunexpected);
+
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ yyformat[sizeof yyunexpected - 1] = '\0';
+ break;
+ }
+ yyarg[yycount++] = yytname[yyx];
+ yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+ yysize_overflow |= yysize1 < yysize;
+ yysize = yysize1;
+ yyfmt = yystpcpy (yyfmt, yyprefix);
+ yyprefix = yyor;
+ }
+
+ yyf = YY_(yyformat);
+ yysize1 = yysize + yystrlen (yyf);
+ yysize_overflow |= yysize1 < yysize;
+ yysize = yysize1;
+
+ if (!yysize_overflow && yysize <= YYSTACK_ALLOC_MAXIMUM)
+ yymsg = (char *) YYSTACK_ALLOC (yysize);
+ if (yymsg)
+ {
+ /* Avoid sprintf, as that infringes on the user's name space.
+ Don't have undefined behavior even if the translation
+ produced a string with the wrong number of "%s"s. */
+ char *yyp = yymsg;
+ int yyi = 0;
+ while ((*yyp = *yyf))
+ {
+ if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+ {
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
+ yyf += 2;
+ }
+ else
+ {
+ yyp++;
+ yyf++;
+ }
+ }
+ yyerror (yymsg);
+ YYSTACK_FREE (yymsg);
+ }
+ else
+ {
+ yyerror (YY_("syntax error"));
+ goto yyexhaustedlab;
+ }
+ }
+ else
+#endif /* YYERROR_VERBOSE */
+ yyerror (YY_("syntax error"));
+ }
+
+
+
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse look-ahead token after an
+ error, discard it. */
+
+ if (yychar <= YYEOF)
+ {
+ /* Return failure if at end of input. */
+ if (yychar == YYEOF)
+ YYABORT;
+ }
+ else
+ {
+ yydestruct ("Error: discarding", yytoken, &yylval);
+ yychar = YYEMPTY;
+ }
+ }
+
+ /* Else will try to reuse look-ahead token after shifting the error
+ token. */
+ goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
+
+ /* Pacify compilers like GCC when the user code never invokes
+ YYERROR and the label yyerrorlab therefore never appears in user
+ code. */
+ if (0)
+ goto yyerrorlab;
+
+yyvsp -= yylen;
+ yyssp -= yylen;
+ yystate = *yyssp;
+ goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (yyn != YYPACT_NINF)
+ {
+ yyn += YYTERROR;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+
+ yydestruct ("Error: popping", yystos[yystate], yyvsp);
+ YYPOPSTACK;
+ yystate = *yyssp;
+ YY_STACK_PRINT (yyss, yyssp);
+ }
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ *++yyvsp = yylval;
+
+
+ /* Shift the error token. */
+ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+#ifndef yyoverflow
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here. |
+`-------------------------------------------------*/
+yyexhaustedlab:
+ yyerror (YY_("memory exhausted"));
+ yyresult = 2;
+ /* Fall through. */
+#endif
+
+yyreturn:
+ if (yychar != YYEOF && yychar != YYEMPTY)
+ yydestruct ("Cleanup: discarding lookahead",
+ yytoken, &yylval);
+ while (yyssp != yyss)
+ {
+ yydestruct ("Cleanup: popping",
+ yystos[*yyssp], yyvsp);
+ YYPOPSTACK;
+ }
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+ return yyresult;
+}
+
+
+#line 3926 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+
+
+int yyerror(const char *ErrorMsg) {
+ std::string where
+ = std::string((CurFilename == "-") ? std::string("<stdin>") : CurFilename)
+ + ":" + llvm::utostr((unsigned) Upgradelineno) + ": ";
+ std::string errMsg = where + "error: " + std::string(ErrorMsg);
+ if (yychar != YYEMPTY && yychar != 0)
+ errMsg += " while reading token '" + std::string(Upgradetext, Upgradeleng) +
+ "'.";
+ std::cerr << "llvm-upgrade: " << errMsg << '\n';
+ std::cout << "llvm-upgrade: parse failed.\n";
+ exit(1);
+}
+
+void warning(const std::string& ErrorMsg) {
+ std::string where
+ = std::string((CurFilename == "-") ? std::string("<stdin>") : CurFilename)
+ + ":" + llvm::utostr((unsigned) Upgradelineno) + ": ";
+ std::string errMsg = where + "warning: " + std::string(ErrorMsg);
+ if (yychar != YYEMPTY && yychar != 0)
+ errMsg += " while reading token '" + std::string(Upgradetext, Upgradeleng) +
+ "'.";
+ std::cerr << "llvm-upgrade: " << errMsg << '\n';
+}
+
+void error(const std::string& ErrorMsg, int LineNo) {
+ if (LineNo == -1) LineNo = Upgradelineno;
+ Upgradelineno = LineNo;
+ yyerror(ErrorMsg.c_str());
+}
+
+
diff --git a/tools/llvm-upgrade/UpgradeParser.h.cvs b/tools/llvm-upgrade/UpgradeParser.h.cvs
new file mode 100644
index 0000000..5666ff9
--- /dev/null
+++ b/tools/llvm-upgrade/UpgradeParser.h.cvs
@@ -0,0 +1,390 @@
+/* A Bison parser, made by GNU Bison 2.1. */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+/* As a special exception, when this file is copied by Bison into a
+ Bison output file, you may use that output file without restriction.
+ This special exception was added by the Free Software Foundation
+ in version 1.24 of Bison. */
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ ESINT64VAL = 258,
+ EUINT64VAL = 259,
+ SINTVAL = 260,
+ UINTVAL = 261,
+ FPVAL = 262,
+ VOID = 263,
+ BOOL = 264,
+ SBYTE = 265,
+ UBYTE = 266,
+ SHORT = 267,
+ USHORT = 268,
+ INT = 269,
+ UINT = 270,
+ LONG = 271,
+ ULONG = 272,
+ FLOAT = 273,
+ DOUBLE = 274,
+ TYPE = 275,
+ LABEL = 276,
+ VAR_ID = 277,
+ LABELSTR = 278,
+ STRINGCONSTANT = 279,
+ IMPLEMENTATION = 280,
+ ZEROINITIALIZER = 281,
+ TRUETOK = 282,
+ FALSETOK = 283,
+ BEGINTOK = 284,
+ ENDTOK = 285,
+ DECLARE = 286,
+ GLOBAL = 287,
+ CONSTANT = 288,
+ SECTION = 289,
+ VOLATILE = 290,
+ TO = 291,
+ DOTDOTDOT = 292,
+ NULL_TOK = 293,
+ UNDEF = 294,
+ CONST = 295,
+ INTERNAL = 296,
+ LINKONCE = 297,
+ WEAK = 298,
+ APPENDING = 299,
+ DLLIMPORT = 300,
+ DLLEXPORT = 301,
+ EXTERN_WEAK = 302,
+ OPAQUE = 303,
+ NOT = 304,
+ EXTERNAL = 305,
+ TARGET = 306,
+ TRIPLE = 307,
+ ENDIAN = 308,
+ POINTERSIZE = 309,
+ LITTLE = 310,
+ BIG = 311,
+ ALIGN = 312,
+ DEPLIBS = 313,
+ CALL = 314,
+ TAIL = 315,
+ ASM_TOK = 316,
+ MODULE = 317,
+ SIDEEFFECT = 318,
+ CC_TOK = 319,
+ CCC_TOK = 320,
+ CSRETCC_TOK = 321,
+ FASTCC_TOK = 322,
+ COLDCC_TOK = 323,
+ X86_STDCALLCC_TOK = 324,
+ X86_FASTCALLCC_TOK = 325,
+ DATALAYOUT = 326,
+ RET = 327,
+ BR = 328,
+ SWITCH = 329,
+ INVOKE = 330,
+ UNREACHABLE = 331,
+ UNWIND = 332,
+ EXCEPT = 333,
+ ADD = 334,
+ SUB = 335,
+ MUL = 336,
+ DIV = 337,
+ UDIV = 338,
+ SDIV = 339,
+ FDIV = 340,
+ REM = 341,
+ UREM = 342,
+ SREM = 343,
+ FREM = 344,
+ AND = 345,
+ OR = 346,
+ XOR = 347,
+ SHL = 348,
+ SHR = 349,
+ ASHR = 350,
+ LSHR = 351,
+ SETLE = 352,
+ SETGE = 353,
+ SETLT = 354,
+ SETGT = 355,
+ SETEQ = 356,
+ SETNE = 357,
+ ICMP = 358,
+ FCMP = 359,
+ MALLOC = 360,
+ ALLOCA = 361,
+ FREE = 362,
+ LOAD = 363,
+ STORE = 364,
+ GETELEMENTPTR = 365,
+ PHI_TOK = 366,
+ SELECT = 367,
+ VAARG = 368,
+ EXTRACTELEMENT = 369,
+ INSERTELEMENT = 370,
+ SHUFFLEVECTOR = 371,
+ VAARG_old = 372,
+ VANEXT_old = 373,
+ EQ = 374,
+ NE = 375,
+ SLT = 376,
+ SGT = 377,
+ SLE = 378,
+ SGE = 379,
+ ULT = 380,
+ UGT = 381,
+ ULE = 382,
+ UGE = 383,
+ OEQ = 384,
+ ONE = 385,
+ OLT = 386,
+ OGT = 387,
+ OLE = 388,
+ OGE = 389,
+ ORD = 390,
+ UNO = 391,
+ UEQ = 392,
+ UNE = 393,
+ CAST = 394,
+ TRUNC = 395,
+ ZEXT = 396,
+ SEXT = 397,
+ FPTRUNC = 398,
+ FPEXT = 399,
+ FPTOUI = 400,
+ FPTOSI = 401,
+ UITOFP = 402,
+ SITOFP = 403,
+ PTRTOINT = 404,
+ INTTOPTR = 405,
+ BITCAST = 406
+ };
+#endif
+/* Tokens. */
+#define ESINT64VAL 258
+#define EUINT64VAL 259
+#define SINTVAL 260
+#define UINTVAL 261
+#define FPVAL 262
+#define VOID 263
+#define BOOL 264
+#define SBYTE 265
+#define UBYTE 266
+#define SHORT 267
+#define USHORT 268
+#define INT 269
+#define UINT 270
+#define LONG 271
+#define ULONG 272
+#define FLOAT 273
+#define DOUBLE 274
+#define TYPE 275
+#define LABEL 276
+#define VAR_ID 277
+#define LABELSTR 278
+#define STRINGCONSTANT 279
+#define IMPLEMENTATION 280
+#define ZEROINITIALIZER 281
+#define TRUETOK 282
+#define FALSETOK 283
+#define BEGINTOK 284
+#define ENDTOK 285
+#define DECLARE 286
+#define GLOBAL 287
+#define CONSTANT 288
+#define SECTION 289
+#define VOLATILE 290
+#define TO 291
+#define DOTDOTDOT 292
+#define NULL_TOK 293
+#define UNDEF 294
+#define CONST 295
+#define INTERNAL 296
+#define LINKONCE 297
+#define WEAK 298
+#define APPENDING 299
+#define DLLIMPORT 300
+#define DLLEXPORT 301
+#define EXTERN_WEAK 302
+#define OPAQUE 303
+#define NOT 304
+#define EXTERNAL 305
+#define TARGET 306
+#define TRIPLE 307
+#define ENDIAN 308
+#define POINTERSIZE 309
+#define LITTLE 310
+#define BIG 311
+#define ALIGN 312
+#define DEPLIBS 313
+#define CALL 314
+#define TAIL 315
+#define ASM_TOK 316
+#define MODULE 317
+#define SIDEEFFECT 318
+#define CC_TOK 319
+#define CCC_TOK 320
+#define CSRETCC_TOK 321
+#define FASTCC_TOK 322
+#define COLDCC_TOK 323
+#define X86_STDCALLCC_TOK 324
+#define X86_FASTCALLCC_TOK 325
+#define DATALAYOUT 326
+#define RET 327
+#define BR 328
+#define SWITCH 329
+#define INVOKE 330
+#define UNREACHABLE 331
+#define UNWIND 332
+#define EXCEPT 333
+#define ADD 334
+#define SUB 335
+#define MUL 336
+#define DIV 337
+#define UDIV 338
+#define SDIV 339
+#define FDIV 340
+#define REM 341
+#define UREM 342
+#define SREM 343
+#define FREM 344
+#define AND 345
+#define OR 346
+#define XOR 347
+#define SHL 348
+#define SHR 349
+#define ASHR 350
+#define LSHR 351
+#define SETLE 352
+#define SETGE 353
+#define SETLT 354
+#define SETGT 355
+#define SETEQ 356
+#define SETNE 357
+#define ICMP 358
+#define FCMP 359
+#define MALLOC 360
+#define ALLOCA 361
+#define FREE 362
+#define LOAD 363
+#define STORE 364
+#define GETELEMENTPTR 365
+#define PHI_TOK 366
+#define SELECT 367
+#define VAARG 368
+#define EXTRACTELEMENT 369
+#define INSERTELEMENT 370
+#define SHUFFLEVECTOR 371
+#define VAARG_old 372
+#define VANEXT_old 373
+#define EQ 374
+#define NE 375
+#define SLT 376
+#define SGT 377
+#define SLE 378
+#define SGE 379
+#define ULT 380
+#define UGT 381
+#define ULE 382
+#define UGE 383
+#define OEQ 384
+#define ONE 385
+#define OLT 386
+#define OGT 387
+#define OLE 388
+#define OGE 389
+#define ORD 390
+#define UNO 391
+#define UEQ 392
+#define UNE 393
+#define CAST 394
+#define TRUNC 395
+#define ZEXT 396
+#define SEXT 397
+#define FPTRUNC 398
+#define FPEXT 399
+#define FPTOUI 400
+#define FPTOSI 401
+#define UITOFP 402
+#define SITOFP 403
+#define PTRTOINT 404
+#define INTTOPTR 405
+#define BITCAST 406
+
+
+
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+#line 1775 "/proj/llvm/llvm-4/tools/llvm-upgrade/UpgradeParser.y"
+typedef union YYSTYPE {
+ llvm::Module *ModuleVal;
+ llvm::Function *FunctionVal;
+ std::pair<llvm::PATypeInfo, char*> *ArgVal;
+ llvm::BasicBlock *BasicBlockVal;
+ llvm::TermInstInfo TermInstVal;
+ llvm::InstrInfo InstVal;
+ llvm::ConstInfo ConstVal;
+ llvm::ValueInfo ValueVal;
+ llvm::PATypeInfo TypeVal;
+ llvm::TypeInfo PrimType;
+ llvm::PHIListInfo PHIList;
+ std::list<llvm::PATypeInfo> *TypeList;
+ std::vector<llvm::ValueInfo> *ValueList;
+ std::vector<llvm::ConstInfo> *ConstVector;
+
+
+ std::vector<std::pair<llvm::PATypeInfo,char*> > *ArgList;
+ // Represent the RHS of PHI node
+ std::vector<std::pair<llvm::Constant*, llvm::BasicBlock*> > *JumpTable;
+
+ llvm::GlobalValue::LinkageTypes Linkage;
+ int64_t SInt64Val;
+ uint64_t UInt64Val;
+ int SIntVal;
+ unsigned UIntVal;
+ double FPVal;
+ bool BoolVal;
+
+ char *StrVal; // This memory is strdup'd!
+ llvm::ValID ValIDVal; // strdup'd memory maybe!
+
+ llvm::BinaryOps BinaryOpVal;
+ llvm::TermOps TermOpVal;
+ llvm::MemoryOps MemOpVal;
+ llvm::OtherOps OtherOpVal;
+ llvm::CastOps CastOpVal;
+ llvm::ICmpInst::Predicate IPred;
+ llvm::FCmpInst::Predicate FPred;
+ llvm::Module::Endianness Endianness;
+} YYSTYPE;
+/* Line 1447 of yacc.c. */
+#line 382 "UpgradeParser.tab.h"
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+extern YYSTYPE Upgradelval;
+
+
+
diff --git a/tools/llvm-upgrade/UpgradeParser.y b/tools/llvm-upgrade/UpgradeParser.y
new file mode 100644
index 0000000..ed84267
--- /dev/null
+++ b/tools/llvm-upgrade/UpgradeParser.y
@@ -0,0 +1,3957 @@
+//===-- llvmAsmParser.y - Parser for llvm assembly files --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the bison parser for LLVM assembly languages files.
+//
+//===----------------------------------------------------------------------===//
+
+%{
+#include "UpgradeInternals.h"
+#include "llvm/CallingConv.h"
+#include "llvm/InlineAsm.h"
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+#include "llvm/ParameterAttributes.h"
+#include "llvm/ValueSymbolTable.h"
+#include "llvm/Support/GetElementPtrTypeIterator.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/MathExtras.h"
+#include <algorithm>
+#include <iostream>
+#include <map>
+#include <list>
+#include <utility>
+
+// DEBUG_UPREFS - Define this symbol if you want to enable debugging output
+// relating to upreferences in the input stream.
+//
+//#define DEBUG_UPREFS 1
+#ifdef DEBUG_UPREFS
+#define UR_OUT(X) std::cerr << X
+#else
+#define UR_OUT(X)
+#endif
+
+#define YYERROR_VERBOSE 1
+#define YYINCLUDED_STDLIB_H
+#define YYDEBUG 1
+
+int yylex();
+int yyparse();
+
+int yyerror(const char*);
+static void warning(const std::string& WarningMsg);
+
+namespace llvm {
+
+std::istream* LexInput;
+static std::string CurFilename;
+
+// This bool controls whether attributes are ever added to function declarations
+// definitions and calls.
+static bool AddAttributes = false;
+
+static Module *ParserResult;
+static bool ObsoleteVarArgs;
+static bool NewVarArgs;
+static BasicBlock *CurBB;
+static GlobalVariable *CurGV;
+static unsigned lastCallingConv;
+
+// This contains info used when building the body of a function. It is
+// destroyed when the function is completed.
+//
+typedef std::vector<Value *> ValueList; // Numbered defs
+
+typedef std::pair<std::string,TypeInfo> RenameMapKey;
+typedef std::map<RenameMapKey,std::string> RenameMapType;
+
+static void
+ResolveDefinitions(std::map<const Type *,ValueList> &LateResolvers,
+ std::map<const Type *,ValueList> *FutureLateResolvers = 0);
+
+static struct PerModuleInfo {
+ Module *CurrentModule;
+ std::map<const Type *, ValueList> Values; // Module level numbered definitions
+ std::map<const Type *,ValueList> LateResolveValues;
+ std::vector<PATypeHolder> Types;
+ std::vector<Signedness> TypeSigns;
+ std::map<std::string,Signedness> NamedTypeSigns;
+ std::map<std::string,Signedness> NamedValueSigns;
+ std::map<ValID, PATypeHolder> LateResolveTypes;
+ static Module::Endianness Endian;
+ static Module::PointerSize PointerSize;
+ RenameMapType RenameMap;
+
+ /// PlaceHolderInfo - When temporary placeholder objects are created, remember
+ /// how they were referenced and on which line of the input they came from so
+ /// that we can resolve them later and print error messages as appropriate.
+ std::map<Value*, std::pair<ValID, int> > PlaceHolderInfo;
+
+ // GlobalRefs - This maintains a mapping between <Type, ValID>'s and forward
+ // references to global values. Global values may be referenced before they
+ // are defined, and if so, the temporary object that they represent is held
+ // here. This is used for forward references of GlobalValues.
+ //
+ typedef std::map<std::pair<const PointerType *, ValID>, GlobalValue*>
+ GlobalRefsType;
+ GlobalRefsType GlobalRefs;
+
+ void ModuleDone() {
+ // If we could not resolve some functions at function compilation time
+ // (calls to functions before they are defined), resolve them now... Types
+ // are resolved when the constant pool has been completely parsed.
+ //
+ ResolveDefinitions(LateResolveValues);
+
+ // Check to make sure that all global value forward references have been
+ // resolved!
+ //
+ if (!GlobalRefs.empty()) {
+ std::string UndefinedReferences = "Unresolved global references exist:\n";
+
+ for (GlobalRefsType::iterator I = GlobalRefs.begin(), E =GlobalRefs.end();
+ I != E; ++I) {
+ UndefinedReferences += " " + I->first.first->getDescription() + " " +
+ I->first.second.getName() + "\n";
+ }
+ error(UndefinedReferences);
+ return;
+ }
+
+ if (CurrentModule->getDataLayout().empty()) {
+ std::string dataLayout;
+ if (Endian != Module::AnyEndianness)
+ dataLayout.append(Endian == Module::BigEndian ? "E" : "e");
+ if (PointerSize != Module::AnyPointerSize) {
+ if (!dataLayout.empty())
+ dataLayout += "-";
+ dataLayout.append(PointerSize == Module::Pointer64 ?
+ "p:64:64" : "p:32:32");
+ }
+ CurrentModule->setDataLayout(dataLayout);
+ }
+
+ Values.clear(); // Clear out function local definitions
+ Types.clear();
+ TypeSigns.clear();
+ NamedTypeSigns.clear();
+ NamedValueSigns.clear();
+ CurrentModule = 0;
+ }
+
+ // GetForwardRefForGlobal - Check to see if there is a forward reference
+ // for this global. If so, remove it from the GlobalRefs map and return it.
+ // If not, just return null.
+ GlobalValue *GetForwardRefForGlobal(const PointerType *PTy, ValID ID) {
+ // Check to see if there is a forward reference to this global variable...
+ // if there is, eliminate it and patch the reference to use the new def'n.
+ GlobalRefsType::iterator I = GlobalRefs.find(std::make_pair(PTy, ID));
+ GlobalValue *Ret = 0;
+ if (I != GlobalRefs.end()) {
+ Ret = I->second;
+ GlobalRefs.erase(I);
+ }
+ return Ret;
+ }
+ void setEndianness(Module::Endianness E) { Endian = E; }
+ void setPointerSize(Module::PointerSize sz) { PointerSize = sz; }
+} CurModule;
+
+Module::Endianness PerModuleInfo::Endian = Module::AnyEndianness;
+Module::PointerSize PerModuleInfo::PointerSize = Module::AnyPointerSize;
+
+static struct PerFunctionInfo {
+ Function *CurrentFunction; // Pointer to current function being created
+
+ std::map<const Type*, ValueList> Values; // Keep track of #'d definitions
+ std::map<const Type*, ValueList> LateResolveValues;
+ bool isDeclare; // Is this function a forward declararation?
+ GlobalValue::LinkageTypes Linkage;// Linkage for forward declaration.
+
+ /// BBForwardRefs - When we see forward references to basic blocks, keep
+ /// track of them here.
+ std::map<BasicBlock*, std::pair<ValID, int> > BBForwardRefs;
+ std::vector<BasicBlock*> NumberedBlocks;
+ RenameMapType RenameMap;
+ unsigned NextBBNum;
+
+ inline PerFunctionInfo() {
+ CurrentFunction = 0;
+ isDeclare = false;
+ Linkage = GlobalValue::ExternalLinkage;
+ }
+
+ inline void FunctionStart(Function *M) {
+ CurrentFunction = M;
+ NextBBNum = 0;
+ }
+
+ void FunctionDone() {
+ NumberedBlocks.clear();
+
+ // Any forward referenced blocks left?
+ if (!BBForwardRefs.empty()) {
+ error("Undefined reference to label " +
+ BBForwardRefs.begin()->first->getName());
+ return;
+ }
+
+ // Resolve all forward references now.
+ ResolveDefinitions(LateResolveValues, &CurModule.LateResolveValues);
+
+ Values.clear(); // Clear out function local definitions
+ RenameMap.clear();
+ CurrentFunction = 0;
+ isDeclare = false;
+ Linkage = GlobalValue::ExternalLinkage;
+ }
+} CurFun; // Info for the current function...
+
+static bool inFunctionScope() { return CurFun.CurrentFunction != 0; }
+
+/// This function is just a utility to make a Key value for the rename map.
+/// The Key is a combination of the name, type, Signedness of the original
+/// value (global/function). This just constructs the key and ensures that
+/// named Signedness values are resolved to the actual Signedness.
+/// @brief Make a key for the RenameMaps
+static RenameMapKey makeRenameMapKey(const std::string &Name, const Type* Ty,
+ const Signedness &Sign) {
+ TypeInfo TI;
+ TI.T = Ty;
+ if (Sign.isNamed())
+ // Don't allow Named Signedness nodes because they won't match. The actual
+ // Signedness must be looked up in the NamedTypeSigns map.
+ TI.S.copy(CurModule.NamedTypeSigns[Sign.getName()]);
+ else
+ TI.S.copy(Sign);
+ return std::make_pair(Name, TI);
+}
+
+
+//===----------------------------------------------------------------------===//
+// Code to handle definitions of all the types
+//===----------------------------------------------------------------------===//
+
+static int InsertValue(Value *V,
+ std::map<const Type*,ValueList> &ValueTab = CurFun.Values) {
+ if (V->hasName()) return -1; // Is this a numbered definition?
+
+ // Yes, insert the value into the value table...
+ ValueList &List = ValueTab[V->getType()];
+ List.push_back(V);
+ return List.size()-1;
+}
+
+static const Type *getType(const ValID &D, bool DoNotImprovise = false) {
+ switch (D.Type) {
+ case ValID::NumberVal: // Is it a numbered definition?
+ // Module constants occupy the lowest numbered slots...
+ if ((unsigned)D.Num < CurModule.Types.size()) {
+ return CurModule.Types[(unsigned)D.Num];
+ }
+ break;
+ case ValID::NameVal: // Is it a named definition?
+ if (const Type *N = CurModule.CurrentModule->getTypeByName(D.Name)) {
+ return N;
+ }
+ break;
+ default:
+ error("Internal parser error: Invalid symbol type reference");
+ return 0;
+ }
+
+ // If we reached here, we referenced either a symbol that we don't know about
+ // or an id number that hasn't been read yet. We may be referencing something
+ // forward, so just create an entry to be resolved later and get to it...
+ //
+ if (DoNotImprovise) return 0; // Do we just want a null to be returned?
+
+ if (inFunctionScope()) {
+ if (D.Type == ValID::NameVal) {
+ error("Reference to an undefined type: '" + D.getName() + "'");
+ return 0;
+ } else {
+ error("Reference to an undefined type: #" + itostr(D.Num));
+ return 0;
+ }
+ }
+
+ std::map<ValID, PATypeHolder>::iterator I =CurModule.LateResolveTypes.find(D);
+ if (I != CurModule.LateResolveTypes.end())
+ return I->second;
+
+ Type *Typ = OpaqueType::get();
+ CurModule.LateResolveTypes.insert(std::make_pair(D, Typ));
+ return Typ;
+}
+
+/// This is like the getType method except that instead of looking up the type
+/// for a given ID, it looks up that type's sign.
+/// @brief Get the signedness of a referenced type
+static Signedness getTypeSign(const ValID &D) {
+ switch (D.Type) {
+ case ValID::NumberVal: // Is it a numbered definition?
+ // Module constants occupy the lowest numbered slots...
+ if ((unsigned)D.Num < CurModule.TypeSigns.size()) {
+ return CurModule.TypeSigns[(unsigned)D.Num];
+ }
+ break;
+ case ValID::NameVal: { // Is it a named definition?
+ std::map<std::string,Signedness>::const_iterator I =
+ CurModule.NamedTypeSigns.find(D.Name);
+ if (I != CurModule.NamedTypeSigns.end())
+ return I->second;
+ // Perhaps its a named forward .. just cache the name
+ Signedness S;
+ S.makeNamed(D.Name);
+ return S;
+ }
+ default:
+ break;
+ }
+ // If we don't find it, its signless
+ Signedness S;
+ S.makeSignless();
+ return S;
+}
+
+/// This function is analagous to getElementType in LLVM. It provides the same
+/// function except that it looks up the Signedness instead of the type. This is
+/// used when processing GEP instructions that need to extract the type of an
+/// indexed struct/array/ptr member.
+/// @brief Look up an element's sign.
+static Signedness getElementSign(const ValueInfo& VI,
+ const std::vector<Value*> &Indices) {
+ const Type *Ptr = VI.V->getType();
+ assert(isa<PointerType>(Ptr) && "Need pointer type");
+
+ unsigned CurIdx = 0;
+ Signedness S(VI.S);
+ while (const CompositeType *CT = dyn_cast<CompositeType>(Ptr)) {
+ if (CurIdx == Indices.size())
+ break;
+
+ Value *Index = Indices[CurIdx++];
+ assert(!isa<PointerType>(CT) || CurIdx == 1 && "Invalid type");
+ Ptr = CT->getTypeAtIndex(Index);
+ if (const Type* Ty = Ptr->getForwardedType())
+ Ptr = Ty;
+ assert(S.isComposite() && "Bad Signedness type");
+ if (isa<StructType>(CT)) {
+ S = S.get(cast<ConstantInt>(Index)->getZExtValue());
+ } else {
+ S = S.get(0UL);
+ }
+ if (S.isNamed())
+ S = CurModule.NamedTypeSigns[S.getName()];
+ }
+ Signedness Result;
+ Result.makeComposite(S);
+ return Result;
+}
+
+/// This function just translates a ConstantInfo into a ValueInfo and calls
+/// getElementSign(ValueInfo,...). Its just a convenience.
+/// @brief ConstantInfo version of getElementSign.
+static Signedness getElementSign(const ConstInfo& CI,
+ const std::vector<Constant*> &Indices) {
+ ValueInfo VI;
+ VI.V = CI.C;
+ VI.S.copy(CI.S);
+ std::vector<Value*> Idx;
+ for (unsigned i = 0; i < Indices.size(); ++i)
+ Idx.push_back(Indices[i]);
+ Signedness result = getElementSign(VI, Idx);
+ VI.destroy();
+ return result;
+}
+
+/// This function determines if two function types differ only in their use of
+/// the sret parameter attribute in the first argument. If they are identical
+/// in all other respects, it returns true. Otherwise, it returns false.
+static bool FuncTysDifferOnlyBySRet(const FunctionType *F1,
+ const FunctionType *F2) {
+ if (F1->getReturnType() != F2->getReturnType() ||
+ F1->getNumParams() != F2->getNumParams())
+ return false;
+ const ParamAttrsList *PAL1 = F1->getParamAttrs();
+ const ParamAttrsList *PAL2 = F2->getParamAttrs();
+ if (PAL1 && !PAL2 || PAL2 && !PAL1)
+ return false;
+ if (PAL1 && PAL2 && ((PAL1->size() != PAL2->size()) ||
+ (PAL1->getParamAttrs(0) != PAL2->getParamAttrs(0))))
+ return false;
+ unsigned SRetMask = ~unsigned(ParamAttr::StructRet);
+ for (unsigned i = 0; i < F1->getNumParams(); ++i) {
+ if (F1->getParamType(i) != F2->getParamType(i) || (PAL1 && PAL2 &&
+ (unsigned(PAL1->getParamAttrs(i+1)) & SRetMask !=
+ unsigned(PAL2->getParamAttrs(i+1)) & SRetMask)))
+ return false;
+ }
+ return true;
+}
+
+/// This function determines if the type of V and Ty differ only by the SRet
+/// parameter attribute. This is a more generalized case of
+/// FuncTysDIfferOnlyBySRet since it doesn't require FunctionType arguments.
+static bool TypesDifferOnlyBySRet(Value *V, const Type* Ty) {
+ if (V->getType() == Ty)
+ return true;
+ const PointerType *PF1 = dyn_cast<PointerType>(Ty);
+ const PointerType *PF2 = dyn_cast<PointerType>(V->getType());
+ if (PF1 && PF2) {
+ const FunctionType* FT1 = dyn_cast<FunctionType>(PF1->getElementType());
+ const FunctionType* FT2 = dyn_cast<FunctionType>(PF2->getElementType());
+ if (FT1 && FT2)
+ return FuncTysDifferOnlyBySRet(FT1, FT2);
+ }
+ return false;
+}
+
+// The upgrade of csretcc to sret param attribute may have caused a function
+// to not be found because the param attribute changed the type of the called
+// function. This helper function, used in getExistingValue, detects that
+// situation and bitcasts the function to the correct type.
+static Value* handleSRetFuncTypeMerge(Value *V, const Type* Ty) {
+ // Handle degenerate cases
+ if (!V)
+ return 0;
+ if (V->getType() == Ty)
+ return V;
+
+ const PointerType *PF1 = dyn_cast<PointerType>(Ty);
+ const PointerType *PF2 = dyn_cast<PointerType>(V->getType());
+ if (PF1 && PF2) {
+ const FunctionType *FT1 = dyn_cast<FunctionType>(PF1->getElementType());
+ const FunctionType *FT2 = dyn_cast<FunctionType>(PF2->getElementType());
+ if (FT1 && FT2 && FuncTysDifferOnlyBySRet(FT1, FT2)) {
+ const ParamAttrsList *PAL2 = FT2->getParamAttrs();
+ if (PAL2 && PAL2->paramHasAttr(1, ParamAttr::StructRet))
+ return V;
+ else if (Constant *C = dyn_cast<Constant>(V))
+ return ConstantExpr::getBitCast(C, PF1);
+ else
+ return new BitCastInst(V, PF1, "upgrd.cast", CurBB);
+ }
+
+ }
+ return 0;
+}
+
+// getExistingValue - Look up the value specified by the provided type and
+// the provided ValID. If the value exists and has already been defined, return
+// it. Otherwise return null.
+//
+static Value *getExistingValue(const Type *Ty, const ValID &D) {
+ if (isa<FunctionType>(Ty)) {
+ error("Functions are not values and must be referenced as pointers");
+ }
+
+ switch (D.Type) {
+ case ValID::NumberVal: { // Is it a numbered definition?
+ unsigned Num = (unsigned)D.Num;
+
+ // Module constants occupy the lowest numbered slots...
+ std::map<const Type*,ValueList>::iterator VI = CurModule.Values.find(Ty);
+ if (VI != CurModule.Values.end()) {
+ if (Num < VI->second.size())
+ return VI->second[Num];
+ Num -= VI->second.size();
+ }
+
+ // Make sure that our type is within bounds
+ VI = CurFun.Values.find(Ty);
+ if (VI == CurFun.Values.end()) return 0;
+
+ // Check that the number is within bounds...
+ if (VI->second.size() <= Num) return 0;
+
+ return VI->second[Num];
+ }
+
+ case ValID::NameVal: { // Is it a named definition?
+ // Get the name out of the ID
+ RenameMapKey Key = makeRenameMapKey(D.Name, Ty, D.S);
+ Value *V = 0;
+ if (inFunctionScope()) {
+ // See if the name was renamed
+ RenameMapType::const_iterator I = CurFun.RenameMap.find(Key);
+ std::string LookupName;
+ if (I != CurFun.RenameMap.end())
+ LookupName = I->second;
+ else
+ LookupName = D.Name;
+ ValueSymbolTable &SymTab = CurFun.CurrentFunction->getValueSymbolTable();
+ V = SymTab.lookup(LookupName);
+ if (V && V->getType() != Ty)
+ V = handleSRetFuncTypeMerge(V, Ty);
+ assert((!V || TypesDifferOnlyBySRet(V, Ty)) && "Found wrong type");
+ }
+ if (!V) {
+ RenameMapType::const_iterator I = CurModule.RenameMap.find(Key);
+ std::string LookupName;
+ if (I != CurModule.RenameMap.end())
+ LookupName = I->second;
+ else
+ LookupName = D.Name;
+ V = CurModule.CurrentModule->getValueSymbolTable().lookup(LookupName);
+ if (V && V->getType() != Ty)
+ V = handleSRetFuncTypeMerge(V, Ty);
+ assert((!V || TypesDifferOnlyBySRet(V, Ty)) && "Found wrong type");
+ }
+ if (!V)
+ return 0;
+
+ D.destroy(); // Free old strdup'd memory...
+ return V;
+ }
+
+ // Check to make sure that "Ty" is an integral type, and that our
+ // value will fit into the specified type...
+ case ValID::ConstSIntVal: // Is it a constant pool reference??
+ if (!ConstantInt::isValueValidForType(Ty, D.ConstPool64)) {
+ error("Signed integral constant '" + itostr(D.ConstPool64) +
+ "' is invalid for type '" + Ty->getDescription() + "'");
+ }
+ return ConstantInt::get(Ty, D.ConstPool64);
+
+ case ValID::ConstUIntVal: // Is it an unsigned const pool reference?
+ if (!ConstantInt::isValueValidForType(Ty, D.UConstPool64)) {
+ if (!ConstantInt::isValueValidForType(Ty, D.ConstPool64))
+ error("Integral constant '" + utostr(D.UConstPool64) +
+ "' is invalid or out of range");
+ else // This is really a signed reference. Transmogrify.
+ return ConstantInt::get(Ty, D.ConstPool64);
+ } else
+ return ConstantInt::get(Ty, D.UConstPool64);
+
+ case ValID::ConstFPVal: // Is it a floating point const pool reference?
+ if (!ConstantFP::isValueValidForType(Ty, D.ConstPoolFP))
+ error("FP constant invalid for type");
+ return ConstantFP::get(Ty, D.ConstPoolFP);
+
+ case ValID::ConstNullVal: // Is it a null value?
+ if (!isa<PointerType>(Ty))
+ error("Cannot create a a non pointer null");
+ return ConstantPointerNull::get(cast<PointerType>(Ty));
+
+ case ValID::ConstUndefVal: // Is it an undef value?
+ return UndefValue::get(Ty);
+
+ case ValID::ConstZeroVal: // Is it a zero value?
+ return Constant::getNullValue(Ty);
+
+ case ValID::ConstantVal: // Fully resolved constant?
+ if (D.ConstantValue->getType() != Ty)
+ error("Constant expression type different from required type");
+ return D.ConstantValue;
+
+ case ValID::InlineAsmVal: { // Inline asm expression
+ const PointerType *PTy = dyn_cast<PointerType>(Ty);
+ const FunctionType *FTy =
+ PTy ? dyn_cast<FunctionType>(PTy->getElementType()) : 0;
+ if (!FTy || !InlineAsm::Verify(FTy, D.IAD->Constraints))
+ error("Invalid type for asm constraint string");
+ InlineAsm *IA = InlineAsm::get(FTy, D.IAD->AsmString, D.IAD->Constraints,
+ D.IAD->HasSideEffects);
+ D.destroy(); // Free InlineAsmDescriptor.
+ return IA;
+ }
+ default:
+ assert(0 && "Unhandled case");
+ return 0;
+ } // End of switch
+
+ assert(0 && "Unhandled case");
+ return 0;
+}
+
+// getVal - This function is identical to getExistingValue, except that if a
+// value is not already defined, it "improvises" by creating a placeholder var
+// that looks and acts just like the requested variable. When the value is
+// defined later, all uses of the placeholder variable are replaced with the
+// real thing.
+//
+static Value *getVal(const Type *Ty, const ValID &ID) {
+ if (Ty == Type::LabelTy)
+ error("Cannot use a basic block here");
+
+ // See if the value has already been defined.
+ Value *V = getExistingValue(Ty, ID);
+ if (V) return V;
+
+ if (!Ty->isFirstClassType() && !isa<OpaqueType>(Ty))
+ error("Invalid use of a composite type");
+
+ // If we reached here, we referenced either a symbol that we don't know about
+ // or an id number that hasn't been read yet. We may be referencing something
+ // forward, so just create an entry to be resolved later and get to it...
+ V = new Argument(Ty);
+
+ // Remember where this forward reference came from. FIXME, shouldn't we try
+ // to recycle these things??
+ CurModule.PlaceHolderInfo.insert(
+ std::make_pair(V, std::make_pair(ID, Upgradelineno)));
+
+ if (inFunctionScope())
+ InsertValue(V, CurFun.LateResolveValues);
+ else
+ InsertValue(V, CurModule.LateResolveValues);
+ return V;
+}
+
+/// @brief This just makes any name given to it unique, up to MAX_UINT times.
+static std::string makeNameUnique(const std::string& Name) {
+ static unsigned UniqueNameCounter = 1;
+ std::string Result(Name);
+ Result += ".upgrd." + llvm::utostr(UniqueNameCounter++);
+ return Result;
+}
+
+/// getBBVal - This is used for two purposes:
+/// * If isDefinition is true, a new basic block with the specified ID is being
+/// defined.
+/// * If isDefinition is true, this is a reference to a basic block, which may
+/// or may not be a forward reference.
+///
+static BasicBlock *getBBVal(const ValID &ID, bool isDefinition = false) {
+ assert(inFunctionScope() && "Can't get basic block at global scope");
+
+ std::string Name;
+ BasicBlock *BB = 0;
+ switch (ID.Type) {
+ default:
+ error("Illegal label reference " + ID.getName());
+ break;
+ case ValID::NumberVal: // Is it a numbered definition?
+ if (unsigned(ID.Num) >= CurFun.NumberedBlocks.size())
+ CurFun.NumberedBlocks.resize(ID.Num+1);
+ BB = CurFun.NumberedBlocks[ID.Num];
+ break;
+ case ValID::NameVal: // Is it a named definition?
+ Name = ID.Name;
+ if (Value *N = CurFun.CurrentFunction->getValueSymbolTable().lookup(Name)) {
+ if (N->getType() != Type::LabelTy) {
+ // Register names didn't use to conflict with basic block names
+ // because of type planes. Now they all have to be unique. So, we just
+ // rename the register and treat this name as if no basic block
+ // had been found.
+ RenameMapKey Key = makeRenameMapKey(ID.Name, N->getType(), ID.S);
+ N->setName(makeNameUnique(N->getName()));
+ CurModule.RenameMap[Key] = N->getName();
+ BB = 0;
+ } else {
+ BB = cast<BasicBlock>(N);
+ }
+ }
+ break;
+ }
+
+ // See if the block has already been defined.
+ if (BB) {
+ // If this is the definition of the block, make sure the existing value was
+ // just a forward reference. If it was a forward reference, there will be
+ // an entry for it in the PlaceHolderInfo map.
+ if (isDefinition && !CurFun.BBForwardRefs.erase(BB))
+ // The existing value was a definition, not a forward reference.
+ error("Redefinition of label " + ID.getName());
+
+ ID.destroy(); // Free strdup'd memory.
+ return BB;
+ }
+
+ // Otherwise this block has not been seen before.
+ BB = new BasicBlock("", CurFun.CurrentFunction);
+ if (ID.Type == ValID::NameVal) {
+ BB->setName(ID.Name);
+ } else {
+ CurFun.NumberedBlocks[ID.Num] = BB;
+ }
+
+ // If this is not a definition, keep track of it so we can use it as a forward
+ // reference.
+ if (!isDefinition) {
+ // Remember where this forward reference came from.
+ CurFun.BBForwardRefs[BB] = std::make_pair(ID, Upgradelineno);
+ } else {
+ // The forward declaration could have been inserted anywhere in the
+ // function: insert it into the correct place now.
+ CurFun.CurrentFunction->getBasicBlockList().remove(BB);
+ CurFun.CurrentFunction->getBasicBlockList().push_back(BB);
+ }
+ ID.destroy();
+ return BB;
+}
+
+
+//===----------------------------------------------------------------------===//
+// Code to handle forward references in instructions
+//===----------------------------------------------------------------------===//
+//
+// This code handles the late binding needed with statements that reference
+// values not defined yet... for example, a forward branch, or the PHI node for
+// a loop body.
+//
+// This keeps a table (CurFun.LateResolveValues) of all such forward references
+// and back patchs after we are done.
+//
+
+// ResolveDefinitions - If we could not resolve some defs at parsing
+// time (forward branches, phi functions for loops, etc...) resolve the
+// defs now...
+//
+static void
+ResolveDefinitions(std::map<const Type*,ValueList> &LateResolvers,
+ std::map<const Type*,ValueList> *FutureLateResolvers) {
+
+ // Loop over LateResolveDefs fixing up stuff that couldn't be resolved
+ for (std::map<const Type*,ValueList>::iterator LRI = LateResolvers.begin(),
+ E = LateResolvers.end(); LRI != E; ++LRI) {
+ const Type* Ty = LRI->first;
+ ValueList &List = LRI->second;
+ while (!List.empty()) {
+ Value *V = List.back();
+ List.pop_back();
+
+ std::map<Value*, std::pair<ValID, int> >::iterator PHI =
+ CurModule.PlaceHolderInfo.find(V);
+ assert(PHI != CurModule.PlaceHolderInfo.end() && "Placeholder error");
+
+ ValID &DID = PHI->second.first;
+
+ Value *TheRealValue = getExistingValue(Ty, DID);
+ if (TheRealValue) {
+ V->replaceAllUsesWith(TheRealValue);
+ delete V;
+ CurModule.PlaceHolderInfo.erase(PHI);
+ } else if (FutureLateResolvers) {
+ // Functions have their unresolved items forwarded to the module late
+ // resolver table
+ InsertValue(V, *FutureLateResolvers);
+ } else {
+ if (DID.Type == ValID::NameVal) {
+ error("Reference to an invalid definition: '" + DID.getName() +
+ "' of type '" + V->getType()->getDescription() + "'",
+ PHI->second.second);
+ return;
+ } else {
+ error("Reference to an invalid definition: #" +
+ itostr(DID.Num) + " of type '" +
+ V->getType()->getDescription() + "'", PHI->second.second);
+ return;
+ }
+ }
+ }
+ }
+
+ LateResolvers.clear();
+}
+
+/// This function is used for type resolution and upref handling. When a type
+/// becomes concrete, this function is called to adjust the signedness for the
+/// concrete type.
+static void ResolveTypeSign(const Type* oldTy, const Signedness &Sign) {
+ std::string TyName = CurModule.CurrentModule->getTypeName(oldTy);
+ if (!TyName.empty())
+ CurModule.NamedTypeSigns[TyName] = Sign;
+}
+
+/// ResolveTypeTo - A brand new type was just declared. This means that (if
+/// name is not null) things referencing Name can be resolved. Otherwise,
+/// things refering to the number can be resolved. Do this now.
+static void ResolveTypeTo(char *Name, const Type *ToTy, const Signedness& Sign){
+ ValID D;
+ if (Name)
+ D = ValID::create(Name);
+ else
+ D = ValID::create((int)CurModule.Types.size());
+ D.S.copy(Sign);
+
+ if (Name)
+ CurModule.NamedTypeSigns[Name] = Sign;
+
+ std::map<ValID, PATypeHolder>::iterator I =
+ CurModule.LateResolveTypes.find(D);
+ if (I != CurModule.LateResolveTypes.end()) {
+ const Type *OldTy = I->second.get();
+ ((DerivedType*)OldTy)->refineAbstractTypeTo(ToTy);
+ CurModule.LateResolveTypes.erase(I);
+ }
+}
+
+/// This is the implementation portion of TypeHasInteger. It traverses the
+/// type given, avoiding recursive types, and returns true as soon as it finds
+/// an integer type. If no integer type is found, it returns false.
+static bool TypeHasIntegerI(const Type *Ty, std::vector<const Type*> Stack) {
+ // Handle some easy cases
+ if (Ty->isPrimitiveType() || (Ty->getTypeID() == Type::OpaqueTyID))
+ return false;
+ if (Ty->isInteger())
+ return true;
+ if (const SequentialType *STy = dyn_cast<SequentialType>(Ty))
+ return STy->getElementType()->isInteger();
+
+ // Avoid type structure recursion
+ for (std::vector<const Type*>::iterator I = Stack.begin(), E = Stack.end();
+ I != E; ++I)
+ if (Ty == *I)
+ return false;
+
+ // Push us on the type stack
+ Stack.push_back(Ty);
+
+ if (const FunctionType *FTy = dyn_cast<FunctionType>(Ty)) {
+ if (TypeHasIntegerI(FTy->getReturnType(), Stack))
+ return true;
+ FunctionType::param_iterator I = FTy->param_begin();
+ FunctionType::param_iterator E = FTy->param_end();
+ for (; I != E; ++I)
+ if (TypeHasIntegerI(*I, Stack))
+ return true;
+ return false;
+ } else if (const StructType *STy = dyn_cast<StructType>(Ty)) {
+ StructType::element_iterator I = STy->element_begin();
+ StructType::element_iterator E = STy->element_end();
+ for (; I != E; ++I) {
+ if (TypeHasIntegerI(*I, Stack))
+ return true;
+ }
+ return false;
+ }
+ // There shouldn't be anything else, but its definitely not integer
+ assert(0 && "What type is this?");
+ return false;
+}
+
+/// This is the interface to TypeHasIntegerI. It just provides the type stack,
+/// to avoid recursion, and then calls TypeHasIntegerI.
+static inline bool TypeHasInteger(const Type *Ty) {
+ std::vector<const Type*> TyStack;
+ return TypeHasIntegerI(Ty, TyStack);
+}
+
+// setValueName - Set the specified value to the name given. The name may be
+// null potentially, in which case this is a noop. The string passed in is
+// assumed to be a malloc'd string buffer, and is free'd by this function.
+//
+static void setValueName(const ValueInfo &V, char *NameStr) {
+ if (NameStr) {
+ std::string Name(NameStr); // Copy string
+ free(NameStr); // Free old string
+
+ if (V.V->getType() == Type::VoidTy) {
+ error("Can't assign name '" + Name + "' to value with void type");
+ return;
+ }
+
+ assert(inFunctionScope() && "Must be in function scope");
+
+ // Search the function's symbol table for an existing value of this name
+ ValueSymbolTable &ST = CurFun.CurrentFunction->getValueSymbolTable();
+ Value* Existing = ST.lookup(Name);
+ if (Existing) {
+ // An existing value of the same name was found. This might have happened
+ // because of the integer type planes collapsing in LLVM 2.0.
+ if (Existing->getType() == V.V->getType() &&
+ !TypeHasInteger(Existing->getType())) {
+ // If the type does not contain any integers in them then this can't be
+ // a type plane collapsing issue. It truly is a redefinition and we
+ // should error out as the assembly is invalid.
+ error("Redefinition of value named '" + Name + "' of type '" +
+ V.V->getType()->getDescription() + "'");
+ return;
+ }
+ // In LLVM 2.0 we don't allow names to be re-used for any values in a
+ // function, regardless of Type. Previously re-use of names was okay as
+ // long as they were distinct types. With type planes collapsing because
+ // of the signedness change and because of PR411, this can no longer be
+ // supported. We must search the entire symbol table for a conflicting
+ // name and make the name unique. No warning is needed as this can't
+ // cause a problem.
+ std::string NewName = makeNameUnique(Name);
+ // We're changing the name but it will probably be used by other
+ // instructions as operands later on. Consequently we have to retain
+ // a mapping of the renaming that we're doing.
+ RenameMapKey Key = makeRenameMapKey(Name, V.V->getType(), V.S);
+ CurFun.RenameMap[Key] = NewName;
+ Name = NewName;
+ }
+
+ // Set the name.
+ V.V->setName(Name);
+ }
+}
+
+/// ParseGlobalVariable - Handle parsing of a global. If Initializer is null,
+/// this is a declaration, otherwise it is a definition.
+static GlobalVariable *
+ParseGlobalVariable(char *NameStr,GlobalValue::LinkageTypes Linkage,
+ bool isConstantGlobal, const Type *Ty,
+ Constant *Initializer,
+ const Signedness &Sign) {
+ if (isa<FunctionType>(Ty))
+ error("Cannot declare global vars of function type");
+
+ const PointerType *PTy = PointerType::get(Ty);
+
+ std::string Name;
+ if (NameStr) {
+ Name = NameStr; // Copy string
+ free(NameStr); // Free old string
+ }
+
+ // See if this global value was forward referenced. If so, recycle the
+ // object.
+ ValID ID;
+ if (!Name.empty()) {
+ ID = ValID::create((char*)Name.c_str());
+ } else {
+ ID = ValID::create((int)CurModule.Values[PTy].size());
+ }
+ ID.S.makeComposite(Sign);
+
+ if (GlobalValue *FWGV = CurModule.GetForwardRefForGlobal(PTy, ID)) {
+ // Move the global to the end of the list, from whereever it was
+ // previously inserted.
+ GlobalVariable *GV = cast<GlobalVariable>(FWGV);
+ CurModule.CurrentModule->getGlobalList().remove(GV);
+ CurModule.CurrentModule->getGlobalList().push_back(GV);
+ GV->setInitializer(Initializer);
+ GV->setLinkage(Linkage);
+ GV->setConstant(isConstantGlobal);
+ InsertValue(GV, CurModule.Values);
+ return GV;
+ }
+
+ // If this global has a name, check to see if there is already a definition
+ // of this global in the module and emit warnings if there are conflicts.
+ if (!Name.empty()) {
+ // The global has a name. See if there's an existing one of the same name.
+ if (CurModule.CurrentModule->getNamedGlobal(Name) ||
+ CurModule.CurrentModule->getFunction(Name)) {
+ // We found an existing global of the same name. This isn't allowed
+ // in LLVM 2.0. Consequently, we must alter the name of the global so it
+ // can at least compile. This can happen because of type planes
+ // There is alread a global of the same name which means there is a
+ // conflict. Let's see what we can do about it.
+ std::string NewName(makeNameUnique(Name));
+ if (Linkage != GlobalValue::InternalLinkage) {
+ // The linkage of this gval is external so we can't reliably rename
+ // it because it could potentially create a linking problem.
+ // However, we can't leave the name conflict in the output either or
+ // it won't assemble with LLVM 2.0. So, all we can do is rename
+ // this one to something unique and emit a warning about the problem.
+ warning("Renaming global variable '" + Name + "' to '" + NewName +
+ "' may cause linkage errors");
+ }
+
+ // Put the renaming in the global rename map
+ RenameMapKey Key = makeRenameMapKey(Name, PointerType::get(Ty), ID.S);
+ CurModule.RenameMap[Key] = NewName;
+
+ // Rename it
+ Name = NewName;
+ }
+ }
+
+ // Otherwise there is no existing GV to use, create one now.
+ GlobalVariable *GV =
+ new GlobalVariable(Ty, isConstantGlobal, Linkage, Initializer, Name,
+ CurModule.CurrentModule);
+ InsertValue(GV, CurModule.Values);
+ // Remember the sign of this global.
+ CurModule.NamedValueSigns[Name] = ID.S;
+ return GV;
+}
+
+// setTypeName - Set the specified type to the name given. The name may be
+// null potentially, in which case this is a noop. The string passed in is
+// assumed to be a malloc'd string buffer, and is freed by this function.
+//
+// This function returns true if the type has already been defined, but is
+// allowed to be redefined in the specified context. If the name is a new name
+// for the type plane, it is inserted and false is returned.
+static bool setTypeName(const PATypeInfo& TI, char *NameStr) {
+ assert(!inFunctionScope() && "Can't give types function-local names");
+ if (NameStr == 0) return false;
+
+ std::string Name(NameStr); // Copy string
+ free(NameStr); // Free old string
+
+ const Type* Ty = TI.PAT->get();
+
+ // We don't allow assigning names to void type
+ if (Ty == Type::VoidTy) {
+ error("Can't assign name '" + Name + "' to the void type");
+ return false;
+ }
+
+ // Set the type name, checking for conflicts as we do so.
+ bool AlreadyExists = CurModule.CurrentModule->addTypeName(Name, Ty);
+
+ // Save the sign information for later use
+ CurModule.NamedTypeSigns[Name] = TI.S;
+
+ if (AlreadyExists) { // Inserting a name that is already defined???
+ const Type *Existing = CurModule.CurrentModule->getTypeByName(Name);
+ assert(Existing && "Conflict but no matching type?");
+
+ // There is only one case where this is allowed: when we are refining an
+ // opaque type. In this case, Existing will be an opaque type.
+ if (const OpaqueType *OpTy = dyn_cast<OpaqueType>(Existing)) {
+ // We ARE replacing an opaque type!
+ const_cast<OpaqueType*>(OpTy)->refineAbstractTypeTo(Ty);
+ return true;
+ }
+
+ // Otherwise, this is an attempt to redefine a type. That's okay if
+ // the redefinition is identical to the original. This will be so if
+ // Existing and T point to the same Type object. In this one case we
+ // allow the equivalent redefinition.
+ if (Existing == Ty) return true; // Yes, it's equal.
+
+ // Any other kind of (non-equivalent) redefinition is an error.
+ error("Redefinition of type named '" + Name + "' in the '" +
+ Ty->getDescription() + "' type plane");
+ }
+
+ return false;
+}
+
+//===----------------------------------------------------------------------===//
+// Code for handling upreferences in type names...
+//
+
+// TypeContains - Returns true if Ty directly contains E in it.
+//
+static bool TypeContains(const Type *Ty, const Type *E) {
+ return std::find(Ty->subtype_begin(), Ty->subtype_end(),
+ E) != Ty->subtype_end();
+}
+
+namespace {
+ struct UpRefRecord {
+ // NestingLevel - The number of nesting levels that need to be popped before
+ // this type is resolved.
+ unsigned NestingLevel;
+
+ // LastContainedTy - This is the type at the current binding level for the
+ // type. Every time we reduce the nesting level, this gets updated.
+ const Type *LastContainedTy;
+
+ // UpRefTy - This is the actual opaque type that the upreference is
+ // represented with.
+ OpaqueType *UpRefTy;
+
+ UpRefRecord(unsigned NL, OpaqueType *URTy)
+ : NestingLevel(NL), LastContainedTy(URTy), UpRefTy(URTy) { }
+ };
+}
+
+// UpRefs - A list of the outstanding upreferences that need to be resolved.
+static std::vector<UpRefRecord> UpRefs;
+
+/// HandleUpRefs - Every time we finish a new layer of types, this function is
+/// called. It loops through the UpRefs vector, which is a list of the
+/// currently active types. For each type, if the up reference is contained in
+/// the newly completed type, we decrement the level count. When the level
+/// count reaches zero, the upreferenced type is the type that is passed in:
+/// thus we can complete the cycle.
+///
+static PATypeHolder HandleUpRefs(const Type *ty, const Signedness& Sign) {
+ // If Ty isn't abstract, or if there are no up-references in it, then there is
+ // nothing to resolve here.
+ if (!ty->isAbstract() || UpRefs.empty()) return ty;
+
+ PATypeHolder Ty(ty);
+ UR_OUT("Type '" << Ty->getDescription() <<
+ "' newly formed. Resolving upreferences.\n" <<
+ UpRefs.size() << " upreferences active!\n");
+
+ // If we find any resolvable upreferences (i.e., those whose NestingLevel goes
+ // to zero), we resolve them all together before we resolve them to Ty. At
+ // the end of the loop, if there is anything to resolve to Ty, it will be in
+ // this variable.
+ OpaqueType *TypeToResolve = 0;
+
+ unsigned i = 0;
+ for (; i != UpRefs.size(); ++i) {
+ UR_OUT(" UR#" << i << " - TypeContains(" << Ty->getDescription() << ", "
+ << UpRefs[i].UpRefTy->getDescription() << ") = "
+ << (TypeContains(Ty, UpRefs[i].UpRefTy) ? "true" : "false") << "\n");
+ if (TypeContains(Ty, UpRefs[i].LastContainedTy)) {
+ // Decrement level of upreference
+ unsigned Level = --UpRefs[i].NestingLevel;
+ UpRefs[i].LastContainedTy = Ty;
+ UR_OUT(" Uplevel Ref Level = " << Level << "\n");
+ if (Level == 0) { // Upreference should be resolved!
+ if (!TypeToResolve) {
+ TypeToResolve = UpRefs[i].UpRefTy;
+ } else {
+ UR_OUT(" * Resolving upreference for "
+ << UpRefs[i].UpRefTy->getDescription() << "\n";
+ std::string OldName = UpRefs[i].UpRefTy->getDescription());
+ ResolveTypeSign(UpRefs[i].UpRefTy, Sign);
+ UpRefs[i].UpRefTy->refineAbstractTypeTo(TypeToResolve);
+ UR_OUT(" * Type '" << OldName << "' refined upreference to: "
+ << (const void*)Ty << ", " << Ty->getDescription() << "\n");
+ }
+ UpRefs.erase(UpRefs.begin()+i); // Remove from upreference list...
+ --i; // Do not skip the next element...
+ }
+ }
+ }
+
+ if (TypeToResolve) {
+ UR_OUT(" * Resolving upreference for "
+ << UpRefs[i].UpRefTy->getDescription() << "\n";
+ std::string OldName = TypeToResolve->getDescription());
+ ResolveTypeSign(TypeToResolve, Sign);
+ TypeToResolve->refineAbstractTypeTo(Ty);
+ }
+
+ return Ty;
+}
+
+bool Signedness::operator<(const Signedness &that) const {
+ if (isNamed()) {
+ if (that.isNamed())
+ return *(this->name) < *(that.name);
+ else
+ return CurModule.NamedTypeSigns[*name] < that;
+ } else if (that.isNamed()) {
+ return *this < CurModule.NamedTypeSigns[*that.name];
+ }
+
+ if (isComposite() && that.isComposite()) {
+ if (sv->size() == that.sv->size()) {
+ SignVector::const_iterator thisI = sv->begin(), thisE = sv->end();
+ SignVector::const_iterator thatI = that.sv->begin(),
+ thatE = that.sv->end();
+ for (; thisI != thisE; ++thisI, ++thatI) {
+ if (*thisI < *thatI)
+ return true;
+ else if (!(*thisI == *thatI))
+ return false;
+ }
+ return false;
+ }
+ return sv->size() < that.sv->size();
+ }
+ return kind < that.kind;
+}
+
+bool Signedness::operator==(const Signedness &that) const {
+ if (isNamed())
+ if (that.isNamed())
+ return *(this->name) == *(that.name);
+ else
+ return CurModule.NamedTypeSigns[*(this->name)] == that;
+ else if (that.isNamed())
+ return *this == CurModule.NamedTypeSigns[*(that.name)];
+ if (isComposite() && that.isComposite()) {
+ if (sv->size() == that.sv->size()) {
+ SignVector::const_iterator thisI = sv->begin(), thisE = sv->end();
+ SignVector::const_iterator thatI = that.sv->begin(),
+ thatE = that.sv->end();
+ for (; thisI != thisE; ++thisI, ++thatI) {
+ if (!(*thisI == *thatI))
+ return false;
+ }
+ return true;
+ }
+ return false;
+ }
+ return kind == that.kind;
+}
+
+void Signedness::copy(const Signedness &that) {
+ if (that.isNamed()) {
+ kind = Named;
+ name = new std::string(*that.name);
+ } else if (that.isComposite()) {
+ kind = Composite;
+ sv = new SignVector();
+ *sv = *that.sv;
+ } else {
+ kind = that.kind;
+ sv = 0;
+ }
+}
+
+void Signedness::destroy() {
+ if (isNamed()) {
+ delete name;
+ } else if (isComposite()) {
+ delete sv;
+ }
+}
+
+#ifndef NDEBUG
+void Signedness::dump() const {
+ if (isComposite()) {
+ if (sv->size() == 1) {
+ (*sv)[0].dump();
+ std::cerr << "*";
+ } else {
+ std::cerr << "{ " ;
+ for (unsigned i = 0; i < sv->size(); ++i) {
+ if (i != 0)
+ std::cerr << ", ";
+ (*sv)[i].dump();
+ }
+ std::cerr << "} " ;
+ }
+ } else if (isNamed()) {
+ std::cerr << *name;
+ } else if (isSigned()) {
+ std::cerr << "S";
+ } else if (isUnsigned()) {
+ std::cerr << "U";
+ } else
+ std::cerr << ".";
+}
+#endif
+
+static inline Instruction::TermOps
+getTermOp(TermOps op) {
+ switch (op) {
+ default : assert(0 && "Invalid OldTermOp");
+ case RetOp : return Instruction::Ret;
+ case BrOp : return Instruction::Br;
+ case SwitchOp : return Instruction::Switch;
+ case InvokeOp : return Instruction::Invoke;
+ case UnwindOp : return Instruction::Unwind;
+ case UnreachableOp: return Instruction::Unreachable;
+ }
+}
+
+static inline Instruction::BinaryOps
+getBinaryOp(BinaryOps op, const Type *Ty, const Signedness& Sign) {
+ switch (op) {
+ default : assert(0 && "Invalid OldBinaryOps");
+ case SetEQ :
+ case SetNE :
+ case SetLE :
+ case SetGE :
+ case SetLT :
+ case SetGT : assert(0 && "Should use getCompareOp");
+ case AddOp : return Instruction::Add;
+ case SubOp : return Instruction::Sub;
+ case MulOp : return Instruction::Mul;
+ case DivOp : {
+ // This is an obsolete instruction so we must upgrade it based on the
+ // types of its operands.
+ bool isFP = Ty->isFloatingPoint();
+ if (const VectorType* PTy = dyn_cast<VectorType>(Ty))
+ // If its a vector type we want to use the element type
+ isFP = PTy->getElementType()->isFloatingPoint();
+ if (isFP)
+ return Instruction::FDiv;
+ else if (Sign.isSigned())
+ return Instruction::SDiv;
+ return Instruction::UDiv;
+ }
+ case UDivOp : return Instruction::UDiv;
+ case SDivOp : return Instruction::SDiv;
+ case FDivOp : return Instruction::FDiv;
+ case RemOp : {
+ // This is an obsolete instruction so we must upgrade it based on the
+ // types of its operands.
+ bool isFP = Ty->isFloatingPoint();
+ if (const VectorType* PTy = dyn_cast<VectorType>(Ty))
+ // If its a vector type we want to use the element type
+ isFP = PTy->getElementType()->isFloatingPoint();
+ // Select correct opcode
+ if (isFP)
+ return Instruction::FRem;
+ else if (Sign.isSigned())
+ return Instruction::SRem;
+ return Instruction::URem;
+ }
+ case URemOp : return Instruction::URem;
+ case SRemOp : return Instruction::SRem;
+ case FRemOp : return Instruction::FRem;
+ case LShrOp : return Instruction::LShr;
+ case AShrOp : return Instruction::AShr;
+ case ShlOp : return Instruction::Shl;
+ case ShrOp :
+ if (Sign.isSigned())
+ return Instruction::AShr;
+ return Instruction::LShr;
+ case AndOp : return Instruction::And;
+ case OrOp : return Instruction::Or;
+ case XorOp : return Instruction::Xor;
+ }
+}
+
+static inline Instruction::OtherOps
+getCompareOp(BinaryOps op, unsigned short &predicate, const Type* &Ty,
+ const Signedness &Sign) {
+ bool isSigned = Sign.isSigned();
+ bool isFP = Ty->isFloatingPoint();
+ switch (op) {
+ default : assert(0 && "Invalid OldSetCC");
+ case SetEQ :
+ if (isFP) {
+ predicate = FCmpInst::FCMP_OEQ;
+ return Instruction::FCmp;
+ } else {
+ predicate = ICmpInst::ICMP_EQ;
+ return Instruction::ICmp;
+ }
+ case SetNE :
+ if (isFP) {
+ predicate = FCmpInst::FCMP_UNE;
+ return Instruction::FCmp;
+ } else {
+ predicate = ICmpInst::ICMP_NE;
+ return Instruction::ICmp;
+ }
+ case SetLE :
+ if (isFP) {
+ predicate = FCmpInst::FCMP_OLE;
+ return Instruction::FCmp;
+ } else {
+ if (isSigned)
+ predicate = ICmpInst::ICMP_SLE;
+ else
+ predicate = ICmpInst::ICMP_ULE;
+ return Instruction::ICmp;
+ }
+ case SetGE :
+ if (isFP) {
+ predicate = FCmpInst::FCMP_OGE;
+ return Instruction::FCmp;
+ } else {
+ if (isSigned)
+ predicate = ICmpInst::ICMP_SGE;
+ else
+ predicate = ICmpInst::ICMP_UGE;
+ return Instruction::ICmp;
+ }
+ case SetLT :
+ if (isFP) {
+ predicate = FCmpInst::FCMP_OLT;
+ return Instruction::FCmp;
+ } else {
+ if (isSigned)
+ predicate = ICmpInst::ICMP_SLT;
+ else
+ predicate = ICmpInst::ICMP_ULT;
+ return Instruction::ICmp;
+ }
+ case SetGT :
+ if (isFP) {
+ predicate = FCmpInst::FCMP_OGT;
+ return Instruction::FCmp;
+ } else {
+ if (isSigned)
+ predicate = ICmpInst::ICMP_SGT;
+ else
+ predicate = ICmpInst::ICMP_UGT;
+ return Instruction::ICmp;
+ }
+ }
+}
+
+static inline Instruction::MemoryOps getMemoryOp(MemoryOps op) {
+ switch (op) {
+ default : assert(0 && "Invalid OldMemoryOps");
+ case MallocOp : return Instruction::Malloc;
+ case FreeOp : return Instruction::Free;
+ case AllocaOp : return Instruction::Alloca;
+ case LoadOp : return Instruction::Load;
+ case StoreOp : return Instruction::Store;
+ case GetElementPtrOp : return Instruction::GetElementPtr;
+ }
+}
+
+static inline Instruction::OtherOps
+getOtherOp(OtherOps op, const Signedness &Sign) {
+ switch (op) {
+ default : assert(0 && "Invalid OldOtherOps");
+ case PHIOp : return Instruction::PHI;
+ case CallOp : return Instruction::Call;
+ case SelectOp : return Instruction::Select;
+ case UserOp1 : return Instruction::UserOp1;
+ case UserOp2 : return Instruction::UserOp2;
+ case VAArg : return Instruction::VAArg;
+ case ExtractElementOp : return Instruction::ExtractElement;
+ case InsertElementOp : return Instruction::InsertElement;
+ case ShuffleVectorOp : return Instruction::ShuffleVector;
+ case ICmpOp : return Instruction::ICmp;
+ case FCmpOp : return Instruction::FCmp;
+ };
+}
+
+static inline Value*
+getCast(CastOps op, Value *Src, const Signedness &SrcSign, const Type *DstTy,
+ const Signedness &DstSign, bool ForceInstruction = false) {
+ Instruction::CastOps Opcode;
+ const Type* SrcTy = Src->getType();
+ if (op == CastOp) {
+ if (SrcTy->isFloatingPoint() && isa<PointerType>(DstTy)) {
+ // fp -> ptr cast is no longer supported but we must upgrade this
+ // by doing a double cast: fp -> int -> ptr
+ SrcTy = Type::Int64Ty;
+ Opcode = Instruction::IntToPtr;
+ if (isa<Constant>(Src)) {
+ Src = ConstantExpr::getCast(Instruction::FPToUI,
+ cast<Constant>(Src), SrcTy);
+ } else {
+ std::string NewName(makeNameUnique(Src->getName()));
+ Src = new FPToUIInst(Src, SrcTy, NewName, CurBB);
+ }
+ } else if (isa<IntegerType>(DstTy) &&
+ cast<IntegerType>(DstTy)->getBitWidth() == 1) {
+ // cast type %x to bool was previously defined as setne type %x, null
+ // The cast semantic is now to truncate, not compare so we must retain
+ // the original intent by replacing the cast with a setne
+ Constant* Null = Constant::getNullValue(SrcTy);
+ Instruction::OtherOps Opcode = Instruction::ICmp;
+ unsigned short predicate = ICmpInst::ICMP_NE;
+ if (SrcTy->isFloatingPoint()) {
+ Opcode = Instruction::FCmp;
+ predicate = FCmpInst::FCMP_ONE;
+ } else if (!SrcTy->isInteger() && !isa<PointerType>(SrcTy)) {
+ error("Invalid cast to bool");
+ }
+ if (isa<Constant>(Src) && !ForceInstruction)
+ return ConstantExpr::getCompare(predicate, cast<Constant>(Src), Null);
+ else
+ return CmpInst::create(Opcode, predicate, Src, Null);
+ }
+ // Determine the opcode to use by calling CastInst::getCastOpcode
+ Opcode =
+ CastInst::getCastOpcode(Src, SrcSign.isSigned(), DstTy,
+ DstSign.isSigned());
+
+ } else switch (op) {
+ default: assert(0 && "Invalid cast token");
+ case TruncOp: Opcode = Instruction::Trunc; break;
+ case ZExtOp: Opcode = Instruction::ZExt; break;
+ case SExtOp: Opcode = Instruction::SExt; break;
+ case FPTruncOp: Opcode = Instruction::FPTrunc; break;
+ case FPExtOp: Opcode = Instruction::FPExt; break;
+ case FPToUIOp: Opcode = Instruction::FPToUI; break;
+ case FPToSIOp: Opcode = Instruction::FPToSI; break;
+ case UIToFPOp: Opcode = Instruction::UIToFP; break;
+ case SIToFPOp: Opcode = Instruction::SIToFP; break;
+ case PtrToIntOp: Opcode = Instruction::PtrToInt; break;
+ case IntToPtrOp: Opcode = Instruction::IntToPtr; break;
+ case BitCastOp: Opcode = Instruction::BitCast; break;
+ }
+
+ if (isa<Constant>(Src) && !ForceInstruction)
+ return ConstantExpr::getCast(Opcode, cast<Constant>(Src), DstTy);
+ return CastInst::create(Opcode, Src, DstTy);
+}
+
+static Instruction *
+upgradeIntrinsicCall(const Type* RetTy, const ValID &ID,
+ std::vector<Value*>& Args) {
+
+ std::string Name = ID.Type == ValID::NameVal ? ID.Name : "";
+ if (Name.length() <= 5 || Name[0] != 'l' || Name[1] != 'l' ||
+ Name[2] != 'v' || Name[3] != 'm' || Name[4] != '.')
+ return 0;
+
+ switch (Name[5]) {
+ case 'i':
+ if (Name == "llvm.isunordered.f32" || Name == "llvm.isunordered.f64") {
+ if (Args.size() != 2)
+ error("Invalid prototype for " + Name);
+ return new FCmpInst(FCmpInst::FCMP_UNO, Args[0], Args[1]);
+ }
+ break;
+ case 'b':
+ if (Name.length() == 14 && !memcmp(&Name[5], "bswap.i", 7)) {
+ const Type* ArgTy = Args[0]->getType();
+ Name += ".i" + utostr(cast<IntegerType>(ArgTy)->getBitWidth());
+ Function *F = cast<Function>(
+ CurModule.CurrentModule->getOrInsertFunction(Name, RetTy, ArgTy,
+ (void*)0));
+ return new CallInst(F, Args[0]);
+ }
+ break;
+ case 'c':
+ if ((Name.length() <= 14 && !memcmp(&Name[5], "ctpop.i", 7)) ||
+ (Name.length() <= 13 && !memcmp(&Name[5], "ctlz.i", 6)) ||
+ (Name.length() <= 13 && !memcmp(&Name[5], "cttz.i", 6))) {
+ // These intrinsics changed their result type.
+ const Type* ArgTy = Args[0]->getType();
+ Function *OldF = CurModule.CurrentModule->getFunction(Name);
+ if (OldF)
+ OldF->setName("upgrd.rm." + Name);
+
+ Function *NewF = cast<Function>(
+ CurModule.CurrentModule->getOrInsertFunction(Name, Type::Int32Ty,
+ ArgTy, (void*)0));
+
+ Instruction *Call = new CallInst(NewF, Args[0], "", CurBB);
+ return CastInst::createIntegerCast(Call, RetTy, false);
+ }
+ break;
+
+ case 'v' : {
+ const Type* PtrTy = PointerType::get(Type::Int8Ty);
+ std::vector<const Type*> Params;
+ if (Name == "llvm.va_start" || Name == "llvm.va_end") {
+ if (Args.size() != 1)
+ error("Invalid prototype for " + Name + " prototype");
+ Params.push_back(PtrTy);
+ const FunctionType *FTy =
+ FunctionType::get(Type::VoidTy, Params, false);
+ const PointerType *PFTy = PointerType::get(FTy);
+ Value* Func = getVal(PFTy, ID);
+ Args[0] = new BitCastInst(Args[0], PtrTy, makeNameUnique("va"), CurBB);
+ return new CallInst(Func, &Args[0], Args.size());
+ } else if (Name == "llvm.va_copy") {
+ if (Args.size() != 2)
+ error("Invalid prototype for " + Name + " prototype");
+ Params.push_back(PtrTy);
+ Params.push_back(PtrTy);
+ const FunctionType *FTy =
+ FunctionType::get(Type::VoidTy, Params, false);
+ const PointerType *PFTy = PointerType::get(FTy);
+ Value* Func = getVal(PFTy, ID);
+ std::string InstName0(makeNameUnique("va0"));
+ std::string InstName1(makeNameUnique("va1"));
+ Args[0] = new BitCastInst(Args[0], PtrTy, InstName0, CurBB);
+ Args[1] = new BitCastInst(Args[1], PtrTy, InstName1, CurBB);
+ return new CallInst(Func, &Args[0], Args.size());
+ }
+ }
+ }
+ return 0;
+}
+
+const Type* upgradeGEPCEIndices(const Type* PTy,
+ std::vector<ValueInfo> *Indices,
+ std::vector<Constant*> &Result) {
+ const Type *Ty = PTy;
+ Result.clear();
+ for (unsigned i = 0, e = Indices->size(); i != e ; ++i) {
+ Constant *Index = cast<Constant>((*Indices)[i].V);
+
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(Index)) {
+ // LLVM 1.2 and earlier used ubyte struct indices. Convert any ubyte
+ // struct indices to i32 struct indices with ZExt for compatibility.
+ if (CI->getBitWidth() < 32)
+ Index = ConstantExpr::getCast(Instruction::ZExt, CI, Type::Int32Ty);
+ }
+
+ if (isa<SequentialType>(Ty)) {
+ // Make sure that unsigned SequentialType indices are zext'd to
+ // 64-bits if they were smaller than that because LLVM 2.0 will sext
+ // all indices for SequentialType elements. We must retain the same
+ // semantic (zext) for unsigned types.
+ if (const IntegerType *Ity = dyn_cast<IntegerType>(Index->getType())) {
+ if (Ity->getBitWidth() < 64 && (*Indices)[i].S.isUnsigned()) {
+ Index = ConstantExpr::getCast(Instruction::ZExt, Index,Type::Int64Ty);
+ }
+ }
+ }
+ Result.push_back(Index);
+ Ty = GetElementPtrInst::getIndexedType(PTy, (Value**)&Result[0],
+ Result.size(),true);
+ if (!Ty)
+ error("Index list invalid for constant getelementptr");
+ }
+ return Ty;
+}
+
+const Type* upgradeGEPInstIndices(const Type* PTy,
+ std::vector<ValueInfo> *Indices,
+ std::vector<Value*> &Result) {
+ const Type *Ty = PTy;
+ Result.clear();
+ for (unsigned i = 0, e = Indices->size(); i != e ; ++i) {
+ Value *Index = (*Indices)[i].V;
+
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(Index)) {
+ // LLVM 1.2 and earlier used ubyte struct indices. Convert any ubyte
+ // struct indices to i32 struct indices with ZExt for compatibility.
+ if (CI->getBitWidth() < 32)
+ Index = ConstantExpr::getCast(Instruction::ZExt, CI, Type::Int32Ty);
+ }
+
+
+ if (isa<StructType>(Ty)) { // Only change struct indices
+ if (!isa<Constant>(Index)) {
+ error("Invalid non-constant structure index");
+ return 0;
+ }
+ } else {
+ // Make sure that unsigned SequentialType indices are zext'd to
+ // 64-bits if they were smaller than that because LLVM 2.0 will sext
+ // all indices for SequentialType elements. We must retain the same
+ // semantic (zext) for unsigned types.
+ if (const IntegerType *Ity = dyn_cast<IntegerType>(Index->getType())) {
+ if (Ity->getBitWidth() < 64 && (*Indices)[i].S.isUnsigned()) {
+ if (isa<Constant>(Index))
+ Index = ConstantExpr::getCast(Instruction::ZExt,
+ cast<Constant>(Index), Type::Int64Ty);
+ else
+ Index = CastInst::create(Instruction::ZExt, Index, Type::Int64Ty,
+ makeNameUnique("gep"), CurBB);
+ }
+ }
+ }
+ Result.push_back(Index);
+ Ty = GetElementPtrInst::getIndexedType(PTy, &Result[0], Result.size(),true);
+ if (!Ty)
+ error("Index list invalid for constant getelementptr");
+ }
+ return Ty;
+}
+
+unsigned upgradeCallingConv(unsigned CC) {
+ switch (CC) {
+ case OldCallingConv::C : return CallingConv::C;
+ case OldCallingConv::CSRet : return CallingConv::C;
+ case OldCallingConv::Fast : return CallingConv::Fast;
+ case OldCallingConv::Cold : return CallingConv::Cold;
+ case OldCallingConv::X86_StdCall : return CallingConv::X86_StdCall;
+ case OldCallingConv::X86_FastCall: return CallingConv::X86_FastCall;
+ default:
+ return CC;
+ }
+}
+
+Module* UpgradeAssembly(const std::string &infile, std::istream& in,
+ bool debug, bool addAttrs)
+{
+ Upgradelineno = 1;
+ CurFilename = infile;
+ LexInput = &in;
+ yydebug = debug;
+ AddAttributes = addAttrs;
+ ObsoleteVarArgs = false;
+ NewVarArgs = false;
+
+ CurModule.CurrentModule = new Module(CurFilename);
+
+ // Check to make sure the parser succeeded
+ if (yyparse()) {
+ if (ParserResult)
+ delete ParserResult;
+ std::cerr << "llvm-upgrade: parse failed.\n";
+ return 0;
+ }
+
+ // Check to make sure that parsing produced a result
+ if (!ParserResult) {
+ std::cerr << "llvm-upgrade: no parse result.\n";
+ return 0;
+ }
+
+ // Reset ParserResult variable while saving its value for the result.
+ Module *Result = ParserResult;
+ ParserResult = 0;
+
+ //Not all functions use vaarg, so make a second check for ObsoleteVarArgs
+ {
+ Function* F;
+ if ((F = Result->getFunction("llvm.va_start"))
+ && F->getFunctionType()->getNumParams() == 0)
+ ObsoleteVarArgs = true;
+ if((F = Result->getFunction("llvm.va_copy"))
+ && F->getFunctionType()->getNumParams() == 1)
+ ObsoleteVarArgs = true;
+ }
+
+ if (ObsoleteVarArgs && NewVarArgs) {
+ error("This file is corrupt: it uses both new and old style varargs");
+ return 0;
+ }
+
+ if(ObsoleteVarArgs) {
+ if(Function* F = Result->getFunction("llvm.va_start")) {
+ if (F->arg_size() != 0) {
+ error("Obsolete va_start takes 0 argument");
+ return 0;
+ }
+
+ //foo = va_start()
+ // ->
+ //bar = alloca typeof(foo)
+ //va_start(bar)
+ //foo = load bar
+
+ const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID);
+ const Type* ArgTy = F->getFunctionType()->getReturnType();
+ const Type* ArgTyPtr = PointerType::get(ArgTy);
+ Function* NF = cast<Function>(Result->getOrInsertFunction(
+ "llvm.va_start", RetTy, ArgTyPtr, (Type *)0));
+
+ while (!F->use_empty()) {
+ CallInst* CI = cast<CallInst>(F->use_back());
+ AllocaInst* bar = new AllocaInst(ArgTy, 0, "vastart.fix.1", CI);
+ new CallInst(NF, bar, "", CI);
+ Value* foo = new LoadInst(bar, "vastart.fix.2", CI);
+ CI->replaceAllUsesWith(foo);
+ CI->getParent()->getInstList().erase(CI);
+ }
+ Result->getFunctionList().erase(F);
+ }
+
+ if(Function* F = Result->getFunction("llvm.va_end")) {
+ if(F->arg_size() != 1) {
+ error("Obsolete va_end takes 1 argument");
+ return 0;
+ }
+
+ //vaend foo
+ // ->
+ //bar = alloca 1 of typeof(foo)
+ //vaend bar
+ const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID);
+ const Type* ArgTy = F->getFunctionType()->getParamType(0);
+ const Type* ArgTyPtr = PointerType::get(ArgTy);
+ Function* NF = cast<Function>(Result->getOrInsertFunction(
+ "llvm.va_end", RetTy, ArgTyPtr, (Type *)0));
+
+ while (!F->use_empty()) {
+ CallInst* CI = cast<CallInst>(F->use_back());
+ AllocaInst* bar = new AllocaInst(ArgTy, 0, "vaend.fix.1", CI);
+ new StoreInst(CI->getOperand(1), bar, CI);
+ new CallInst(NF, bar, "", CI);
+ CI->getParent()->getInstList().erase(CI);
+ }
+ Result->getFunctionList().erase(F);
+ }
+
+ if(Function* F = Result->getFunction("llvm.va_copy")) {
+ if(F->arg_size() != 1) {
+ error("Obsolete va_copy takes 1 argument");
+ return 0;
+ }
+ //foo = vacopy(bar)
+ // ->
+ //a = alloca 1 of typeof(foo)
+ //b = alloca 1 of typeof(foo)
+ //store bar -> b
+ //vacopy(a, b)
+ //foo = load a
+
+ const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID);
+ const Type* ArgTy = F->getFunctionType()->getReturnType();
+ const Type* ArgTyPtr = PointerType::get(ArgTy);
+ Function* NF = cast<Function>(Result->getOrInsertFunction(
+ "llvm.va_copy", RetTy, ArgTyPtr, ArgTyPtr, (Type *)0));
+
+ while (!F->use_empty()) {
+ CallInst* CI = cast<CallInst>(F->use_back());
+ AllocaInst* a = new AllocaInst(ArgTy, 0, "vacopy.fix.1", CI);
+ AllocaInst* b = new AllocaInst(ArgTy, 0, "vacopy.fix.2", CI);
+ new StoreInst(CI->getOperand(1), b, CI);
+ new CallInst(NF, a, b, "", CI);
+ Value* foo = new LoadInst(a, "vacopy.fix.3", CI);
+ CI->replaceAllUsesWith(foo);
+ CI->getParent()->getInstList().erase(CI);
+ }
+ Result->getFunctionList().erase(F);
+ }
+ }
+
+ return Result;
+}
+
+} // end llvm namespace
+
+using namespace llvm;
+
+%}
+
+%union {
+ llvm::Module *ModuleVal;
+ llvm::Function *FunctionVal;
+ std::pair<llvm::PATypeInfo, char*> *ArgVal;
+ llvm::BasicBlock *BasicBlockVal;
+ llvm::TermInstInfo TermInstVal;
+ llvm::InstrInfo InstVal;
+ llvm::ConstInfo ConstVal;
+ llvm::ValueInfo ValueVal;
+ llvm::PATypeInfo TypeVal;
+ llvm::TypeInfo PrimType;
+ llvm::PHIListInfo PHIList;
+ std::list<llvm::PATypeInfo> *TypeList;
+ std::vector<llvm::ValueInfo> *ValueList;
+ std::vector<llvm::ConstInfo> *ConstVector;
+
+
+ std::vector<std::pair<llvm::PATypeInfo,char*> > *ArgList;
+ // Represent the RHS of PHI node
+ std::vector<std::pair<llvm::Constant*, llvm::BasicBlock*> > *JumpTable;
+
+ llvm::GlobalValue::LinkageTypes Linkage;
+ int64_t SInt64Val;
+ uint64_t UInt64Val;
+ int SIntVal;
+ unsigned UIntVal;
+ double FPVal;
+ bool BoolVal;
+
+ char *StrVal; // This memory is strdup'd!
+ llvm::ValID ValIDVal; // strdup'd memory maybe!
+
+ llvm::BinaryOps BinaryOpVal;
+ llvm::TermOps TermOpVal;
+ llvm::MemoryOps MemOpVal;
+ llvm::OtherOps OtherOpVal;
+ llvm::CastOps CastOpVal;
+ llvm::ICmpInst::Predicate IPred;
+ llvm::FCmpInst::Predicate FPred;
+ llvm::Module::Endianness Endianness;
+}
+
+%type <ModuleVal> Module FunctionList
+%type <FunctionVal> Function FunctionProto FunctionHeader BasicBlockList
+%type <BasicBlockVal> BasicBlock InstructionList
+%type <TermInstVal> BBTerminatorInst
+%type <InstVal> Inst InstVal MemoryInst
+%type <ConstVal> ConstVal ConstExpr
+%type <ConstVector> ConstVector
+%type <ArgList> ArgList ArgListH
+%type <ArgVal> ArgVal
+%type <PHIList> PHIList
+%type <ValueList> ValueRefList ValueRefListE // For call param lists
+%type <ValueList> IndexList // For GEP derived indices
+%type <TypeList> TypeListI ArgTypeListI
+%type <JumpTable> JumpTable
+%type <BoolVal> GlobalType // GLOBAL or CONSTANT?
+%type <BoolVal> OptVolatile // 'volatile' or not
+%type <BoolVal> OptTailCall // TAIL CALL or plain CALL.
+%type <BoolVal> OptSideEffect // 'sideeffect' or not.
+%type <Linkage> OptLinkage FnDeclareLinkage
+%type <Endianness> BigOrLittle
+
+// ValueRef - Unresolved reference to a definition or BB
+%type <ValIDVal> ValueRef ConstValueRef SymbolicValueRef
+%type <ValueVal> ResolvedVal // <type> <valref> pair
+
+// Tokens and types for handling constant integer values
+//
+// ESINT64VAL - A negative number within long long range
+%token <SInt64Val> ESINT64VAL
+
+// EUINT64VAL - A positive number within uns. long long range
+%token <UInt64Val> EUINT64VAL
+%type <SInt64Val> EINT64VAL
+
+%token <SIntVal> SINTVAL // Signed 32 bit ints...
+%token <UIntVal> UINTVAL // Unsigned 32 bit ints...
+%type <SIntVal> INTVAL
+%token <FPVal> FPVAL // Float or Double constant
+
+// Built in types...
+%type <TypeVal> Types TypesV UpRTypes UpRTypesV
+%type <PrimType> SIntType UIntType IntType FPType PrimType // Classifications
+%token <PrimType> VOID BOOL SBYTE UBYTE SHORT USHORT INT UINT LONG ULONG
+%token <PrimType> FLOAT DOUBLE TYPE LABEL
+
+%token <StrVal> VAR_ID LABELSTR STRINGCONSTANT
+%type <StrVal> Name OptName OptAssign
+%type <UIntVal> OptAlign OptCAlign
+%type <StrVal> OptSection SectionString
+
+%token IMPLEMENTATION ZEROINITIALIZER TRUETOK FALSETOK BEGINTOK ENDTOK
+%token DECLARE GLOBAL CONSTANT SECTION VOLATILE
+%token TO DOTDOTDOT NULL_TOK UNDEF CONST INTERNAL LINKONCE WEAK APPENDING
+%token DLLIMPORT DLLEXPORT EXTERN_WEAK
+%token OPAQUE NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG ALIGN
+%token DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT
+%token CC_TOK CCC_TOK CSRETCC_TOK FASTCC_TOK COLDCC_TOK
+%token X86_STDCALLCC_TOK X86_FASTCALLCC_TOK
+%token DATALAYOUT
+%type <UIntVal> OptCallingConv
+
+// Basic Block Terminating Operators
+%token <TermOpVal> RET BR SWITCH INVOKE UNREACHABLE
+%token UNWIND EXCEPT
+
+// Binary Operators
+%type <BinaryOpVal> ArithmeticOps LogicalOps SetCondOps // Binops Subcatagories
+%type <BinaryOpVal> ShiftOps
+%token <BinaryOpVal> ADD SUB MUL DIV UDIV SDIV FDIV REM UREM SREM FREM
+%token <BinaryOpVal> AND OR XOR SHL SHR ASHR LSHR
+%token <BinaryOpVal> SETLE SETGE SETLT SETGT SETEQ SETNE // Binary Comparators
+%token <OtherOpVal> ICMP FCMP
+
+// Memory Instructions
+%token <MemOpVal> MALLOC ALLOCA FREE LOAD STORE GETELEMENTPTR
+
+// Other Operators
+%token <OtherOpVal> PHI_TOK SELECT VAARG
+%token <OtherOpVal> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR
+%token VAARG_old VANEXT_old //OBSOLETE
+
+// Support for ICmp/FCmp Predicates, which is 1.9++ but not 2.0
+%type <IPred> IPredicates
+%type <FPred> FPredicates
+%token EQ NE SLT SGT SLE SGE ULT UGT ULE UGE
+%token OEQ ONE OLT OGT OLE OGE ORD UNO UEQ UNE
+
+%token <CastOpVal> CAST TRUNC ZEXT SEXT FPTRUNC FPEXT FPTOUI FPTOSI
+%token <CastOpVal> UITOFP SITOFP PTRTOINT INTTOPTR BITCAST
+%type <CastOpVal> CastOps
+
+%start Module
+
+%%
+
+// Handle constant integer size restriction and conversion...
+//
+INTVAL
+ : SINTVAL
+ | UINTVAL {
+ if ($1 > (uint32_t)INT32_MAX) // Outside of my range!
+ error("Value too large for type");
+ $$ = (int32_t)$1;
+ }
+ ;
+
+EINT64VAL
+ : ESINT64VAL // These have same type and can't cause problems...
+ | EUINT64VAL {
+ if ($1 > (uint64_t)INT64_MAX) // Outside of my range!
+ error("Value too large for type");
+ $$ = (int64_t)$1;
+ };
+
+// Operations that are notably excluded from this list include:
+// RET, BR, & SWITCH because they end basic blocks and are treated specially.
+//
+ArithmeticOps
+ : ADD | SUB | MUL | DIV | UDIV | SDIV | FDIV | REM | UREM | SREM | FREM
+ ;
+
+LogicalOps
+ : AND | OR | XOR
+ ;
+
+SetCondOps
+ : SETLE | SETGE | SETLT | SETGT | SETEQ | SETNE
+ ;
+
+IPredicates
+ : EQ { $$ = ICmpInst::ICMP_EQ; } | NE { $$ = ICmpInst::ICMP_NE; }
+ | SLT { $$ = ICmpInst::ICMP_SLT; } | SGT { $$ = ICmpInst::ICMP_SGT; }
+ | SLE { $$ = ICmpInst::ICMP_SLE; } | SGE { $$ = ICmpInst::ICMP_SGE; }
+ | ULT { $$ = ICmpInst::ICMP_ULT; } | UGT { $$ = ICmpInst::ICMP_UGT; }
+ | ULE { $$ = ICmpInst::ICMP_ULE; } | UGE { $$ = ICmpInst::ICMP_UGE; }
+ ;
+
+FPredicates
+ : OEQ { $$ = FCmpInst::FCMP_OEQ; } | ONE { $$ = FCmpInst::FCMP_ONE; }
+ | OLT { $$ = FCmpInst::FCMP_OLT; } | OGT { $$ = FCmpInst::FCMP_OGT; }
+ | OLE { $$ = FCmpInst::FCMP_OLE; } | OGE { $$ = FCmpInst::FCMP_OGE; }
+ | ORD { $$ = FCmpInst::FCMP_ORD; } | UNO { $$ = FCmpInst::FCMP_UNO; }
+ | UEQ { $$ = FCmpInst::FCMP_UEQ; } | UNE { $$ = FCmpInst::FCMP_UNE; }
+ | ULT { $$ = FCmpInst::FCMP_ULT; } | UGT { $$ = FCmpInst::FCMP_UGT; }
+ | ULE { $$ = FCmpInst::FCMP_ULE; } | UGE { $$ = FCmpInst::FCMP_UGE; }
+ | TRUETOK { $$ = FCmpInst::FCMP_TRUE; }
+ | FALSETOK { $$ = FCmpInst::FCMP_FALSE; }
+ ;
+ShiftOps
+ : SHL | SHR | ASHR | LSHR
+ ;
+
+CastOps
+ : TRUNC | ZEXT | SEXT | FPTRUNC | FPEXT | FPTOUI | FPTOSI
+ | UITOFP | SITOFP | PTRTOINT | INTTOPTR | BITCAST | CAST
+ ;
+
+// These are some types that allow classification if we only want a particular
+// thing... for example, only a signed, unsigned, or integral type.
+SIntType
+ : LONG | INT | SHORT | SBYTE
+ ;
+
+UIntType
+ : ULONG | UINT | USHORT | UBYTE
+ ;
+
+IntType
+ : SIntType | UIntType
+ ;
+
+FPType
+ : FLOAT | DOUBLE
+ ;
+
+// OptAssign - Value producing statements have an optional assignment component
+OptAssign
+ : Name '=' {
+ $$ = $1;
+ }
+ | /*empty*/ {
+ $$ = 0;
+ };
+
+OptLinkage
+ : INTERNAL { $$ = GlobalValue::InternalLinkage; }
+ | LINKONCE { $$ = GlobalValue::LinkOnceLinkage; }
+ | WEAK { $$ = GlobalValue::WeakLinkage; }
+ | APPENDING { $$ = GlobalValue::AppendingLinkage; }
+ | DLLIMPORT { $$ = GlobalValue::DLLImportLinkage; }
+ | DLLEXPORT { $$ = GlobalValue::DLLExportLinkage; }
+ | EXTERN_WEAK { $$ = GlobalValue::ExternalWeakLinkage; }
+ | /*empty*/ { $$ = GlobalValue::ExternalLinkage; }
+ ;
+
+OptCallingConv
+ : /*empty*/ { $$ = lastCallingConv = OldCallingConv::C; }
+ | CCC_TOK { $$ = lastCallingConv = OldCallingConv::C; }
+ | CSRETCC_TOK { $$ = lastCallingConv = OldCallingConv::CSRet; }
+ | FASTCC_TOK { $$ = lastCallingConv = OldCallingConv::Fast; }
+ | COLDCC_TOK { $$ = lastCallingConv = OldCallingConv::Cold; }
+ | X86_STDCALLCC_TOK { $$ = lastCallingConv = OldCallingConv::X86_StdCall; }
+ | X86_FASTCALLCC_TOK { $$ = lastCallingConv = OldCallingConv::X86_FastCall; }
+ | CC_TOK EUINT64VAL {
+ if ((unsigned)$2 != $2)
+ error("Calling conv too large");
+ $$ = lastCallingConv = $2;
+ }
+ ;
+
+// OptAlign/OptCAlign - An optional alignment, and an optional alignment with
+// a comma before it.
+OptAlign
+ : /*empty*/ { $$ = 0; }
+ | ALIGN EUINT64VAL {
+ $$ = $2;
+ if ($$ != 0 && !isPowerOf2_32($$))
+ error("Alignment must be a power of two");
+ }
+ ;
+
+OptCAlign
+ : /*empty*/ { $$ = 0; }
+ | ',' ALIGN EUINT64VAL {
+ $$ = $3;
+ if ($$ != 0 && !isPowerOf2_32($$))
+ error("Alignment must be a power of two");
+ }
+ ;
+
+SectionString
+ : SECTION STRINGCONSTANT {
+ for (unsigned i = 0, e = strlen($2); i != e; ++i)
+ if ($2[i] == '"' || $2[i] == '\\')
+ error("Invalid character in section name");
+ $$ = $2;
+ }
+ ;
+
+OptSection
+ : /*empty*/ { $$ = 0; }
+ | SectionString { $$ = $1; }
+ ;
+
+// GlobalVarAttributes - Used to pass the attributes string on a global. CurGV
+// is set to be the global we are processing.
+//
+GlobalVarAttributes
+ : /* empty */ {}
+ | ',' GlobalVarAttribute GlobalVarAttributes {}
+ ;
+
+GlobalVarAttribute
+ : SectionString {
+ CurGV->setSection($1);
+ free($1);
+ }
+ | ALIGN EUINT64VAL {
+ if ($2 != 0 && !isPowerOf2_32($2))
+ error("Alignment must be a power of two");
+ CurGV->setAlignment($2);
+
+ }
+ ;
+
+//===----------------------------------------------------------------------===//
+// Types includes all predefined types... except void, because it can only be
+// used in specific contexts (function returning void for example). To have
+// access to it, a user must explicitly use TypesV.
+//
+
+// TypesV includes all of 'Types', but it also includes the void type.
+TypesV
+ : Types
+ | VOID {
+ $$.PAT = new PATypeHolder($1.T);
+ $$.S.makeSignless();
+ }
+ ;
+
+UpRTypesV
+ : UpRTypes
+ | VOID {
+ $$.PAT = new PATypeHolder($1.T);
+ $$.S.makeSignless();
+ }
+ ;
+
+Types
+ : UpRTypes {
+ if (!UpRefs.empty())
+ error("Invalid upreference in type: " + (*$1.PAT)->getDescription());
+ $$ = $1;
+ }
+ ;
+
+PrimType
+ : BOOL | SBYTE | UBYTE | SHORT | USHORT | INT | UINT
+ | LONG | ULONG | FLOAT | DOUBLE | LABEL
+ ;
+
+// Derived types are added later...
+UpRTypes
+ : PrimType {
+ $$.PAT = new PATypeHolder($1.T);
+ $$.S.copy($1.S);
+ }
+ | OPAQUE {
+ $$.PAT = new PATypeHolder(OpaqueType::get());
+ $$.S.makeSignless();
+ }
+ | SymbolicValueRef { // Named types are also simple types...
+ $$.S.copy(getTypeSign($1));
+ const Type* tmp = getType($1);
+ $$.PAT = new PATypeHolder(tmp);
+ }
+ | '\\' EUINT64VAL { // Type UpReference
+ if ($2 > (uint64_t)~0U)
+ error("Value out of range");
+ OpaqueType *OT = OpaqueType::get(); // Use temporary placeholder
+ UpRefs.push_back(UpRefRecord((unsigned)$2, OT)); // Add to vector...
+ $$.PAT = new PATypeHolder(OT);
+ $$.S.makeSignless();
+ UR_OUT("New Upreference!\n");
+ }
+ | UpRTypesV '(' ArgTypeListI ')' { // Function derived type?
+ $$.S.makeComposite($1.S);
+ std::vector<const Type*> Params;
+ for (std::list<llvm::PATypeInfo>::iterator I = $3->begin(),
+ E = $3->end(); I != E; ++I) {
+ Params.push_back(I->PAT->get());
+ $$.S.add(I->S);
+ }
+ bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
+ if (isVarArg) Params.pop_back();
+
+ ParamAttrsList *PAL = 0;
+ if (lastCallingConv == OldCallingConv::CSRet) {
+ ParamAttrsVector Attrs;
+ ParamAttrsWithIndex PAWI;
+ PAWI.index = 1; PAWI.attrs = ParamAttr::StructRet; // first arg
+ Attrs.push_back(PAWI);
+ PAL = ParamAttrsList::get(Attrs);
+ }
+
+ const FunctionType *FTy =
+ FunctionType::get($1.PAT->get(), Params, isVarArg, PAL);
+
+ $$.PAT = new PATypeHolder( HandleUpRefs(FTy, $$.S) );
+ delete $1.PAT; // Delete the return type handle
+ delete $3; // Delete the argument list
+ }
+ | '[' EUINT64VAL 'x' UpRTypes ']' { // Sized array type?
+ $$.S.makeComposite($4.S);
+ $$.PAT = new PATypeHolder(HandleUpRefs(ArrayType::get($4.PAT->get(),
+ (unsigned)$2), $$.S));
+ delete $4.PAT;
+ }
+ | '<' EUINT64VAL 'x' UpRTypes '>' { // Vector type?
+ const llvm::Type* ElemTy = $4.PAT->get();
+ if ((unsigned)$2 != $2)
+ error("Unsigned result not equal to signed result");
+ if (!(ElemTy->isInteger() || ElemTy->isFloatingPoint()))
+ error("Elements of a VectorType must be integer or floating point");
+ if (!isPowerOf2_32($2))
+ error("VectorType length should be a power of 2");
+ $$.S.makeComposite($4.S);
+ $$.PAT = new PATypeHolder(HandleUpRefs(VectorType::get(ElemTy,
+ (unsigned)$2), $$.S));
+ delete $4.PAT;
+ }
+ | '{' TypeListI '}' { // Structure type?
+ std::vector<const Type*> Elements;
+ $$.S.makeComposite();
+ for (std::list<llvm::PATypeInfo>::iterator I = $2->begin(),
+ E = $2->end(); I != E; ++I) {
+ Elements.push_back(I->PAT->get());
+ $$.S.add(I->S);
+ }
+ $$.PAT = new PATypeHolder(HandleUpRefs(StructType::get(Elements), $$.S));
+ delete $2;
+ }
+ | '{' '}' { // Empty structure type?
+ $$.PAT = new PATypeHolder(StructType::get(std::vector<const Type*>()));
+ $$.S.makeComposite();
+ }
+ | '<' '{' TypeListI '}' '>' { // Packed Structure type?
+ $$.S.makeComposite();
+ std::vector<const Type*> Elements;
+ for (std::list<llvm::PATypeInfo>::iterator I = $3->begin(),
+ E = $3->end(); I != E; ++I) {
+ Elements.push_back(I->PAT->get());
+ $$.S.add(I->S);
+ delete I->PAT;
+ }
+ $$.PAT = new PATypeHolder(HandleUpRefs(StructType::get(Elements, true),
+ $$.S));
+ delete $3;
+ }
+ | '<' '{' '}' '>' { // Empty packed structure type?
+ $$.PAT = new PATypeHolder(StructType::get(std::vector<const Type*>(),true));
+ $$.S.makeComposite();
+ }
+ | UpRTypes '*' { // Pointer type?
+ if ($1.PAT->get() == Type::LabelTy)
+ error("Cannot form a pointer to a basic block");
+ $$.S.makeComposite($1.S);
+ $$.PAT = new PATypeHolder(HandleUpRefs(PointerType::get($1.PAT->get()),
+ $$.S));
+ delete $1.PAT;
+ }
+ ;
+
+// TypeList - Used for struct declarations and as a basis for function type
+// declaration type lists
+//
+TypeListI
+ : UpRTypes {
+ $$ = new std::list<PATypeInfo>();
+ $$->push_back($1);
+ }
+ | TypeListI ',' UpRTypes {
+ ($$=$1)->push_back($3);
+ }
+ ;
+
+// ArgTypeList - List of types for a function type declaration...
+ArgTypeListI
+ : TypeListI
+ | TypeListI ',' DOTDOTDOT {
+ PATypeInfo VoidTI;
+ VoidTI.PAT = new PATypeHolder(Type::VoidTy);
+ VoidTI.S.makeSignless();
+ ($$=$1)->push_back(VoidTI);
+ }
+ | DOTDOTDOT {
+ $$ = new std::list<PATypeInfo>();
+ PATypeInfo VoidTI;
+ VoidTI.PAT = new PATypeHolder(Type::VoidTy);
+ VoidTI.S.makeSignless();
+ $$->push_back(VoidTI);
+ }
+ | /*empty*/ {
+ $$ = new std::list<PATypeInfo>();
+ }
+ ;
+
+// ConstVal - The various declarations that go into the constant pool. This
+// production is used ONLY to represent constants that show up AFTER a 'const',
+// 'constant' or 'global' token at global scope. Constants that can be inlined
+// into other expressions (such as integers and constexprs) are handled by the
+// ResolvedVal, ValueRef and ConstValueRef productions.
+//
+ConstVal
+ : Types '[' ConstVector ']' { // Nonempty unsized arr
+ const ArrayType *ATy = dyn_cast<ArrayType>($1.PAT->get());
+ if (ATy == 0)
+ error("Cannot make array constant with type: '" +
+ $1.PAT->get()->getDescription() + "'");
+ const Type *ETy = ATy->getElementType();
+ int NumElements = ATy->getNumElements();
+
+ // Verify that we have the correct size...
+ if (NumElements != -1 && NumElements != (int)$3->size())
+ error("Type mismatch: constant sized array initialized with " +
+ utostr($3->size()) + " arguments, but has size of " +
+ itostr(NumElements) + "");
+
+ // Verify all elements are correct type!
+ std::vector<Constant*> Elems;
+ for (unsigned i = 0; i < $3->size(); i++) {
+ Constant *C = (*$3)[i].C;
+ const Type* ValTy = C->getType();
+ if (ETy != ValTy)
+ error("Element #" + utostr(i) + " is not of type '" +
+ ETy->getDescription() +"' as required!\nIt is of type '"+
+ ValTy->getDescription() + "'");
+ Elems.push_back(C);
+ }
+ $$.C = ConstantArray::get(ATy, Elems);
+ $$.S.copy($1.S);
+ delete $1.PAT;
+ delete $3;
+ }
+ | Types '[' ']' {
+ const ArrayType *ATy = dyn_cast<ArrayType>($1.PAT->get());
+ if (ATy == 0)
+ error("Cannot make array constant with type: '" +
+ $1.PAT->get()->getDescription() + "'");
+ int NumElements = ATy->getNumElements();
+ if (NumElements != -1 && NumElements != 0)
+ error("Type mismatch: constant sized array initialized with 0"
+ " arguments, but has size of " + itostr(NumElements) +"");
+ $$.C = ConstantArray::get(ATy, std::vector<Constant*>());
+ $$.S.copy($1.S);
+ delete $1.PAT;
+ }
+ | Types 'c' STRINGCONSTANT {
+ const ArrayType *ATy = dyn_cast<ArrayType>($1.PAT->get());
+ if (ATy == 0)
+ error("Cannot make array constant with type: '" +
+ $1.PAT->get()->getDescription() + "'");
+ int NumElements = ATy->getNumElements();
+ const Type *ETy = dyn_cast<IntegerType>(ATy->getElementType());
+ if (!ETy || cast<IntegerType>(ETy)->getBitWidth() != 8)
+ error("String arrays require type i8, not '" + ETy->getDescription() +
+ "'");
+ char *EndStr = UnEscapeLexed($3, true);
+ if (NumElements != -1 && NumElements != (EndStr-$3))
+ error("Can't build string constant of size " +
+ itostr((int)(EndStr-$3)) + " when array has size " +
+ itostr(NumElements) + "");
+ std::vector<Constant*> Vals;
+ for (char *C = (char *)$3; C != (char *)EndStr; ++C)
+ Vals.push_back(ConstantInt::get(ETy, *C));
+ free($3);
+ $$.C = ConstantArray::get(ATy, Vals);
+ $$.S.copy($1.S);
+ delete $1.PAT;
+ }
+ | Types '<' ConstVector '>' { // Nonempty unsized arr
+ const VectorType *PTy = dyn_cast<VectorType>($1.PAT->get());
+ if (PTy == 0)
+ error("Cannot make packed constant with type: '" +
+ $1.PAT->get()->getDescription() + "'");
+ const Type *ETy = PTy->getElementType();
+ int NumElements = PTy->getNumElements();
+ // Verify that we have the correct size...
+ if (NumElements != -1 && NumElements != (int)$3->size())
+ error("Type mismatch: constant sized packed initialized with " +
+ utostr($3->size()) + " arguments, but has size of " +
+ itostr(NumElements) + "");
+ // Verify all elements are correct type!
+ std::vector<Constant*> Elems;
+ for (unsigned i = 0; i < $3->size(); i++) {
+ Constant *C = (*$3)[i].C;
+ const Type* ValTy = C->getType();
+ if (ETy != ValTy)
+ error("Element #" + utostr(i) + " is not of type '" +
+ ETy->getDescription() +"' as required!\nIt is of type '"+
+ ValTy->getDescription() + "'");
+ Elems.push_back(C);
+ }
+ $$.C = ConstantVector::get(PTy, Elems);
+ $$.S.copy($1.S);
+ delete $1.PAT;
+ delete $3;
+ }
+ | Types '{' ConstVector '}' {
+ const StructType *STy = dyn_cast<StructType>($1.PAT->get());
+ if (STy == 0)
+ error("Cannot make struct constant with type: '" +
+ $1.PAT->get()->getDescription() + "'");
+ if ($3->size() != STy->getNumContainedTypes())
+ error("Illegal number of initializers for structure type");
+
+ // Check to ensure that constants are compatible with the type initializer!
+ std::vector<Constant*> Fields;
+ for (unsigned i = 0, e = $3->size(); i != e; ++i) {
+ Constant *C = (*$3)[i].C;
+ if (C->getType() != STy->getElementType(i))
+ error("Expected type '" + STy->getElementType(i)->getDescription() +
+ "' for element #" + utostr(i) + " of structure initializer");
+ Fields.push_back(C);
+ }
+ $$.C = ConstantStruct::get(STy, Fields);
+ $$.S.copy($1.S);
+ delete $1.PAT;
+ delete $3;
+ }
+ | Types '{' '}' {
+ const StructType *STy = dyn_cast<StructType>($1.PAT->get());
+ if (STy == 0)
+ error("Cannot make struct constant with type: '" +
+ $1.PAT->get()->getDescription() + "'");
+ if (STy->getNumContainedTypes() != 0)
+ error("Illegal number of initializers for structure type");
+ $$.C = ConstantStruct::get(STy, std::vector<Constant*>());
+ $$.S.copy($1.S);
+ delete $1.PAT;
+ }
+ | Types '<' '{' ConstVector '}' '>' {
+ const StructType *STy = dyn_cast<StructType>($1.PAT->get());
+ if (STy == 0)
+ error("Cannot make packed struct constant with type: '" +
+ $1.PAT->get()->getDescription() + "'");
+ if ($4->size() != STy->getNumContainedTypes())
+ error("Illegal number of initializers for packed structure type");
+
+ // Check to ensure that constants are compatible with the type initializer!
+ std::vector<Constant*> Fields;
+ for (unsigned i = 0, e = $4->size(); i != e; ++i) {
+ Constant *C = (*$4)[i].C;
+ if (C->getType() != STy->getElementType(i))
+ error("Expected type '" + STy->getElementType(i)->getDescription() +
+ "' for element #" + utostr(i) + " of packed struct initializer");
+ Fields.push_back(C);
+ }
+ $$.C = ConstantStruct::get(STy, Fields);
+ $$.S.copy($1.S);
+ delete $1.PAT;
+ delete $4;
+ }
+ | Types '<' '{' '}' '>' {
+ const StructType *STy = dyn_cast<StructType>($1.PAT->get());
+ if (STy == 0)
+ error("Cannot make packed struct constant with type: '" +
+ $1.PAT->get()->getDescription() + "'");
+ if (STy->getNumContainedTypes() != 0)
+ error("Illegal number of initializers for packed structure type");
+ $$.C = ConstantStruct::get(STy, std::vector<Constant*>());
+ $$.S.copy($1.S);
+ delete $1.PAT;
+ }
+ | Types NULL_TOK {
+ const PointerType *PTy = dyn_cast<PointerType>($1.PAT->get());
+ if (PTy == 0)
+ error("Cannot make null pointer constant with type: '" +
+ $1.PAT->get()->getDescription() + "'");
+ $$.C = ConstantPointerNull::get(PTy);
+ $$.S.copy($1.S);
+ delete $1.PAT;
+ }
+ | Types UNDEF {
+ $$.C = UndefValue::get($1.PAT->get());
+ $$.S.copy($1.S);
+ delete $1.PAT;
+ }
+ | Types SymbolicValueRef {
+ const PointerType *Ty = dyn_cast<PointerType>($1.PAT->get());
+ if (Ty == 0)
+ error("Global const reference must be a pointer type, not" +
+ $1.PAT->get()->getDescription());
+
+ // ConstExprs can exist in the body of a function, thus creating
+ // GlobalValues whenever they refer to a variable. Because we are in
+ // the context of a function, getExistingValue will search the functions
+ // symbol table instead of the module symbol table for the global symbol,
+ // which throws things all off. To get around this, we just tell
+ // getExistingValue that we are at global scope here.
+ //
+ Function *SavedCurFn = CurFun.CurrentFunction;
+ CurFun.CurrentFunction = 0;
+ $2.S.copy($1.S);
+ Value *V = getExistingValue(Ty, $2);
+ CurFun.CurrentFunction = SavedCurFn;
+
+ // If this is an initializer for a constant pointer, which is referencing a
+ // (currently) undefined variable, create a stub now that shall be replaced
+ // in the future with the right type of variable.
+ //
+ if (V == 0) {
+ assert(isa<PointerType>(Ty) && "Globals may only be used as pointers");
+ const PointerType *PT = cast<PointerType>(Ty);
+
+ // First check to see if the forward references value is already created!
+ PerModuleInfo::GlobalRefsType::iterator I =
+ CurModule.GlobalRefs.find(std::make_pair(PT, $2));
+
+ if (I != CurModule.GlobalRefs.end()) {
+ V = I->second; // Placeholder already exists, use it...
+ $2.destroy();
+ } else {
+ std::string Name;
+ if ($2.Type == ValID::NameVal) Name = $2.Name;
+
+ // Create the forward referenced global.
+ GlobalValue *GV;
+ if (const FunctionType *FTy =
+ dyn_cast<FunctionType>(PT->getElementType())) {
+ GV = new Function(FTy, GlobalValue::ExternalLinkage, Name,
+ CurModule.CurrentModule);
+ } else {
+ GV = new GlobalVariable(PT->getElementType(), false,
+ GlobalValue::ExternalLinkage, 0,
+ Name, CurModule.CurrentModule);
+ }
+
+ // Keep track of the fact that we have a forward ref to recycle it
+ CurModule.GlobalRefs.insert(std::make_pair(std::make_pair(PT, $2), GV));
+ V = GV;
+ }
+ }
+ $$.C = cast<GlobalValue>(V);
+ $$.S.copy($1.S);
+ delete $1.PAT; // Free the type handle
+ }
+ | Types ConstExpr {
+ if ($1.PAT->get() != $2.C->getType())
+ error("Mismatched types for constant expression");
+ $$ = $2;
+ $$.S.copy($1.S);
+ delete $1.PAT;
+ }
+ | Types ZEROINITIALIZER {
+ const Type *Ty = $1.PAT->get();
+ if (isa<FunctionType>(Ty) || Ty == Type::LabelTy || isa<OpaqueType>(Ty))
+ error("Cannot create a null initialized value of this type");
+ $$.C = Constant::getNullValue(Ty);
+ $$.S.copy($1.S);
+ delete $1.PAT;
+ }
+ | SIntType EINT64VAL { // integral constants
+ const Type *Ty = $1.T;
+ if (!ConstantInt::isValueValidForType(Ty, $2))
+ error("Constant value doesn't fit in type");
+ $$.C = ConstantInt::get(Ty, $2);
+ $$.S.makeSigned();
+ }
+ | UIntType EUINT64VAL { // integral constants
+ const Type *Ty = $1.T;
+ if (!ConstantInt::isValueValidForType(Ty, $2))
+ error("Constant value doesn't fit in type");
+ $$.C = ConstantInt::get(Ty, $2);
+ $$.S.makeUnsigned();
+ }
+ | BOOL TRUETOK { // Boolean constants
+ $$.C = ConstantInt::get(Type::Int1Ty, true);
+ $$.S.makeUnsigned();
+ }
+ | BOOL FALSETOK { // Boolean constants
+ $$.C = ConstantInt::get(Type::Int1Ty, false);
+ $$.S.makeUnsigned();
+ }
+ | FPType FPVAL { // Float & Double constants
+ if (!ConstantFP::isValueValidForType($1.T, $2))
+ error("Floating point constant invalid for type");
+ $$.C = ConstantFP::get($1.T, $2);
+ $$.S.makeSignless();
+ }
+ ;
+
+ConstExpr
+ : CastOps '(' ConstVal TO Types ')' {
+ const Type* SrcTy = $3.C->getType();
+ const Type* DstTy = $5.PAT->get();
+ Signedness SrcSign($3.S);
+ Signedness DstSign($5.S);
+ if (!SrcTy->isFirstClassType())
+ error("cast constant expression from a non-primitive type: '" +
+ SrcTy->getDescription() + "'");
+ if (!DstTy->isFirstClassType())
+ error("cast constant expression to a non-primitive type: '" +
+ DstTy->getDescription() + "'");
+ $$.C = cast<Constant>(getCast($1, $3.C, SrcSign, DstTy, DstSign));
+ $$.S.copy(DstSign);
+ delete $5.PAT;
+ }
+ | GETELEMENTPTR '(' ConstVal IndexList ')' {
+ const Type *Ty = $3.C->getType();
+ if (!isa<PointerType>(Ty))
+ error("GetElementPtr requires a pointer operand");
+
+ std::vector<Constant*> CIndices;
+ upgradeGEPCEIndices($3.C->getType(), $4, CIndices);
+
+ delete $4;
+ $$.C = ConstantExpr::getGetElementPtr($3.C, &CIndices[0], CIndices.size());
+ $$.S.copy(getElementSign($3, CIndices));
+ }
+ | SELECT '(' ConstVal ',' ConstVal ',' ConstVal ')' {
+ if (!$3.C->getType()->isInteger() ||
+ cast<IntegerType>($3.C->getType())->getBitWidth() != 1)
+ error("Select condition must be bool type");
+ if ($5.C->getType() != $7.C->getType())
+ error("Select operand types must match");
+ $$.C = ConstantExpr::getSelect($3.C, $5.C, $7.C);
+ $$.S.copy($5.S);
+ }
+ | ArithmeticOps '(' ConstVal ',' ConstVal ')' {
+ const Type *Ty = $3.C->getType();
+ if (Ty != $5.C->getType())
+ error("Binary operator types must match");
+ // First, make sure we're dealing with the right opcode by upgrading from
+ // obsolete versions.
+ Instruction::BinaryOps Opcode = getBinaryOp($1, Ty, $3.S);
+
+ // HACK: llvm 1.3 and earlier used to emit invalid pointer constant exprs.
+ // To retain backward compatibility with these early compilers, we emit a
+ // cast to the appropriate integer type automatically if we are in the
+ // broken case. See PR424 for more information.
+ if (!isa<PointerType>(Ty)) {
+ $$.C = ConstantExpr::get(Opcode, $3.C, $5.C);
+ } else {
+ const Type *IntPtrTy = 0;
+ switch (CurModule.CurrentModule->getPointerSize()) {
+ case Module::Pointer32: IntPtrTy = Type::Int32Ty; break;
+ case Module::Pointer64: IntPtrTy = Type::Int64Ty; break;
+ default: error("invalid pointer binary constant expr");
+ }
+ $$.C = ConstantExpr::get(Opcode,
+ ConstantExpr::getCast(Instruction::PtrToInt, $3.C, IntPtrTy),
+ ConstantExpr::getCast(Instruction::PtrToInt, $5.C, IntPtrTy));
+ $$.C = ConstantExpr::getCast(Instruction::IntToPtr, $$.C, Ty);
+ }
+ $$.S.copy($3.S);
+ }
+ | LogicalOps '(' ConstVal ',' ConstVal ')' {
+ const Type* Ty = $3.C->getType();
+ if (Ty != $5.C->getType())
+ error("Logical operator types must match");
+ if (!Ty->isInteger()) {
+ if (!isa<VectorType>(Ty) ||
+ !cast<VectorType>(Ty)->getElementType()->isInteger())
+ error("Logical operator requires integer operands");
+ }
+ Instruction::BinaryOps Opcode = getBinaryOp($1, Ty, $3.S);
+ $$.C = ConstantExpr::get(Opcode, $3.C, $5.C);
+ $$.S.copy($3.S);
+ }
+ | SetCondOps '(' ConstVal ',' ConstVal ')' {
+ const Type* Ty = $3.C->getType();
+ if (Ty != $5.C->getType())
+ error("setcc operand types must match");
+ unsigned short pred;
+ Instruction::OtherOps Opcode = getCompareOp($1, pred, Ty, $3.S);
+ $$.C = ConstantExpr::getCompare(Opcode, $3.C, $5.C);
+ $$.S.makeUnsigned();
+ }
+ | ICMP IPredicates '(' ConstVal ',' ConstVal ')' {
+ if ($4.C->getType() != $6.C->getType())
+ error("icmp operand types must match");
+ $$.C = ConstantExpr::getCompare($2, $4.C, $6.C);
+ $$.S.makeUnsigned();
+ }
+ | FCMP FPredicates '(' ConstVal ',' ConstVal ')' {
+ if ($4.C->getType() != $6.C->getType())
+ error("fcmp operand types must match");
+ $$.C = ConstantExpr::getCompare($2, $4.C, $6.C);
+ $$.S.makeUnsigned();
+ }
+ | ShiftOps '(' ConstVal ',' ConstVal ')' {
+ if (!$5.C->getType()->isInteger() ||
+ cast<IntegerType>($5.C->getType())->getBitWidth() != 8)
+ error("Shift count for shift constant must be unsigned byte");
+ const Type* Ty = $3.C->getType();
+ if (!$3.C->getType()->isInteger())
+ error("Shift constant expression requires integer operand");
+ Constant *ShiftAmt = ConstantExpr::getZExt($5.C, Ty);
+ $$.C = ConstantExpr::get(getBinaryOp($1, Ty, $3.S), $3.C, ShiftAmt);
+ $$.S.copy($3.S);
+ }
+ | EXTRACTELEMENT '(' ConstVal ',' ConstVal ')' {
+ if (!ExtractElementInst::isValidOperands($3.C, $5.C))
+ error("Invalid extractelement operands");
+ $$.C = ConstantExpr::getExtractElement($3.C, $5.C);
+ $$.S.copy($3.S.get(0));
+ }
+ | INSERTELEMENT '(' ConstVal ',' ConstVal ',' ConstVal ')' {
+ if (!InsertElementInst::isValidOperands($3.C, $5.C, $7.C))
+ error("Invalid insertelement operands");
+ $$.C = ConstantExpr::getInsertElement($3.C, $5.C, $7.C);
+ $$.S.copy($3.S);
+ }
+ | SHUFFLEVECTOR '(' ConstVal ',' ConstVal ',' ConstVal ')' {
+ if (!ShuffleVectorInst::isValidOperands($3.C, $5.C, $7.C))
+ error("Invalid shufflevector operands");
+ $$.C = ConstantExpr::getShuffleVector($3.C, $5.C, $7.C);
+ $$.S.copy($3.S);
+ }
+ ;
+
+
+// ConstVector - A list of comma separated constants.
+ConstVector
+ : ConstVector ',' ConstVal { ($$ = $1)->push_back($3); }
+ | ConstVal {
+ $$ = new std::vector<ConstInfo>();
+ $$->push_back($1);
+ }
+ ;
+
+
+// GlobalType - Match either GLOBAL or CONSTANT for global declarations...
+GlobalType
+ : GLOBAL { $$ = false; }
+ | CONSTANT { $$ = true; }
+ ;
+
+
+//===----------------------------------------------------------------------===//
+// Rules to match Modules
+//===----------------------------------------------------------------------===//
+
+// Module rule: Capture the result of parsing the whole file into a result
+// variable...
+//
+Module
+ : FunctionList {
+ $$ = ParserResult = $1;
+ CurModule.ModuleDone();
+ }
+ ;
+
+// FunctionList - A list of functions, preceeded by a constant pool.
+//
+FunctionList
+ : FunctionList Function { $$ = $1; CurFun.FunctionDone(); }
+ | FunctionList FunctionProto { $$ = $1; }
+ | FunctionList MODULE ASM_TOK AsmBlock { $$ = $1; }
+ | FunctionList IMPLEMENTATION { $$ = $1; }
+ | ConstPool {
+ $$ = CurModule.CurrentModule;
+ // Emit an error if there are any unresolved types left.
+ if (!CurModule.LateResolveTypes.empty()) {
+ const ValID &DID = CurModule.LateResolveTypes.begin()->first;
+ if (DID.Type == ValID::NameVal) {
+ error("Reference to an undefined type: '"+DID.getName() + "'");
+ } else {
+ error("Reference to an undefined type: #" + itostr(DID.Num));
+ }
+ }
+ }
+ ;
+
+// ConstPool - Constants with optional names assigned to them.
+ConstPool
+ : ConstPool OptAssign TYPE TypesV {
+ // Eagerly resolve types. This is not an optimization, this is a
+ // requirement that is due to the fact that we could have this:
+ //
+ // %list = type { %list * }
+ // %list = type { %list * } ; repeated type decl
+ //
+ // If types are not resolved eagerly, then the two types will not be
+ // determined to be the same type!
+ //
+ ResolveTypeTo($2, $4.PAT->get(), $4.S);
+
+ if (!setTypeName($4, $2) && !$2) {
+ // If this is a numbered type that is not a redefinition, add it to the
+ // slot table.
+ CurModule.Types.push_back($4.PAT->get());
+ CurModule.TypeSigns.push_back($4.S);
+ }
+ delete $4.PAT;
+ }
+ | ConstPool FunctionProto { // Function prototypes can be in const pool
+ }
+ | ConstPool MODULE ASM_TOK AsmBlock { // Asm blocks can be in the const pool
+ }
+ | ConstPool OptAssign OptLinkage GlobalType ConstVal {
+ if ($5.C == 0)
+ error("Global value initializer is not a constant");
+ CurGV = ParseGlobalVariable($2, $3, $4, $5.C->getType(), $5.C, $5.S);
+ } GlobalVarAttributes {
+ CurGV = 0;
+ }
+ | ConstPool OptAssign EXTERNAL GlobalType Types {
+ const Type *Ty = $5.PAT->get();
+ CurGV = ParseGlobalVariable($2, GlobalValue::ExternalLinkage, $4, Ty, 0,
+ $5.S);
+ delete $5.PAT;
+ } GlobalVarAttributes {
+ CurGV = 0;
+ }
+ | ConstPool OptAssign DLLIMPORT GlobalType Types {
+ const Type *Ty = $5.PAT->get();
+ CurGV = ParseGlobalVariable($2, GlobalValue::DLLImportLinkage, $4, Ty, 0,
+ $5.S);
+ delete $5.PAT;
+ } GlobalVarAttributes {
+ CurGV = 0;
+ }
+ | ConstPool OptAssign EXTERN_WEAK GlobalType Types {
+ const Type *Ty = $5.PAT->get();
+ CurGV =
+ ParseGlobalVariable($2, GlobalValue::ExternalWeakLinkage, $4, Ty, 0,
+ $5.S);
+ delete $5.PAT;
+ } GlobalVarAttributes {
+ CurGV = 0;
+ }
+ | ConstPool TARGET TargetDefinition {
+ }
+ | ConstPool DEPLIBS '=' LibrariesDefinition {
+ }
+ | /* empty: end of list */ {
+ }
+ ;
+
+AsmBlock
+ : STRINGCONSTANT {
+ const std::string &AsmSoFar = CurModule.CurrentModule->getModuleInlineAsm();
+ char *EndStr = UnEscapeLexed($1, true);
+ std::string NewAsm($1, EndStr);
+ free($1);
+
+ if (AsmSoFar.empty())
+ CurModule.CurrentModule->setModuleInlineAsm(NewAsm);
+ else
+ CurModule.CurrentModule->setModuleInlineAsm(AsmSoFar+"\n"+NewAsm);
+ }
+ ;
+
+BigOrLittle
+ : BIG { $$ = Module::BigEndian; }
+ | LITTLE { $$ = Module::LittleEndian; }
+ ;
+
+TargetDefinition
+ : ENDIAN '=' BigOrLittle {
+ CurModule.setEndianness($3);
+ }
+ | POINTERSIZE '=' EUINT64VAL {
+ if ($3 == 32)
+ CurModule.setPointerSize(Module::Pointer32);
+ else if ($3 == 64)
+ CurModule.setPointerSize(Module::Pointer64);
+ else
+ error("Invalid pointer size: '" + utostr($3) + "'");
+ }
+ | TRIPLE '=' STRINGCONSTANT {
+ CurModule.CurrentModule->setTargetTriple($3);
+ free($3);
+ }
+ | DATALAYOUT '=' STRINGCONSTANT {
+ CurModule.CurrentModule->setDataLayout($3);
+ free($3);
+ }
+ ;
+
+LibrariesDefinition
+ : '[' LibList ']'
+ ;
+
+LibList
+ : LibList ',' STRINGCONSTANT {
+ CurModule.CurrentModule->addLibrary($3);
+ free($3);
+ }
+ | STRINGCONSTANT {
+ CurModule.CurrentModule->addLibrary($1);
+ free($1);
+ }
+ | /* empty: end of list */ { }
+ ;
+
+//===----------------------------------------------------------------------===//
+// Rules to match Function Headers
+//===----------------------------------------------------------------------===//
+
+Name
+ : VAR_ID | STRINGCONSTANT
+ ;
+
+OptName
+ : Name
+ | /*empty*/ { $$ = 0; }
+ ;
+
+ArgVal
+ : Types OptName {
+ if ($1.PAT->get() == Type::VoidTy)
+ error("void typed arguments are invalid");
+ $$ = new std::pair<PATypeInfo, char*>($1, $2);
+ }
+ ;
+
+ArgListH
+ : ArgListH ',' ArgVal {
+ $$ = $1;
+ $$->push_back(*$3);
+ delete $3;
+ }
+ | ArgVal {
+ $$ = new std::vector<std::pair<PATypeInfo,char*> >();
+ $$->push_back(*$1);
+ delete $1;
+ }
+ ;
+
+ArgList
+ : ArgListH { $$ = $1; }
+ | ArgListH ',' DOTDOTDOT {
+ $$ = $1;
+ PATypeInfo VoidTI;
+ VoidTI.PAT = new PATypeHolder(Type::VoidTy);
+ VoidTI.S.makeSignless();
+ $$->push_back(std::pair<PATypeInfo, char*>(VoidTI, 0));
+ }
+ | DOTDOTDOT {
+ $$ = new std::vector<std::pair<PATypeInfo,char*> >();
+ PATypeInfo VoidTI;
+ VoidTI.PAT = new PATypeHolder(Type::VoidTy);
+ VoidTI.S.makeSignless();
+ $$->push_back(std::pair<PATypeInfo, char*>(VoidTI, 0));
+ }
+ | /* empty */ { $$ = 0; }
+ ;
+
+FunctionHeaderH
+ : OptCallingConv TypesV Name '(' ArgList ')' OptSection OptAlign {
+ UnEscapeLexed($3);
+ std::string FunctionName($3);
+ free($3); // Free strdup'd memory!
+
+ const Type* RetTy = $2.PAT->get();
+
+ if (!RetTy->isFirstClassType() && RetTy != Type::VoidTy)
+ error("LLVM functions cannot return aggregate types");
+
+ Signedness FTySign;
+ FTySign.makeComposite($2.S);
+ std::vector<const Type*> ParamTyList;
+
+ // In LLVM 2.0 the signatures of three varargs intrinsics changed to take
+ // i8*. We check here for those names and override the parameter list
+ // types to ensure the prototype is correct.
+ if (FunctionName == "llvm.va_start" || FunctionName == "llvm.va_end") {
+ ParamTyList.push_back(PointerType::get(Type::Int8Ty));
+ } else if (FunctionName == "llvm.va_copy") {
+ ParamTyList.push_back(PointerType::get(Type::Int8Ty));
+ ParamTyList.push_back(PointerType::get(Type::Int8Ty));
+ } else if ($5) { // If there are arguments...
+ for (std::vector<std::pair<PATypeInfo,char*> >::iterator
+ I = $5->begin(), E = $5->end(); I != E; ++I) {
+ const Type *Ty = I->first.PAT->get();
+ ParamTyList.push_back(Ty);
+ FTySign.add(I->first.S);
+ }
+ }
+
+ bool isVarArg = ParamTyList.size() && ParamTyList.back() == Type::VoidTy;
+ if (isVarArg)
+ ParamTyList.pop_back();
+
+ // Convert the CSRet calling convention into the corresponding parameter
+ // attribute.
+ ParamAttrsList *PAL = 0;
+ if ($1 == OldCallingConv::CSRet) {
+ ParamAttrsVector Attrs;
+ ParamAttrsWithIndex PAWI;
+ PAWI.index = 1; PAWI.attrs = ParamAttr::StructRet; // first arg
+ Attrs.push_back(PAWI);
+ PAL = ParamAttrsList::get(Attrs);
+ }
+
+ const FunctionType *FT =
+ FunctionType::get(RetTy, ParamTyList, isVarArg, PAL);
+ const PointerType *PFT = PointerType::get(FT);
+ delete $2.PAT;
+
+ ValID ID;
+ if (!FunctionName.empty()) {
+ ID = ValID::create((char*)FunctionName.c_str());
+ } else {
+ ID = ValID::create((int)CurModule.Values[PFT].size());
+ }
+ ID.S.makeComposite(FTySign);
+
+ Function *Fn = 0;
+ Module* M = CurModule.CurrentModule;
+
+ // See if this function was forward referenced. If so, recycle the object.
+ if (GlobalValue *FWRef = CurModule.GetForwardRefForGlobal(PFT, ID)) {
+ // Move the function to the end of the list, from whereever it was
+ // previously inserted.
+ Fn = cast<Function>(FWRef);
+ M->getFunctionList().remove(Fn);
+ M->getFunctionList().push_back(Fn);
+ } else if (!FunctionName.empty()) {
+ GlobalValue *Conflict = M->getFunction(FunctionName);
+ if (!Conflict)
+ Conflict = M->getNamedGlobal(FunctionName);
+ if (Conflict && PFT == Conflict->getType()) {
+ if (!CurFun.isDeclare && !Conflict->isDeclaration()) {
+ // We have two function definitions that conflict, same type, same
+ // name. We should really check to make sure that this is the result
+ // of integer type planes collapsing and generate an error if it is
+ // not, but we'll just rename on the assumption that it is. However,
+ // let's do it intelligently and rename the internal linkage one
+ // if there is one.
+ std::string NewName(makeNameUnique(FunctionName));
+ if (Conflict->hasInternalLinkage()) {
+ Conflict->setName(NewName);
+ RenameMapKey Key =
+ makeRenameMapKey(FunctionName, Conflict->getType(), ID.S);
+ CurModule.RenameMap[Key] = NewName;
+ Fn = new Function(FT, CurFun.Linkage, FunctionName, M);
+ InsertValue(Fn, CurModule.Values);
+ } else {
+ Fn = new Function(FT, CurFun.Linkage, NewName, M);
+ InsertValue(Fn, CurModule.Values);
+ RenameMapKey Key =
+ makeRenameMapKey(FunctionName, PFT, ID.S);
+ CurModule.RenameMap[Key] = NewName;
+ }
+ } else {
+ // If they are not both definitions, then just use the function we
+ // found since the types are the same.
+ Fn = cast<Function>(Conflict);
+
+ // Make sure to strip off any argument names so we can't get
+ // conflicts.
+ if (Fn->isDeclaration())
+ for (Function::arg_iterator AI = Fn->arg_begin(),
+ AE = Fn->arg_end(); AI != AE; ++AI)
+ AI->setName("");
+ }
+ } else if (Conflict) {
+ // We have two globals with the same name and different types.
+ // Previously, this was permitted because the symbol table had
+ // "type planes" and names only needed to be distinct within a
+ // type plane. After PR411 was fixed, this is no loner the case.
+ // To resolve this we must rename one of the two.
+ if (Conflict->hasInternalLinkage()) {
+ // We can safely rename the Conflict.
+ RenameMapKey Key =
+ makeRenameMapKey(Conflict->getName(), Conflict->getType(),
+ CurModule.NamedValueSigns[Conflict->getName()]);
+ Conflict->setName(makeNameUnique(Conflict->getName()));
+ CurModule.RenameMap[Key] = Conflict->getName();
+ Fn = new Function(FT, CurFun.Linkage, FunctionName, M);
+ InsertValue(Fn, CurModule.Values);
+ } else {
+ // We can't quietly rename either of these things, but we must
+ // rename one of them. Only if the function's linkage is internal can
+ // we forgo a warning message about the renamed function.
+ std::string NewName = makeNameUnique(FunctionName);
+ if (CurFun.Linkage != GlobalValue::InternalLinkage) {
+ warning("Renaming function '" + FunctionName + "' as '" + NewName +
+ "' may cause linkage errors");
+ }
+ // Elect to rename the thing we're now defining.
+ Fn = new Function(FT, CurFun.Linkage, NewName, M);
+ InsertValue(Fn, CurModule.Values);
+ RenameMapKey Key = makeRenameMapKey(FunctionName, PFT, ID.S);
+ CurModule.RenameMap[Key] = NewName;
+ }
+ } else {
+ // There's no conflict, just define the function
+ Fn = new Function(FT, CurFun.Linkage, FunctionName, M);
+ InsertValue(Fn, CurModule.Values);
+ }
+ } else {
+ // There's no conflict, just define the function
+ Fn = new Function(FT, CurFun.Linkage, FunctionName, M);
+ InsertValue(Fn, CurModule.Values);
+ }
+
+
+ CurFun.FunctionStart(Fn);
+
+ if (CurFun.isDeclare) {
+ // If we have declaration, always overwrite linkage. This will allow us
+ // to correctly handle cases, when pointer to function is passed as
+ // argument to another function.
+ Fn->setLinkage(CurFun.Linkage);
+ }
+ Fn->setCallingConv(upgradeCallingConv($1));
+ Fn->setAlignment($8);
+ if ($7) {
+ Fn->setSection($7);
+ free($7);
+ }
+
+ // Add all of the arguments we parsed to the function...
+ if ($5) { // Is null if empty...
+ if (isVarArg) { // Nuke the last entry
+ assert($5->back().first.PAT->get() == Type::VoidTy &&
+ $5->back().second == 0 && "Not a varargs marker");
+ delete $5->back().first.PAT;
+ $5->pop_back(); // Delete the last entry
+ }
+ Function::arg_iterator ArgIt = Fn->arg_begin();
+ Function::arg_iterator ArgEnd = Fn->arg_end();
+ std::vector<std::pair<PATypeInfo,char*> >::iterator I = $5->begin();
+ std::vector<std::pair<PATypeInfo,char*> >::iterator E = $5->end();
+ for ( ; I != E && ArgIt != ArgEnd; ++I, ++ArgIt) {
+ delete I->first.PAT; // Delete the typeholder...
+ ValueInfo VI; VI.V = ArgIt; VI.S.copy(I->first.S);
+ setValueName(VI, I->second); // Insert arg into symtab...
+ InsertValue(ArgIt);
+ }
+ delete $5; // We're now done with the argument list
+ }
+ lastCallingConv = OldCallingConv::C;
+ }
+ ;
+
+BEGIN
+ : BEGINTOK | '{' // Allow BEGIN or '{' to start a function
+ ;
+
+FunctionHeader
+ : OptLinkage { CurFun.Linkage = $1; } FunctionHeaderH BEGIN {
+ $$ = CurFun.CurrentFunction;
+
+ // Make sure that we keep track of the linkage type even if there was a
+ // previous "declare".
+ $$->setLinkage($1);
+ }
+ ;
+
+END
+ : ENDTOK | '}' // Allow end of '}' to end a function
+ ;
+
+Function
+ : BasicBlockList END {
+ $$ = $1;
+ };
+
+FnDeclareLinkage
+ : /*default*/ { $$ = GlobalValue::ExternalLinkage; }
+ | DLLIMPORT { $$ = GlobalValue::DLLImportLinkage; }
+ | EXTERN_WEAK { $$ = GlobalValue::ExternalWeakLinkage; }
+ ;
+
+FunctionProto
+ : DECLARE { CurFun.isDeclare = true; }
+ FnDeclareLinkage { CurFun.Linkage = $3; } FunctionHeaderH {
+ $$ = CurFun.CurrentFunction;
+ CurFun.FunctionDone();
+
+ }
+ ;
+
+//===----------------------------------------------------------------------===//
+// Rules to match Basic Blocks
+//===----------------------------------------------------------------------===//
+
+OptSideEffect
+ : /* empty */ { $$ = false; }
+ | SIDEEFFECT { $$ = true; }
+ ;
+
+ConstValueRef
+ // A reference to a direct constant
+ : ESINT64VAL { $$ = ValID::create($1); }
+ | EUINT64VAL { $$ = ValID::create($1); }
+ | FPVAL { $$ = ValID::create($1); }
+ | TRUETOK {
+ $$ = ValID::create(ConstantInt::get(Type::Int1Ty, true));
+ $$.S.makeUnsigned();
+ }
+ | FALSETOK {
+ $$ = ValID::create(ConstantInt::get(Type::Int1Ty, false));
+ $$.S.makeUnsigned();
+ }
+ | NULL_TOK { $$ = ValID::createNull(); }
+ | UNDEF { $$ = ValID::createUndef(); }
+ | ZEROINITIALIZER { $$ = ValID::createZeroInit(); }
+ | '<' ConstVector '>' { // Nonempty unsized packed vector
+ const Type *ETy = (*$2)[0].C->getType();
+ int NumElements = $2->size();
+ VectorType* pt = VectorType::get(ETy, NumElements);
+ $$.S.makeComposite((*$2)[0].S);
+ PATypeHolder* PTy = new PATypeHolder(HandleUpRefs(pt, $$.S));
+
+ // Verify all elements are correct type!
+ std::vector<Constant*> Elems;
+ for (unsigned i = 0; i < $2->size(); i++) {
+ Constant *C = (*$2)[i].C;
+ const Type *CTy = C->getType();
+ if (ETy != CTy)
+ error("Element #" + utostr(i) + " is not of type '" +
+ ETy->getDescription() +"' as required!\nIt is of type '" +
+ CTy->getDescription() + "'");
+ Elems.push_back(C);
+ }
+ $$ = ValID::create(ConstantVector::get(pt, Elems));
+ delete PTy; delete $2;
+ }
+ | ConstExpr {
+ $$ = ValID::create($1.C);
+ $$.S.copy($1.S);
+ }
+ | ASM_TOK OptSideEffect STRINGCONSTANT ',' STRINGCONSTANT {
+ char *End = UnEscapeLexed($3, true);
+ std::string AsmStr = std::string($3, End);
+ End = UnEscapeLexed($5, true);
+ std::string Constraints = std::string($5, End);
+ $$ = ValID::createInlineAsm(AsmStr, Constraints, $2);
+ free($3);
+ free($5);
+ }
+ ;
+
+// SymbolicValueRef - Reference to one of two ways of symbolically refering to // another value.
+//
+SymbolicValueRef
+ : INTVAL { $$ = ValID::create($1); $$.S.makeSignless(); }
+ | Name { $$ = ValID::create($1); $$.S.makeSignless(); }
+ ;
+
+// ValueRef - A reference to a definition... either constant or symbolic
+ValueRef
+ : SymbolicValueRef | ConstValueRef
+ ;
+
+
+// ResolvedVal - a <type> <value> pair. This is used only in cases where the
+// type immediately preceeds the value reference, and allows complex constant
+// pool references (for things like: 'ret [2 x int] [ int 12, int 42]')
+ResolvedVal
+ : Types ValueRef {
+ const Type *Ty = $1.PAT->get();
+ $2.S.copy($1.S);
+ $$.V = getVal(Ty, $2);
+ $$.S.copy($1.S);
+ delete $1.PAT;
+ }
+ ;
+
+BasicBlockList
+ : BasicBlockList BasicBlock {
+ $$ = $1;
+ }
+ | FunctionHeader BasicBlock { // Do not allow functions with 0 basic blocks
+ $$ = $1;
+ };
+
+
+// Basic blocks are terminated by branching instructions:
+// br, br/cc, switch, ret
+//
+BasicBlock
+ : InstructionList OptAssign BBTerminatorInst {
+ ValueInfo VI; VI.V = $3.TI; VI.S.copy($3.S);
+ setValueName(VI, $2);
+ InsertValue($3.TI);
+ $1->getInstList().push_back($3.TI);
+ InsertValue($1);
+ $$ = $1;
+ }
+ ;
+
+InstructionList
+ : InstructionList Inst {
+ if ($2.I)
+ $1->getInstList().push_back($2.I);
+ $$ = $1;
+ }
+ | /* empty */ {
+ $$ = CurBB = getBBVal(ValID::create((int)CurFun.NextBBNum++),true);
+ // Make sure to move the basic block to the correct location in the
+ // function, instead of leaving it inserted wherever it was first
+ // referenced.
+ Function::BasicBlockListType &BBL =
+ CurFun.CurrentFunction->getBasicBlockList();
+ BBL.splice(BBL.end(), BBL, $$);
+ }
+ | LABELSTR {
+ $$ = CurBB = getBBVal(ValID::create($1), true);
+ // Make sure to move the basic block to the correct location in the
+ // function, instead of leaving it inserted wherever it was first
+ // referenced.
+ Function::BasicBlockListType &BBL =
+ CurFun.CurrentFunction->getBasicBlockList();
+ BBL.splice(BBL.end(), BBL, $$);
+ }
+ ;
+
+Unwind : UNWIND | EXCEPT;
+
+BBTerminatorInst
+ : RET ResolvedVal { // Return with a result...
+ $$.TI = new ReturnInst($2.V);
+ $$.S.makeSignless();
+ }
+ | RET VOID { // Return with no result...
+ $$.TI = new ReturnInst();
+ $$.S.makeSignless();
+ }
+ | BR LABEL ValueRef { // Unconditional Branch...
+ BasicBlock* tmpBB = getBBVal($3);
+ $$.TI = new BranchInst(tmpBB);
+ $$.S.makeSignless();
+ } // Conditional Branch...
+ | BR BOOL ValueRef ',' LABEL ValueRef ',' LABEL ValueRef {
+ $6.S.makeSignless();
+ $9.S.makeSignless();
+ BasicBlock* tmpBBA = getBBVal($6);
+ BasicBlock* tmpBBB = getBBVal($9);
+ $3.S.makeUnsigned();
+ Value* tmpVal = getVal(Type::Int1Ty, $3);
+ $$.TI = new BranchInst(tmpBBA, tmpBBB, tmpVal);
+ $$.S.makeSignless();
+ }
+ | SWITCH IntType ValueRef ',' LABEL ValueRef '[' JumpTable ']' {
+ $3.S.copy($2.S);
+ Value* tmpVal = getVal($2.T, $3);
+ $6.S.makeSignless();
+ BasicBlock* tmpBB = getBBVal($6);
+ SwitchInst *S = new SwitchInst(tmpVal, tmpBB, $8->size());
+ $$.TI = S;
+ $$.S.makeSignless();
+ std::vector<std::pair<Constant*,BasicBlock*> >::iterator I = $8->begin(),
+ E = $8->end();
+ for (; I != E; ++I) {
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(I->first))
+ S->addCase(CI, I->second);
+ else
+ error("Switch case is constant, but not a simple integer");
+ }
+ delete $8;
+ }
+ | SWITCH IntType ValueRef ',' LABEL ValueRef '[' ']' {
+ $3.S.copy($2.S);
+ Value* tmpVal = getVal($2.T, $3);
+ $6.S.makeSignless();
+ BasicBlock* tmpBB = getBBVal($6);
+ SwitchInst *S = new SwitchInst(tmpVal, tmpBB, 0);
+ $$.TI = S;
+ $$.S.makeSignless();
+ }
+ | INVOKE OptCallingConv TypesV ValueRef '(' ValueRefListE ')'
+ TO LABEL ValueRef Unwind LABEL ValueRef {
+ const PointerType *PFTy;
+ const FunctionType *Ty;
+ Signedness FTySign;
+
+ if (!(PFTy = dyn_cast<PointerType>($3.PAT->get())) ||
+ !(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) {
+ // Pull out the types of all of the arguments...
+ std::vector<const Type*> ParamTypes;
+ FTySign.makeComposite($3.S);
+ if ($6) {
+ for (std::vector<ValueInfo>::iterator I = $6->begin(), E = $6->end();
+ I != E; ++I) {
+ ParamTypes.push_back((*I).V->getType());
+ FTySign.add(I->S);
+ }
+ }
+ ParamAttrsList *PAL = 0;
+ if ($2 == OldCallingConv::CSRet) {
+ ParamAttrsVector Attrs;
+ ParamAttrsWithIndex PAWI;
+ PAWI.index = 1; PAWI.attrs = ParamAttr::StructRet; // first arg
+ Attrs.push_back(PAWI);
+ PAL = ParamAttrsList::get(Attrs);
+ }
+ bool isVarArg = ParamTypes.size() && ParamTypes.back() == Type::VoidTy;
+ if (isVarArg) ParamTypes.pop_back();
+ Ty = FunctionType::get($3.PAT->get(), ParamTypes, isVarArg, PAL);
+ PFTy = PointerType::get(Ty);
+ $$.S.copy($3.S);
+ } else {
+ FTySign = $3.S;
+ // Get the signedness of the result type. $3 is the pointer to the
+ // function type so we get the 0th element to extract the function type,
+ // and then the 0th element again to get the result type.
+ $$.S.copy($3.S.get(0).get(0));
+ }
+
+ $4.S.makeComposite(FTySign);
+ Value *V = getVal(PFTy, $4); // Get the function we're calling...
+ BasicBlock *Normal = getBBVal($10);
+ BasicBlock *Except = getBBVal($13);
+
+ // Create the call node...
+ if (!$6) { // Has no arguments?
+ $$.TI = new InvokeInst(V, Normal, Except, 0, 0);
+ } else { // Has arguments?
+ // Loop through FunctionType's arguments and ensure they are specified
+ // correctly!
+ //
+ FunctionType::param_iterator I = Ty->param_begin();
+ FunctionType::param_iterator E = Ty->param_end();
+ std::vector<ValueInfo>::iterator ArgI = $6->begin(), ArgE = $6->end();
+
+ std::vector<Value*> Args;
+ for (; ArgI != ArgE && I != E; ++ArgI, ++I) {
+ if ((*ArgI).V->getType() != *I)
+ error("Parameter " +(*ArgI).V->getName()+ " is not of type '" +
+ (*I)->getDescription() + "'");
+ Args.push_back((*ArgI).V);
+ }
+
+ if (I != E || (ArgI != ArgE && !Ty->isVarArg()))
+ error("Invalid number of parameters detected");
+
+ $$.TI = new InvokeInst(V, Normal, Except, &Args[0], Args.size());
+ }
+ cast<InvokeInst>($$.TI)->setCallingConv(upgradeCallingConv($2));
+ delete $3.PAT;
+ delete $6;
+ lastCallingConv = OldCallingConv::C;
+ }
+ | Unwind {
+ $$.TI = new UnwindInst();
+ $$.S.makeSignless();
+ }
+ | UNREACHABLE {
+ $$.TI = new UnreachableInst();
+ $$.S.makeSignless();
+ }
+ ;
+
+JumpTable
+ : JumpTable IntType ConstValueRef ',' LABEL ValueRef {
+ $$ = $1;
+ $3.S.copy($2.S);
+ Constant *V = cast<Constant>(getExistingValue($2.T, $3));
+
+ if (V == 0)
+ error("May only switch on a constant pool value");
+
+ $6.S.makeSignless();
+ BasicBlock* tmpBB = getBBVal($6);
+ $$->push_back(std::make_pair(V, tmpBB));
+ }
+ | IntType ConstValueRef ',' LABEL ValueRef {
+ $$ = new std::vector<std::pair<Constant*, BasicBlock*> >();
+ $2.S.copy($1.S);
+ Constant *V = cast<Constant>(getExistingValue($1.T, $2));
+
+ if (V == 0)
+ error("May only switch on a constant pool value");
+
+ $5.S.makeSignless();
+ BasicBlock* tmpBB = getBBVal($5);
+ $$->push_back(std::make_pair(V, tmpBB));
+ }
+ ;
+
+Inst
+ : OptAssign InstVal {
+ bool omit = false;
+ if ($1)
+ if (BitCastInst *BCI = dyn_cast<BitCastInst>($2.I))
+ if (BCI->getSrcTy() == BCI->getDestTy() &&
+ BCI->getOperand(0)->getName() == $1)
+ // This is a useless bit cast causing a name redefinition. It is
+ // a bit cast from a type to the same type of an operand with the
+ // same name as the name we would give this instruction. Since this
+ // instruction results in no code generation, it is safe to omit
+ // the instruction. This situation can occur because of collapsed
+ // type planes. For example:
+ // %X = add int %Y, %Z
+ // %X = cast int %Y to uint
+ // After upgrade, this looks like:
+ // %X = add i32 %Y, %Z
+ // %X = bitcast i32 to i32
+ // The bitcast is clearly useless so we omit it.
+ omit = true;
+ if (omit) {
+ $$.I = 0;
+ $$.S.makeSignless();
+ } else {
+ ValueInfo VI; VI.V = $2.I; VI.S.copy($2.S);
+ setValueName(VI, $1);
+ InsertValue($2.I);
+ $$ = $2;
+ }
+ };
+
+PHIList : Types '[' ValueRef ',' ValueRef ']' { // Used for PHI nodes
+ $$.P = new std::list<std::pair<Value*, BasicBlock*> >();
+ $$.S.copy($1.S);
+ $3.S.copy($1.S);
+ Value* tmpVal = getVal($1.PAT->get(), $3);
+ $5.S.makeSignless();
+ BasicBlock* tmpBB = getBBVal($5);
+ $$.P->push_back(std::make_pair(tmpVal, tmpBB));
+ delete $1.PAT;
+ }
+ | PHIList ',' '[' ValueRef ',' ValueRef ']' {
+ $$ = $1;
+ $4.S.copy($1.S);
+ Value* tmpVal = getVal($1.P->front().first->getType(), $4);
+ $6.S.makeSignless();
+ BasicBlock* tmpBB = getBBVal($6);
+ $1.P->push_back(std::make_pair(tmpVal, tmpBB));
+ }
+ ;
+
+ValueRefList : ResolvedVal { // Used for call statements, and memory insts...
+ $$ = new std::vector<ValueInfo>();
+ $$->push_back($1);
+ }
+ | ValueRefList ',' ResolvedVal {
+ $$ = $1;
+ $1->push_back($3);
+ };
+
+// ValueRefListE - Just like ValueRefList, except that it may also be empty!
+ValueRefListE
+ : ValueRefList
+ | /*empty*/ { $$ = 0; }
+ ;
+
+OptTailCall
+ : TAIL CALL {
+ $$ = true;
+ }
+ | CALL {
+ $$ = false;
+ }
+ ;
+
+InstVal
+ : ArithmeticOps Types ValueRef ',' ValueRef {
+ $3.S.copy($2.S);
+ $5.S.copy($2.S);
+ const Type* Ty = $2.PAT->get();
+ if (!Ty->isInteger() && !Ty->isFloatingPoint() && !isa<VectorType>(Ty))
+ error("Arithmetic operator requires integer, FP, or packed operands");
+ if (isa<VectorType>(Ty) &&
+ ($1 == URemOp || $1 == SRemOp || $1 == FRemOp || $1 == RemOp))
+ error("Remainder not supported on vector types");
+ // Upgrade the opcode from obsolete versions before we do anything with it.
+ Instruction::BinaryOps Opcode = getBinaryOp($1, Ty, $2.S);
+ Value* val1 = getVal(Ty, $3);
+ Value* val2 = getVal(Ty, $5);
+ $$.I = BinaryOperator::create(Opcode, val1, val2);
+ if ($$.I == 0)
+ error("binary operator returned null");
+ $$.S.copy($2.S);
+ delete $2.PAT;
+ }
+ | LogicalOps Types ValueRef ',' ValueRef {
+ $3.S.copy($2.S);
+ $5.S.copy($2.S);
+ const Type *Ty = $2.PAT->get();
+ if (!Ty->isInteger()) {
+ if (!isa<VectorType>(Ty) ||
+ !cast<VectorType>(Ty)->getElementType()->isInteger())
+ error("Logical operator requires integral operands");
+ }
+ Instruction::BinaryOps Opcode = getBinaryOp($1, Ty, $2.S);
+ Value* tmpVal1 = getVal(Ty, $3);
+ Value* tmpVal2 = getVal(Ty, $5);
+ $$.I = BinaryOperator::create(Opcode, tmpVal1, tmpVal2);
+ if ($$.I == 0)
+ error("binary operator returned null");
+ $$.S.copy($2.S);
+ delete $2.PAT;
+ }
+ | SetCondOps Types ValueRef ',' ValueRef {
+ $3.S.copy($2.S);
+ $5.S.copy($2.S);
+ const Type* Ty = $2.PAT->get();
+ if(isa<VectorType>(Ty))
+ error("VectorTypes currently not supported in setcc instructions");
+ unsigned short pred;
+ Instruction::OtherOps Opcode = getCompareOp($1, pred, Ty, $2.S);
+ Value* tmpVal1 = getVal(Ty, $3);
+ Value* tmpVal2 = getVal(Ty, $5);
+ $$.I = CmpInst::create(Opcode, pred, tmpVal1, tmpVal2);
+ if ($$.I == 0)
+ error("binary operator returned null");
+ $$.S.makeUnsigned();
+ delete $2.PAT;
+ }
+ | ICMP IPredicates Types ValueRef ',' ValueRef {
+ $4.S.copy($3.S);
+ $6.S.copy($3.S);
+ const Type *Ty = $3.PAT->get();
+ if (isa<VectorType>(Ty))
+ error("VectorTypes currently not supported in icmp instructions");
+ else if (!Ty->isInteger() && !isa<PointerType>(Ty))
+ error("icmp requires integer or pointer typed operands");
+ Value* tmpVal1 = getVal(Ty, $4);
+ Value* tmpVal2 = getVal(Ty, $6);
+ $$.I = new ICmpInst($2, tmpVal1, tmpVal2);
+ $$.S.makeUnsigned();
+ delete $3.PAT;
+ }
+ | FCMP FPredicates Types ValueRef ',' ValueRef {
+ $4.S.copy($3.S);
+ $6.S.copy($3.S);
+ const Type *Ty = $3.PAT->get();
+ if (isa<VectorType>(Ty))
+ error("VectorTypes currently not supported in fcmp instructions");
+ else if (!Ty->isFloatingPoint())
+ error("fcmp instruction requires floating point operands");
+ Value* tmpVal1 = getVal(Ty, $4);
+ Value* tmpVal2 = getVal(Ty, $6);
+ $$.I = new FCmpInst($2, tmpVal1, tmpVal2);
+ $$.S.makeUnsigned();
+ delete $3.PAT;
+ }
+ | NOT ResolvedVal {
+ warning("Use of obsolete 'not' instruction: Replacing with 'xor");
+ const Type *Ty = $2.V->getType();
+ Value *Ones = ConstantInt::getAllOnesValue(Ty);
+ if (Ones == 0)
+ error("Expected integral type for not instruction");
+ $$.I = BinaryOperator::create(Instruction::Xor, $2.V, Ones);
+ if ($$.I == 0)
+ error("Could not create a xor instruction");
+ $$.S.copy($2.S);
+ }
+ | ShiftOps ResolvedVal ',' ResolvedVal {
+ if (!$4.V->getType()->isInteger() ||
+ cast<IntegerType>($4.V->getType())->getBitWidth() != 8)
+ error("Shift amount must be int8");
+ const Type* Ty = $2.V->getType();
+ if (!Ty->isInteger())
+ error("Shift constant expression requires integer operand");
+ Value* ShiftAmt = 0;
+ if (cast<IntegerType>(Ty)->getBitWidth() > Type::Int8Ty->getBitWidth())
+ if (Constant *C = dyn_cast<Constant>($4.V))
+ ShiftAmt = ConstantExpr::getZExt(C, Ty);
+ else
+ ShiftAmt = new ZExtInst($4.V, Ty, makeNameUnique("shift"), CurBB);
+ else
+ ShiftAmt = $4.V;
+ $$.I = BinaryOperator::create(getBinaryOp($1, Ty, $2.S), $2.V, ShiftAmt);
+ $$.S.copy($2.S);
+ }
+ | CastOps ResolvedVal TO Types {
+ const Type *DstTy = $4.PAT->get();
+ if (!DstTy->isFirstClassType())
+ error("cast instruction to a non-primitive type: '" +
+ DstTy->getDescription() + "'");
+ $$.I = cast<Instruction>(getCast($1, $2.V, $2.S, DstTy, $4.S, true));
+ $$.S.copy($4.S);
+ delete $4.PAT;
+ }
+ | SELECT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
+ if (!$2.V->getType()->isInteger() ||
+ cast<IntegerType>($2.V->getType())->getBitWidth() != 1)
+ error("select condition must be bool");
+ if ($4.V->getType() != $6.V->getType())
+ error("select value types should match");
+ $$.I = new SelectInst($2.V, $4.V, $6.V);
+ $$.S.copy($4.S);
+ }
+ | VAARG ResolvedVal ',' Types {
+ const Type *Ty = $4.PAT->get();
+ NewVarArgs = true;
+ $$.I = new VAArgInst($2.V, Ty);
+ $$.S.copy($4.S);
+ delete $4.PAT;
+ }
+ | VAARG_old ResolvedVal ',' Types {
+ const Type* ArgTy = $2.V->getType();
+ const Type* DstTy = $4.PAT->get();
+ ObsoleteVarArgs = true;
+ Function* NF = cast<Function>(CurModule.CurrentModule->
+ getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, (Type *)0));
+
+ //b = vaarg a, t ->
+ //foo = alloca 1 of t
+ //bar = vacopy a
+ //store bar -> foo
+ //b = vaarg foo, t
+ AllocaInst* foo = new AllocaInst(ArgTy, 0, "vaarg.fix");
+ CurBB->getInstList().push_back(foo);
+ CallInst* bar = new CallInst(NF, $2.V);
+ CurBB->getInstList().push_back(bar);
+ CurBB->getInstList().push_back(new StoreInst(bar, foo));
+ $$.I = new VAArgInst(foo, DstTy);
+ $$.S.copy($4.S);
+ delete $4.PAT;
+ }
+ | VANEXT_old ResolvedVal ',' Types {
+ const Type* ArgTy = $2.V->getType();
+ const Type* DstTy = $4.PAT->get();
+ ObsoleteVarArgs = true;
+ Function* NF = cast<Function>(CurModule.CurrentModule->
+ getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, (Type *)0));
+
+ //b = vanext a, t ->
+ //foo = alloca 1 of t
+ //bar = vacopy a
+ //store bar -> foo
+ //tmp = vaarg foo, t
+ //b = load foo
+ AllocaInst* foo = new AllocaInst(ArgTy, 0, "vanext.fix");
+ CurBB->getInstList().push_back(foo);
+ CallInst* bar = new CallInst(NF, $2.V);
+ CurBB->getInstList().push_back(bar);
+ CurBB->getInstList().push_back(new StoreInst(bar, foo));
+ Instruction* tmp = new VAArgInst(foo, DstTy);
+ CurBB->getInstList().push_back(tmp);
+ $$.I = new LoadInst(foo);
+ $$.S.copy($4.S);
+ delete $4.PAT;
+ }
+ | EXTRACTELEMENT ResolvedVal ',' ResolvedVal {
+ if (!ExtractElementInst::isValidOperands($2.V, $4.V))
+ error("Invalid extractelement operands");
+ $$.I = new ExtractElementInst($2.V, $4.V);
+ $$.S.copy($2.S.get(0));
+ }
+ | INSERTELEMENT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
+ if (!InsertElementInst::isValidOperands($2.V, $4.V, $6.V))
+ error("Invalid insertelement operands");
+ $$.I = new InsertElementInst($2.V, $4.V, $6.V);
+ $$.S.copy($2.S);
+ }
+ | SHUFFLEVECTOR ResolvedVal ',' ResolvedVal ',' ResolvedVal {
+ if (!ShuffleVectorInst::isValidOperands($2.V, $4.V, $6.V))
+ error("Invalid shufflevector operands");
+ $$.I = new ShuffleVectorInst($2.V, $4.V, $6.V);
+ $$.S.copy($2.S);
+ }
+ | PHI_TOK PHIList {
+ const Type *Ty = $2.P->front().first->getType();
+ if (!Ty->isFirstClassType())
+ error("PHI node operands must be of first class type");
+ PHINode *PHI = new PHINode(Ty);
+ PHI->reserveOperandSpace($2.P->size());
+ while ($2.P->begin() != $2.P->end()) {
+ if ($2.P->front().first->getType() != Ty)
+ error("All elements of a PHI node must be of the same type");
+ PHI->addIncoming($2.P->front().first, $2.P->front().second);
+ $2.P->pop_front();
+ }
+ $$.I = PHI;
+ $$.S.copy($2.S);
+ delete $2.P; // Free the list...
+ }
+ | OptTailCall OptCallingConv TypesV ValueRef '(' ValueRefListE ')' {
+ // Handle the short call syntax
+ const PointerType *PFTy;
+ const FunctionType *FTy;
+ Signedness FTySign;
+ if (!(PFTy = dyn_cast<PointerType>($3.PAT->get())) ||
+ !(FTy = dyn_cast<FunctionType>(PFTy->getElementType()))) {
+ // Pull out the types of all of the arguments...
+ std::vector<const Type*> ParamTypes;
+ FTySign.makeComposite($3.S);
+ if ($6) {
+ for (std::vector<ValueInfo>::iterator I = $6->begin(), E = $6->end();
+ I != E; ++I) {
+ ParamTypes.push_back((*I).V->getType());
+ FTySign.add(I->S);
+ }
+ }
+
+ bool isVarArg = ParamTypes.size() && ParamTypes.back() == Type::VoidTy;
+ if (isVarArg) ParamTypes.pop_back();
+
+ const Type *RetTy = $3.PAT->get();
+ if (!RetTy->isFirstClassType() && RetTy != Type::VoidTy)
+ error("Functions cannot return aggregate types");
+
+ // Deal with CSRetCC
+ ParamAttrsList *PAL = 0;
+ if ($2 == OldCallingConv::CSRet) {
+ ParamAttrsVector Attrs;
+ ParamAttrsWithIndex PAWI;
+ PAWI.index = 1; PAWI.attrs = ParamAttr::StructRet; // first arg
+ Attrs.push_back(PAWI);
+ PAL = ParamAttrsList::get(Attrs);
+ }
+
+ FTy = FunctionType::get(RetTy, ParamTypes, isVarArg, PAL);
+ PFTy = PointerType::get(FTy);
+ $$.S.copy($3.S);
+ } else {
+ FTySign = $3.S;
+ // Get the signedness of the result type. $3 is the pointer to the
+ // function type so we get the 0th element to extract the function type,
+ // and then the 0th element again to get the result type.
+ $$.S.copy($3.S.get(0).get(0));
+ }
+ $4.S.makeComposite(FTySign);
+
+ // First upgrade any intrinsic calls.
+ std::vector<Value*> Args;
+ if ($6)
+ for (unsigned i = 0, e = $6->size(); i < e; ++i)
+ Args.push_back((*$6)[i].V);
+ Instruction *Inst = upgradeIntrinsicCall(FTy->getReturnType(), $4, Args);
+
+ // If we got an upgraded intrinsic
+ if (Inst) {
+ $$.I = Inst;
+ } else {
+ // Get the function we're calling
+ Value *V = getVal(PFTy, $4);
+
+ // Check the argument values match
+ if (!$6) { // Has no arguments?
+ // Make sure no arguments is a good thing!
+ if (FTy->getNumParams() != 0)
+ error("No arguments passed to a function that expects arguments");
+ } else { // Has arguments?
+ // Loop through FunctionType's arguments and ensure they are specified
+ // correctly!
+ //
+ FunctionType::param_iterator I = FTy->param_begin();
+ FunctionType::param_iterator E = FTy->param_end();
+ std::vector<ValueInfo>::iterator ArgI = $6->begin(), ArgE = $6->end();
+
+ for (; ArgI != ArgE && I != E; ++ArgI, ++I)
+ if ((*ArgI).V->getType() != *I)
+ error("Parameter " +(*ArgI).V->getName()+ " is not of type '" +
+ (*I)->getDescription() + "'");
+
+ if (I != E || (ArgI != ArgE && !FTy->isVarArg()))
+ error("Invalid number of parameters detected");
+ }
+
+ // Create the call instruction
+ CallInst *CI = new CallInst(V, &Args[0], Args.size());
+ CI->setTailCall($1);
+ CI->setCallingConv(upgradeCallingConv($2));
+ $$.I = CI;
+ }
+ delete $3.PAT;
+ delete $6;
+ lastCallingConv = OldCallingConv::C;
+ }
+ | MemoryInst {
+ $$ = $1;
+ }
+ ;
+
+
+// IndexList - List of indices for GEP based instructions...
+IndexList
+ : ',' ValueRefList { $$ = $2; }
+ | /* empty */ { $$ = new std::vector<ValueInfo>(); }
+ ;
+
+OptVolatile
+ : VOLATILE { $$ = true; }
+ | /* empty */ { $$ = false; }
+ ;
+
+MemoryInst
+ : MALLOC Types OptCAlign {
+ const Type *Ty = $2.PAT->get();
+ $$.S.makeComposite($2.S);
+ $$.I = new MallocInst(Ty, 0, $3);
+ delete $2.PAT;
+ }
+ | MALLOC Types ',' UINT ValueRef OptCAlign {
+ const Type *Ty = $2.PAT->get();
+ $5.S.makeUnsigned();
+ $$.S.makeComposite($2.S);
+ $$.I = new MallocInst(Ty, getVal($4.T, $5), $6);
+ delete $2.PAT;
+ }
+ | ALLOCA Types OptCAlign {
+ const Type *Ty = $2.PAT->get();
+ $$.S.makeComposite($2.S);
+ $$.I = new AllocaInst(Ty, 0, $3);
+ delete $2.PAT;
+ }
+ | ALLOCA Types ',' UINT ValueRef OptCAlign {
+ const Type *Ty = $2.PAT->get();
+ $5.S.makeUnsigned();
+ $$.S.makeComposite($4.S);
+ $$.I = new AllocaInst(Ty, getVal($4.T, $5), $6);
+ delete $2.PAT;
+ }
+ | FREE ResolvedVal {
+ const Type *PTy = $2.V->getType();
+ if (!isa<PointerType>(PTy))
+ error("Trying to free nonpointer type '" + PTy->getDescription() + "'");
+ $$.I = new FreeInst($2.V);
+ $$.S.makeSignless();
+ }
+ | OptVolatile LOAD Types ValueRef {
+ const Type* Ty = $3.PAT->get();
+ $4.S.copy($3.S);
+ if (!isa<PointerType>(Ty))
+ error("Can't load from nonpointer type: " + Ty->getDescription());
+ if (!cast<PointerType>(Ty)->getElementType()->isFirstClassType())
+ error("Can't load from pointer of non-first-class type: " +
+ Ty->getDescription());
+ Value* tmpVal = getVal(Ty, $4);
+ $$.I = new LoadInst(tmpVal, "", $1);
+ $$.S.copy($3.S.get(0));
+ delete $3.PAT;
+ }
+ | OptVolatile STORE ResolvedVal ',' Types ValueRef {
+ $6.S.copy($5.S);
+ const PointerType *PTy = dyn_cast<PointerType>($5.PAT->get());
+ if (!PTy)
+ error("Can't store to a nonpointer type: " +
+ $5.PAT->get()->getDescription());
+ const Type *ElTy = PTy->getElementType();
+ Value *StoreVal = $3.V;
+ Value* tmpVal = getVal(PTy, $6);
+ if (ElTy != $3.V->getType()) {
+ StoreVal = handleSRetFuncTypeMerge($3.V, ElTy);
+ if (!StoreVal)
+ error("Can't store '" + $3.V->getType()->getDescription() +
+ "' into space of type '" + ElTy->getDescription() + "'");
+ else {
+ PTy = PointerType::get(StoreVal->getType());
+ if (Constant *C = dyn_cast<Constant>(tmpVal))
+ tmpVal = ConstantExpr::getBitCast(C, PTy);
+ else
+ tmpVal = new BitCastInst(tmpVal, PTy, "upgrd.cast", CurBB);
+ }
+ }
+ $$.I = new StoreInst(StoreVal, tmpVal, $1);
+ $$.S.makeSignless();
+ delete $5.PAT;
+ }
+ | GETELEMENTPTR Types ValueRef IndexList {
+ $3.S.copy($2.S);
+ const Type* Ty = $2.PAT->get();
+ if (!isa<PointerType>(Ty))
+ error("getelementptr insn requires pointer operand");
+
+ std::vector<Value*> VIndices;
+ upgradeGEPInstIndices(Ty, $4, VIndices);
+
+ Value* tmpVal = getVal(Ty, $3);
+ $$.I = new GetElementPtrInst(tmpVal, &VIndices[0], VIndices.size());
+ ValueInfo VI; VI.V = tmpVal; VI.S.copy($2.S);
+ $$.S.copy(getElementSign(VI, VIndices));
+ delete $2.PAT;
+ delete $4;
+ };
+
+
+%%
+
+int yyerror(const char *ErrorMsg) {
+ std::string where
+ = std::string((CurFilename == "-") ? std::string("<stdin>") : CurFilename)
+ + ":" + llvm::utostr((unsigned) Upgradelineno) + ": ";
+ std::string errMsg = where + "error: " + std::string(ErrorMsg);
+ if (yychar != YYEMPTY && yychar != 0)
+ errMsg += " while reading token '" + std::string(Upgradetext, Upgradeleng) +
+ "'.";
+ std::cerr << "llvm-upgrade: " << errMsg << '\n';
+ std::cout << "llvm-upgrade: parse failed.\n";
+ exit(1);
+}
+
+void warning(const std::string& ErrorMsg) {
+ std::string where
+ = std::string((CurFilename == "-") ? std::string("<stdin>") : CurFilename)
+ + ":" + llvm::utostr((unsigned) Upgradelineno) + ": ";
+ std::string errMsg = where + "warning: " + std::string(ErrorMsg);
+ if (yychar != YYEMPTY && yychar != 0)
+ errMsg += " while reading token '" + std::string(Upgradetext, Upgradeleng) +
+ "'.";
+ std::cerr << "llvm-upgrade: " << errMsg << '\n';
+}
+
+void error(const std::string& ErrorMsg, int LineNo) {
+ if (LineNo == -1) LineNo = Upgradelineno;
+ Upgradelineno = LineNo;
+ yyerror(ErrorMsg.c_str());
+}
+
diff --git a/tools/llvm-upgrade/UpgradeParser.y.cvs b/tools/llvm-upgrade/UpgradeParser.y.cvs
new file mode 100644
index 0000000..ed84267
--- /dev/null
+++ b/tools/llvm-upgrade/UpgradeParser.y.cvs
@@ -0,0 +1,3957 @@
+//===-- llvmAsmParser.y - Parser for llvm assembly files --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the bison parser for LLVM assembly languages files.
+//
+//===----------------------------------------------------------------------===//
+
+%{
+#include "UpgradeInternals.h"
+#include "llvm/CallingConv.h"
+#include "llvm/InlineAsm.h"
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+#include "llvm/ParameterAttributes.h"
+#include "llvm/ValueSymbolTable.h"
+#include "llvm/Support/GetElementPtrTypeIterator.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/MathExtras.h"
+#include <algorithm>
+#include <iostream>
+#include <map>
+#include <list>
+#include <utility>
+
+// DEBUG_UPREFS - Define this symbol if you want to enable debugging output
+// relating to upreferences in the input stream.
+//
+//#define DEBUG_UPREFS 1
+#ifdef DEBUG_UPREFS
+#define UR_OUT(X) std::cerr << X
+#else
+#define UR_OUT(X)
+#endif
+
+#define YYERROR_VERBOSE 1
+#define YYINCLUDED_STDLIB_H
+#define YYDEBUG 1
+
+int yylex();
+int yyparse();
+
+int yyerror(const char*);
+static void warning(const std::string& WarningMsg);
+
+namespace llvm {
+
+std::istream* LexInput;
+static std::string CurFilename;
+
+// This bool controls whether attributes are ever added to function declarations
+// definitions and calls.
+static bool AddAttributes = false;
+
+static Module *ParserResult;
+static bool ObsoleteVarArgs;
+static bool NewVarArgs;
+static BasicBlock *CurBB;
+static GlobalVariable *CurGV;
+static unsigned lastCallingConv;
+
+// This contains info used when building the body of a function. It is
+// destroyed when the function is completed.
+//
+typedef std::vector<Value *> ValueList; // Numbered defs
+
+typedef std::pair<std::string,TypeInfo> RenameMapKey;
+typedef std::map<RenameMapKey,std::string> RenameMapType;
+
+static void
+ResolveDefinitions(std::map<const Type *,ValueList> &LateResolvers,
+ std::map<const Type *,ValueList> *FutureLateResolvers = 0);
+
+static struct PerModuleInfo {
+ Module *CurrentModule;
+ std::map<const Type *, ValueList> Values; // Module level numbered definitions
+ std::map<const Type *,ValueList> LateResolveValues;
+ std::vector<PATypeHolder> Types;
+ std::vector<Signedness> TypeSigns;
+ std::map<std::string,Signedness> NamedTypeSigns;
+ std::map<std::string,Signedness> NamedValueSigns;
+ std::map<ValID, PATypeHolder> LateResolveTypes;
+ static Module::Endianness Endian;
+ static Module::PointerSize PointerSize;
+ RenameMapType RenameMap;
+
+ /// PlaceHolderInfo - When temporary placeholder objects are created, remember
+ /// how they were referenced and on which line of the input they came from so
+ /// that we can resolve them later and print error messages as appropriate.
+ std::map<Value*, std::pair<ValID, int> > PlaceHolderInfo;
+
+ // GlobalRefs - This maintains a mapping between <Type, ValID>'s and forward
+ // references to global values. Global values may be referenced before they
+ // are defined, and if so, the temporary object that they represent is held
+ // here. This is used for forward references of GlobalValues.
+ //
+ typedef std::map<std::pair<const PointerType *, ValID>, GlobalValue*>
+ GlobalRefsType;
+ GlobalRefsType GlobalRefs;
+
+ void ModuleDone() {
+ // If we could not resolve some functions at function compilation time
+ // (calls to functions before they are defined), resolve them now... Types
+ // are resolved when the constant pool has been completely parsed.
+ //
+ ResolveDefinitions(LateResolveValues);
+
+ // Check to make sure that all global value forward references have been
+ // resolved!
+ //
+ if (!GlobalRefs.empty()) {
+ std::string UndefinedReferences = "Unresolved global references exist:\n";
+
+ for (GlobalRefsType::iterator I = GlobalRefs.begin(), E =GlobalRefs.end();
+ I != E; ++I) {
+ UndefinedReferences += " " + I->first.first->getDescription() + " " +
+ I->first.second.getName() + "\n";
+ }
+ error(UndefinedReferences);
+ return;
+ }
+
+ if (CurrentModule->getDataLayout().empty()) {
+ std::string dataLayout;
+ if (Endian != Module::AnyEndianness)
+ dataLayout.append(Endian == Module::BigEndian ? "E" : "e");
+ if (PointerSize != Module::AnyPointerSize) {
+ if (!dataLayout.empty())
+ dataLayout += "-";
+ dataLayout.append(PointerSize == Module::Pointer64 ?
+ "p:64:64" : "p:32:32");
+ }
+ CurrentModule->setDataLayout(dataLayout);
+ }
+
+ Values.clear(); // Clear out function local definitions
+ Types.clear();
+ TypeSigns.clear();
+ NamedTypeSigns.clear();
+ NamedValueSigns.clear();
+ CurrentModule = 0;
+ }
+
+ // GetForwardRefForGlobal - Check to see if there is a forward reference
+ // for this global. If so, remove it from the GlobalRefs map and return it.
+ // If not, just return null.
+ GlobalValue *GetForwardRefForGlobal(const PointerType *PTy, ValID ID) {
+ // Check to see if there is a forward reference to this global variable...
+ // if there is, eliminate it and patch the reference to use the new def'n.
+ GlobalRefsType::iterator I = GlobalRefs.find(std::make_pair(PTy, ID));
+ GlobalValue *Ret = 0;
+ if (I != GlobalRefs.end()) {
+ Ret = I->second;
+ GlobalRefs.erase(I);
+ }
+ return Ret;
+ }
+ void setEndianness(Module::Endianness E) { Endian = E; }
+ void setPointerSize(Module::PointerSize sz) { PointerSize = sz; }
+} CurModule;
+
+Module::Endianness PerModuleInfo::Endian = Module::AnyEndianness;
+Module::PointerSize PerModuleInfo::PointerSize = Module::AnyPointerSize;
+
+static struct PerFunctionInfo {
+ Function *CurrentFunction; // Pointer to current function being created
+
+ std::map<const Type*, ValueList> Values; // Keep track of #'d definitions
+ std::map<const Type*, ValueList> LateResolveValues;
+ bool isDeclare; // Is this function a forward declararation?
+ GlobalValue::LinkageTypes Linkage;// Linkage for forward declaration.
+
+ /// BBForwardRefs - When we see forward references to basic blocks, keep
+ /// track of them here.
+ std::map<BasicBlock*, std::pair<ValID, int> > BBForwardRefs;
+ std::vector<BasicBlock*> NumberedBlocks;
+ RenameMapType RenameMap;
+ unsigned NextBBNum;
+
+ inline PerFunctionInfo() {
+ CurrentFunction = 0;
+ isDeclare = false;
+ Linkage = GlobalValue::ExternalLinkage;
+ }
+
+ inline void FunctionStart(Function *M) {
+ CurrentFunction = M;
+ NextBBNum = 0;
+ }
+
+ void FunctionDone() {
+ NumberedBlocks.clear();
+
+ // Any forward referenced blocks left?
+ if (!BBForwardRefs.empty()) {
+ error("Undefined reference to label " +
+ BBForwardRefs.begin()->first->getName());
+ return;
+ }
+
+ // Resolve all forward references now.
+ ResolveDefinitions(LateResolveValues, &CurModule.LateResolveValues);
+
+ Values.clear(); // Clear out function local definitions
+ RenameMap.clear();
+ CurrentFunction = 0;
+ isDeclare = false;
+ Linkage = GlobalValue::ExternalLinkage;
+ }
+} CurFun; // Info for the current function...
+
+static bool inFunctionScope() { return CurFun.CurrentFunction != 0; }
+
+/// This function is just a utility to make a Key value for the rename map.
+/// The Key is a combination of the name, type, Signedness of the original
+/// value (global/function). This just constructs the key and ensures that
+/// named Signedness values are resolved to the actual Signedness.
+/// @brief Make a key for the RenameMaps
+static RenameMapKey makeRenameMapKey(const std::string &Name, const Type* Ty,
+ const Signedness &Sign) {
+ TypeInfo TI;
+ TI.T = Ty;
+ if (Sign.isNamed())
+ // Don't allow Named Signedness nodes because they won't match. The actual
+ // Signedness must be looked up in the NamedTypeSigns map.
+ TI.S.copy(CurModule.NamedTypeSigns[Sign.getName()]);
+ else
+ TI.S.copy(Sign);
+ return std::make_pair(Name, TI);
+}
+
+
+//===----------------------------------------------------------------------===//
+// Code to handle definitions of all the types
+//===----------------------------------------------------------------------===//
+
+static int InsertValue(Value *V,
+ std::map<const Type*,ValueList> &ValueTab = CurFun.Values) {
+ if (V->hasName()) return -1; // Is this a numbered definition?
+
+ // Yes, insert the value into the value table...
+ ValueList &List = ValueTab[V->getType()];
+ List.push_back(V);
+ return List.size()-1;
+}
+
+static const Type *getType(const ValID &D, bool DoNotImprovise = false) {
+ switch (D.Type) {
+ case ValID::NumberVal: // Is it a numbered definition?
+ // Module constants occupy the lowest numbered slots...
+ if ((unsigned)D.Num < CurModule.Types.size()) {
+ return CurModule.Types[(unsigned)D.Num];
+ }
+ break;
+ case ValID::NameVal: // Is it a named definition?
+ if (const Type *N = CurModule.CurrentModule->getTypeByName(D.Name)) {
+ return N;
+ }
+ break;
+ default:
+ error("Internal parser error: Invalid symbol type reference");
+ return 0;
+ }
+
+ // If we reached here, we referenced either a symbol that we don't know about
+ // or an id number that hasn't been read yet. We may be referencing something
+ // forward, so just create an entry to be resolved later and get to it...
+ //
+ if (DoNotImprovise) return 0; // Do we just want a null to be returned?
+
+ if (inFunctionScope()) {
+ if (D.Type == ValID::NameVal) {
+ error("Reference to an undefined type: '" + D.getName() + "'");
+ return 0;
+ } else {
+ error("Reference to an undefined type: #" + itostr(D.Num));
+ return 0;
+ }
+ }
+
+ std::map<ValID, PATypeHolder>::iterator I =CurModule.LateResolveTypes.find(D);
+ if (I != CurModule.LateResolveTypes.end())
+ return I->second;
+
+ Type *Typ = OpaqueType::get();
+ CurModule.LateResolveTypes.insert(std::make_pair(D, Typ));
+ return Typ;
+}
+
+/// This is like the getType method except that instead of looking up the type
+/// for a given ID, it looks up that type's sign.
+/// @brief Get the signedness of a referenced type
+static Signedness getTypeSign(const ValID &D) {
+ switch (D.Type) {
+ case ValID::NumberVal: // Is it a numbered definition?
+ // Module constants occupy the lowest numbered slots...
+ if ((unsigned)D.Num < CurModule.TypeSigns.size()) {
+ return CurModule.TypeSigns[(unsigned)D.Num];
+ }
+ break;
+ case ValID::NameVal: { // Is it a named definition?
+ std::map<std::string,Signedness>::const_iterator I =
+ CurModule.NamedTypeSigns.find(D.Name);
+ if (I != CurModule.NamedTypeSigns.end())
+ return I->second;
+ // Perhaps its a named forward .. just cache the name
+ Signedness S;
+ S.makeNamed(D.Name);
+ return S;
+ }
+ default:
+ break;
+ }
+ // If we don't find it, its signless
+ Signedness S;
+ S.makeSignless();
+ return S;
+}
+
+/// This function is analagous to getElementType in LLVM. It provides the same
+/// function except that it looks up the Signedness instead of the type. This is
+/// used when processing GEP instructions that need to extract the type of an
+/// indexed struct/array/ptr member.
+/// @brief Look up an element's sign.
+static Signedness getElementSign(const ValueInfo& VI,
+ const std::vector<Value*> &Indices) {
+ const Type *Ptr = VI.V->getType();
+ assert(isa<PointerType>(Ptr) && "Need pointer type");
+
+ unsigned CurIdx = 0;
+ Signedness S(VI.S);
+ while (const CompositeType *CT = dyn_cast<CompositeType>(Ptr)) {
+ if (CurIdx == Indices.size())
+ break;
+
+ Value *Index = Indices[CurIdx++];
+ assert(!isa<PointerType>(CT) || CurIdx == 1 && "Invalid type");
+ Ptr = CT->getTypeAtIndex(Index);
+ if (const Type* Ty = Ptr->getForwardedType())
+ Ptr = Ty;
+ assert(S.isComposite() && "Bad Signedness type");
+ if (isa<StructType>(CT)) {
+ S = S.get(cast<ConstantInt>(Index)->getZExtValue());
+ } else {
+ S = S.get(0UL);
+ }
+ if (S.isNamed())
+ S = CurModule.NamedTypeSigns[S.getName()];
+ }
+ Signedness Result;
+ Result.makeComposite(S);
+ return Result;
+}
+
+/// This function just translates a ConstantInfo into a ValueInfo and calls
+/// getElementSign(ValueInfo,...). Its just a convenience.
+/// @brief ConstantInfo version of getElementSign.
+static Signedness getElementSign(const ConstInfo& CI,
+ const std::vector<Constant*> &Indices) {
+ ValueInfo VI;
+ VI.V = CI.C;
+ VI.S.copy(CI.S);
+ std::vector<Value*> Idx;
+ for (unsigned i = 0; i < Indices.size(); ++i)
+ Idx.push_back(Indices[i]);
+ Signedness result = getElementSign(VI, Idx);
+ VI.destroy();
+ return result;
+}
+
+/// This function determines if two function types differ only in their use of
+/// the sret parameter attribute in the first argument. If they are identical
+/// in all other respects, it returns true. Otherwise, it returns false.
+static bool FuncTysDifferOnlyBySRet(const FunctionType *F1,
+ const FunctionType *F2) {
+ if (F1->getReturnType() != F2->getReturnType() ||
+ F1->getNumParams() != F2->getNumParams())
+ return false;
+ const ParamAttrsList *PAL1 = F1->getParamAttrs();
+ const ParamAttrsList *PAL2 = F2->getParamAttrs();
+ if (PAL1 && !PAL2 || PAL2 && !PAL1)
+ return false;
+ if (PAL1 && PAL2 && ((PAL1->size() != PAL2->size()) ||
+ (PAL1->getParamAttrs(0) != PAL2->getParamAttrs(0))))
+ return false;
+ unsigned SRetMask = ~unsigned(ParamAttr::StructRet);
+ for (unsigned i = 0; i < F1->getNumParams(); ++i) {
+ if (F1->getParamType(i) != F2->getParamType(i) || (PAL1 && PAL2 &&
+ (unsigned(PAL1->getParamAttrs(i+1)) & SRetMask !=
+ unsigned(PAL2->getParamAttrs(i+1)) & SRetMask)))
+ return false;
+ }
+ return true;
+}
+
+/// This function determines if the type of V and Ty differ only by the SRet
+/// parameter attribute. This is a more generalized case of
+/// FuncTysDIfferOnlyBySRet since it doesn't require FunctionType arguments.
+static bool TypesDifferOnlyBySRet(Value *V, const Type* Ty) {
+ if (V->getType() == Ty)
+ return true;
+ const PointerType *PF1 = dyn_cast<PointerType>(Ty);
+ const PointerType *PF2 = dyn_cast<PointerType>(V->getType());
+ if (PF1 && PF2) {
+ const FunctionType* FT1 = dyn_cast<FunctionType>(PF1->getElementType());
+ const FunctionType* FT2 = dyn_cast<FunctionType>(PF2->getElementType());
+ if (FT1 && FT2)
+ return FuncTysDifferOnlyBySRet(FT1, FT2);
+ }
+ return false;
+}
+
+// The upgrade of csretcc to sret param attribute may have caused a function
+// to not be found because the param attribute changed the type of the called
+// function. This helper function, used in getExistingValue, detects that
+// situation and bitcasts the function to the correct type.
+static Value* handleSRetFuncTypeMerge(Value *V, const Type* Ty) {
+ // Handle degenerate cases
+ if (!V)
+ return 0;
+ if (V->getType() == Ty)
+ return V;
+
+ const PointerType *PF1 = dyn_cast<PointerType>(Ty);
+ const PointerType *PF2 = dyn_cast<PointerType>(V->getType());
+ if (PF1 && PF2) {
+ const FunctionType *FT1 = dyn_cast<FunctionType>(PF1->getElementType());
+ const FunctionType *FT2 = dyn_cast<FunctionType>(PF2->getElementType());
+ if (FT1 && FT2 && FuncTysDifferOnlyBySRet(FT1, FT2)) {
+ const ParamAttrsList *PAL2 = FT2->getParamAttrs();
+ if (PAL2 && PAL2->paramHasAttr(1, ParamAttr::StructRet))
+ return V;
+ else if (Constant *C = dyn_cast<Constant>(V))
+ return ConstantExpr::getBitCast(C, PF1);
+ else
+ return new BitCastInst(V, PF1, "upgrd.cast", CurBB);
+ }
+
+ }
+ return 0;
+}
+
+// getExistingValue - Look up the value specified by the provided type and
+// the provided ValID. If the value exists and has already been defined, return
+// it. Otherwise return null.
+//
+static Value *getExistingValue(const Type *Ty, const ValID &D) {
+ if (isa<FunctionType>(Ty)) {
+ error("Functions are not values and must be referenced as pointers");
+ }
+
+ switch (D.Type) {
+ case ValID::NumberVal: { // Is it a numbered definition?
+ unsigned Num = (unsigned)D.Num;
+
+ // Module constants occupy the lowest numbered slots...
+ std::map<const Type*,ValueList>::iterator VI = CurModule.Values.find(Ty);
+ if (VI != CurModule.Values.end()) {
+ if (Num < VI->second.size())
+ return VI->second[Num];
+ Num -= VI->second.size();
+ }
+
+ // Make sure that our type is within bounds
+ VI = CurFun.Values.find(Ty);
+ if (VI == CurFun.Values.end()) return 0;
+
+ // Check that the number is within bounds...
+ if (VI->second.size() <= Num) return 0;
+
+ return VI->second[Num];
+ }
+
+ case ValID::NameVal: { // Is it a named definition?
+ // Get the name out of the ID
+ RenameMapKey Key = makeRenameMapKey(D.Name, Ty, D.S);
+ Value *V = 0;
+ if (inFunctionScope()) {
+ // See if the name was renamed
+ RenameMapType::const_iterator I = CurFun.RenameMap.find(Key);
+ std::string LookupName;
+ if (I != CurFun.RenameMap.end())
+ LookupName = I->second;
+ else
+ LookupName = D.Name;
+ ValueSymbolTable &SymTab = CurFun.CurrentFunction->getValueSymbolTable();
+ V = SymTab.lookup(LookupName);
+ if (V && V->getType() != Ty)
+ V = handleSRetFuncTypeMerge(V, Ty);
+ assert((!V || TypesDifferOnlyBySRet(V, Ty)) && "Found wrong type");
+ }
+ if (!V) {
+ RenameMapType::const_iterator I = CurModule.RenameMap.find(Key);
+ std::string LookupName;
+ if (I != CurModule.RenameMap.end())
+ LookupName = I->second;
+ else
+ LookupName = D.Name;
+ V = CurModule.CurrentModule->getValueSymbolTable().lookup(LookupName);
+ if (V && V->getType() != Ty)
+ V = handleSRetFuncTypeMerge(V, Ty);
+ assert((!V || TypesDifferOnlyBySRet(V, Ty)) && "Found wrong type");
+ }
+ if (!V)
+ return 0;
+
+ D.destroy(); // Free old strdup'd memory...
+ return V;
+ }
+
+ // Check to make sure that "Ty" is an integral type, and that our
+ // value will fit into the specified type...
+ case ValID::ConstSIntVal: // Is it a constant pool reference??
+ if (!ConstantInt::isValueValidForType(Ty, D.ConstPool64)) {
+ error("Signed integral constant '" + itostr(D.ConstPool64) +
+ "' is invalid for type '" + Ty->getDescription() + "'");
+ }
+ return ConstantInt::get(Ty, D.ConstPool64);
+
+ case ValID::ConstUIntVal: // Is it an unsigned const pool reference?
+ if (!ConstantInt::isValueValidForType(Ty, D.UConstPool64)) {
+ if (!ConstantInt::isValueValidForType(Ty, D.ConstPool64))
+ error("Integral constant '" + utostr(D.UConstPool64) +
+ "' is invalid or out of range");
+ else // This is really a signed reference. Transmogrify.
+ return ConstantInt::get(Ty, D.ConstPool64);
+ } else
+ return ConstantInt::get(Ty, D.UConstPool64);
+
+ case ValID::ConstFPVal: // Is it a floating point const pool reference?
+ if (!ConstantFP::isValueValidForType(Ty, D.ConstPoolFP))
+ error("FP constant invalid for type");
+ return ConstantFP::get(Ty, D.ConstPoolFP);
+
+ case ValID::ConstNullVal: // Is it a null value?
+ if (!isa<PointerType>(Ty))
+ error("Cannot create a a non pointer null");
+ return ConstantPointerNull::get(cast<PointerType>(Ty));
+
+ case ValID::ConstUndefVal: // Is it an undef value?
+ return UndefValue::get(Ty);
+
+ case ValID::ConstZeroVal: // Is it a zero value?
+ return Constant::getNullValue(Ty);
+
+ case ValID::ConstantVal: // Fully resolved constant?
+ if (D.ConstantValue->getType() != Ty)
+ error("Constant expression type different from required type");
+ return D.ConstantValue;
+
+ case ValID::InlineAsmVal: { // Inline asm expression
+ const PointerType *PTy = dyn_cast<PointerType>(Ty);
+ const FunctionType *FTy =
+ PTy ? dyn_cast<FunctionType>(PTy->getElementType()) : 0;
+ if (!FTy || !InlineAsm::Verify(FTy, D.IAD->Constraints))
+ error("Invalid type for asm constraint string");
+ InlineAsm *IA = InlineAsm::get(FTy, D.IAD->AsmString, D.IAD->Constraints,
+ D.IAD->HasSideEffects);
+ D.destroy(); // Free InlineAsmDescriptor.
+ return IA;
+ }
+ default:
+ assert(0 && "Unhandled case");
+ return 0;
+ } // End of switch
+
+ assert(0 && "Unhandled case");
+ return 0;
+}
+
+// getVal - This function is identical to getExistingValue, except that if a
+// value is not already defined, it "improvises" by creating a placeholder var
+// that looks and acts just like the requested variable. When the value is
+// defined later, all uses of the placeholder variable are replaced with the
+// real thing.
+//
+static Value *getVal(const Type *Ty, const ValID &ID) {
+ if (Ty == Type::LabelTy)
+ error("Cannot use a basic block here");
+
+ // See if the value has already been defined.
+ Value *V = getExistingValue(Ty, ID);
+ if (V) return V;
+
+ if (!Ty->isFirstClassType() && !isa<OpaqueType>(Ty))
+ error("Invalid use of a composite type");
+
+ // If we reached here, we referenced either a symbol that we don't know about
+ // or an id number that hasn't been read yet. We may be referencing something
+ // forward, so just create an entry to be resolved later and get to it...
+ V = new Argument(Ty);
+
+ // Remember where this forward reference came from. FIXME, shouldn't we try
+ // to recycle these things??
+ CurModule.PlaceHolderInfo.insert(
+ std::make_pair(V, std::make_pair(ID, Upgradelineno)));
+
+ if (inFunctionScope())
+ InsertValue(V, CurFun.LateResolveValues);
+ else
+ InsertValue(V, CurModule.LateResolveValues);
+ return V;
+}
+
+/// @brief This just makes any name given to it unique, up to MAX_UINT times.
+static std::string makeNameUnique(const std::string& Name) {
+ static unsigned UniqueNameCounter = 1;
+ std::string Result(Name);
+ Result += ".upgrd." + llvm::utostr(UniqueNameCounter++);
+ return Result;
+}
+
+/// getBBVal - This is used for two purposes:
+/// * If isDefinition is true, a new basic block with the specified ID is being
+/// defined.
+/// * If isDefinition is true, this is a reference to a basic block, which may
+/// or may not be a forward reference.
+///
+static BasicBlock *getBBVal(const ValID &ID, bool isDefinition = false) {
+ assert(inFunctionScope() && "Can't get basic block at global scope");
+
+ std::string Name;
+ BasicBlock *BB = 0;
+ switch (ID.Type) {
+ default:
+ error("Illegal label reference " + ID.getName());
+ break;
+ case ValID::NumberVal: // Is it a numbered definition?
+ if (unsigned(ID.Num) >= CurFun.NumberedBlocks.size())
+ CurFun.NumberedBlocks.resize(ID.Num+1);
+ BB = CurFun.NumberedBlocks[ID.Num];
+ break;
+ case ValID::NameVal: // Is it a named definition?
+ Name = ID.Name;
+ if (Value *N = CurFun.CurrentFunction->getValueSymbolTable().lookup(Name)) {
+ if (N->getType() != Type::LabelTy) {
+ // Register names didn't use to conflict with basic block names
+ // because of type planes. Now they all have to be unique. So, we just
+ // rename the register and treat this name as if no basic block
+ // had been found.
+ RenameMapKey Key = makeRenameMapKey(ID.Name, N->getType(), ID.S);
+ N->setName(makeNameUnique(N->getName()));
+ CurModule.RenameMap[Key] = N->getName();
+ BB = 0;
+ } else {
+ BB = cast<BasicBlock>(N);
+ }
+ }
+ break;
+ }
+
+ // See if the block has already been defined.
+ if (BB) {
+ // If this is the definition of the block, make sure the existing value was
+ // just a forward reference. If it was a forward reference, there will be
+ // an entry for it in the PlaceHolderInfo map.
+ if (isDefinition && !CurFun.BBForwardRefs.erase(BB))
+ // The existing value was a definition, not a forward reference.
+ error("Redefinition of label " + ID.getName());
+
+ ID.destroy(); // Free strdup'd memory.
+ return BB;
+ }
+
+ // Otherwise this block has not been seen before.
+ BB = new BasicBlock("", CurFun.CurrentFunction);
+ if (ID.Type == ValID::NameVal) {
+ BB->setName(ID.Name);
+ } else {
+ CurFun.NumberedBlocks[ID.Num] = BB;
+ }
+
+ // If this is not a definition, keep track of it so we can use it as a forward
+ // reference.
+ if (!isDefinition) {
+ // Remember where this forward reference came from.
+ CurFun.BBForwardRefs[BB] = std::make_pair(ID, Upgradelineno);
+ } else {
+ // The forward declaration could have been inserted anywhere in the
+ // function: insert it into the correct place now.
+ CurFun.CurrentFunction->getBasicBlockList().remove(BB);
+ CurFun.CurrentFunction->getBasicBlockList().push_back(BB);
+ }
+ ID.destroy();
+ return BB;
+}
+
+
+//===----------------------------------------------------------------------===//
+// Code to handle forward references in instructions
+//===----------------------------------------------------------------------===//
+//
+// This code handles the late binding needed with statements that reference
+// values not defined yet... for example, a forward branch, or the PHI node for
+// a loop body.
+//
+// This keeps a table (CurFun.LateResolveValues) of all such forward references
+// and back patchs after we are done.
+//
+
+// ResolveDefinitions - If we could not resolve some defs at parsing
+// time (forward branches, phi functions for loops, etc...) resolve the
+// defs now...
+//
+static void
+ResolveDefinitions(std::map<const Type*,ValueList> &LateResolvers,
+ std::map<const Type*,ValueList> *FutureLateResolvers) {
+
+ // Loop over LateResolveDefs fixing up stuff that couldn't be resolved
+ for (std::map<const Type*,ValueList>::iterator LRI = LateResolvers.begin(),
+ E = LateResolvers.end(); LRI != E; ++LRI) {
+ const Type* Ty = LRI->first;
+ ValueList &List = LRI->second;
+ while (!List.empty()) {
+ Value *V = List.back();
+ List.pop_back();
+
+ std::map<Value*, std::pair<ValID, int> >::iterator PHI =
+ CurModule.PlaceHolderInfo.find(V);
+ assert(PHI != CurModule.PlaceHolderInfo.end() && "Placeholder error");
+
+ ValID &DID = PHI->second.first;
+
+ Value *TheRealValue = getExistingValue(Ty, DID);
+ if (TheRealValue) {
+ V->replaceAllUsesWith(TheRealValue);
+ delete V;
+ CurModule.PlaceHolderInfo.erase(PHI);
+ } else if (FutureLateResolvers) {
+ // Functions have their unresolved items forwarded to the module late
+ // resolver table
+ InsertValue(V, *FutureLateResolvers);
+ } else {
+ if (DID.Type == ValID::NameVal) {
+ error("Reference to an invalid definition: '" + DID.getName() +
+ "' of type '" + V->getType()->getDescription() + "'",
+ PHI->second.second);
+ return;
+ } else {
+ error("Reference to an invalid definition: #" +
+ itostr(DID.Num) + " of type '" +
+ V->getType()->getDescription() + "'", PHI->second.second);
+ return;
+ }
+ }
+ }
+ }
+
+ LateResolvers.clear();
+}
+
+/// This function is used for type resolution and upref handling. When a type
+/// becomes concrete, this function is called to adjust the signedness for the
+/// concrete type.
+static void ResolveTypeSign(const Type* oldTy, const Signedness &Sign) {
+ std::string TyName = CurModule.CurrentModule->getTypeName(oldTy);
+ if (!TyName.empty())
+ CurModule.NamedTypeSigns[TyName] = Sign;
+}
+
+/// ResolveTypeTo - A brand new type was just declared. This means that (if
+/// name is not null) things referencing Name can be resolved. Otherwise,
+/// things refering to the number can be resolved. Do this now.
+static void ResolveTypeTo(char *Name, const Type *ToTy, const Signedness& Sign){
+ ValID D;
+ if (Name)
+ D = ValID::create(Name);
+ else
+ D = ValID::create((int)CurModule.Types.size());
+ D.S.copy(Sign);
+
+ if (Name)
+ CurModule.NamedTypeSigns[Name] = Sign;
+
+ std::map<ValID, PATypeHolder>::iterator I =
+ CurModule.LateResolveTypes.find(D);
+ if (I != CurModule.LateResolveTypes.end()) {
+ const Type *OldTy = I->second.get();
+ ((DerivedType*)OldTy)->refineAbstractTypeTo(ToTy);
+ CurModule.LateResolveTypes.erase(I);
+ }
+}
+
+/// This is the implementation portion of TypeHasInteger. It traverses the
+/// type given, avoiding recursive types, and returns true as soon as it finds
+/// an integer type. If no integer type is found, it returns false.
+static bool TypeHasIntegerI(const Type *Ty, std::vector<const Type*> Stack) {
+ // Handle some easy cases
+ if (Ty->isPrimitiveType() || (Ty->getTypeID() == Type::OpaqueTyID))
+ return false;
+ if (Ty->isInteger())
+ return true;
+ if (const SequentialType *STy = dyn_cast<SequentialType>(Ty))
+ return STy->getElementType()->isInteger();
+
+ // Avoid type structure recursion
+ for (std::vector<const Type*>::iterator I = Stack.begin(), E = Stack.end();
+ I != E; ++I)
+ if (Ty == *I)
+ return false;
+
+ // Push us on the type stack
+ Stack.push_back(Ty);
+
+ if (const FunctionType *FTy = dyn_cast<FunctionType>(Ty)) {
+ if (TypeHasIntegerI(FTy->getReturnType(), Stack))
+ return true;
+ FunctionType::param_iterator I = FTy->param_begin();
+ FunctionType::param_iterator E = FTy->param_end();
+ for (; I != E; ++I)
+ if (TypeHasIntegerI(*I, Stack))
+ return true;
+ return false;
+ } else if (const StructType *STy = dyn_cast<StructType>(Ty)) {
+ StructType::element_iterator I = STy->element_begin();
+ StructType::element_iterator E = STy->element_end();
+ for (; I != E; ++I) {
+ if (TypeHasIntegerI(*I, Stack))
+ return true;
+ }
+ return false;
+ }
+ // There shouldn't be anything else, but its definitely not integer
+ assert(0 && "What type is this?");
+ return false;
+}
+
+/// This is the interface to TypeHasIntegerI. It just provides the type stack,
+/// to avoid recursion, and then calls TypeHasIntegerI.
+static inline bool TypeHasInteger(const Type *Ty) {
+ std::vector<const Type*> TyStack;
+ return TypeHasIntegerI(Ty, TyStack);
+}
+
+// setValueName - Set the specified value to the name given. The name may be
+// null potentially, in which case this is a noop. The string passed in is
+// assumed to be a malloc'd string buffer, and is free'd by this function.
+//
+static void setValueName(const ValueInfo &V, char *NameStr) {
+ if (NameStr) {
+ std::string Name(NameStr); // Copy string
+ free(NameStr); // Free old string
+
+ if (V.V->getType() == Type::VoidTy) {
+ error("Can't assign name '" + Name + "' to value with void type");
+ return;
+ }
+
+ assert(inFunctionScope() && "Must be in function scope");
+
+ // Search the function's symbol table for an existing value of this name
+ ValueSymbolTable &ST = CurFun.CurrentFunction->getValueSymbolTable();
+ Value* Existing = ST.lookup(Name);
+ if (Existing) {
+ // An existing value of the same name was found. This might have happened
+ // because of the integer type planes collapsing in LLVM 2.0.
+ if (Existing->getType() == V.V->getType() &&
+ !TypeHasInteger(Existing->getType())) {
+ // If the type does not contain any integers in them then this can't be
+ // a type plane collapsing issue. It truly is a redefinition and we
+ // should error out as the assembly is invalid.
+ error("Redefinition of value named '" + Name + "' of type '" +
+ V.V->getType()->getDescription() + "'");
+ return;
+ }
+ // In LLVM 2.0 we don't allow names to be re-used for any values in a
+ // function, regardless of Type. Previously re-use of names was okay as
+ // long as they were distinct types. With type planes collapsing because
+ // of the signedness change and because of PR411, this can no longer be
+ // supported. We must search the entire symbol table for a conflicting
+ // name and make the name unique. No warning is needed as this can't
+ // cause a problem.
+ std::string NewName = makeNameUnique(Name);
+ // We're changing the name but it will probably be used by other
+ // instructions as operands later on. Consequently we have to retain
+ // a mapping of the renaming that we're doing.
+ RenameMapKey Key = makeRenameMapKey(Name, V.V->getType(), V.S);
+ CurFun.RenameMap[Key] = NewName;
+ Name = NewName;
+ }
+
+ // Set the name.
+ V.V->setName(Name);
+ }
+}
+
+/// ParseGlobalVariable - Handle parsing of a global. If Initializer is null,
+/// this is a declaration, otherwise it is a definition.
+static GlobalVariable *
+ParseGlobalVariable(char *NameStr,GlobalValue::LinkageTypes Linkage,
+ bool isConstantGlobal, const Type *Ty,
+ Constant *Initializer,
+ const Signedness &Sign) {
+ if (isa<FunctionType>(Ty))
+ error("Cannot declare global vars of function type");
+
+ const PointerType *PTy = PointerType::get(Ty);
+
+ std::string Name;
+ if (NameStr) {
+ Name = NameStr; // Copy string
+ free(NameStr); // Free old string
+ }
+
+ // See if this global value was forward referenced. If so, recycle the
+ // object.
+ ValID ID;
+ if (!Name.empty()) {
+ ID = ValID::create((char*)Name.c_str());
+ } else {
+ ID = ValID::create((int)CurModule.Values[PTy].size());
+ }
+ ID.S.makeComposite(Sign);
+
+ if (GlobalValue *FWGV = CurModule.GetForwardRefForGlobal(PTy, ID)) {
+ // Move the global to the end of the list, from whereever it was
+ // previously inserted.
+ GlobalVariable *GV = cast<GlobalVariable>(FWGV);
+ CurModule.CurrentModule->getGlobalList().remove(GV);
+ CurModule.CurrentModule->getGlobalList().push_back(GV);
+ GV->setInitializer(Initializer);
+ GV->setLinkage(Linkage);
+ GV->setConstant(isConstantGlobal);
+ InsertValue(GV, CurModule.Values);
+ return GV;
+ }
+
+ // If this global has a name, check to see if there is already a definition
+ // of this global in the module and emit warnings if there are conflicts.
+ if (!Name.empty()) {
+ // The global has a name. See if there's an existing one of the same name.
+ if (CurModule.CurrentModule->getNamedGlobal(Name) ||
+ CurModule.CurrentModule->getFunction(Name)) {
+ // We found an existing global of the same name. This isn't allowed
+ // in LLVM 2.0. Consequently, we must alter the name of the global so it
+ // can at least compile. This can happen because of type planes
+ // There is alread a global of the same name which means there is a
+ // conflict. Let's see what we can do about it.
+ std::string NewName(makeNameUnique(Name));
+ if (Linkage != GlobalValue::InternalLinkage) {
+ // The linkage of this gval is external so we can't reliably rename
+ // it because it could potentially create a linking problem.
+ // However, we can't leave the name conflict in the output either or
+ // it won't assemble with LLVM 2.0. So, all we can do is rename
+ // this one to something unique and emit a warning about the problem.
+ warning("Renaming global variable '" + Name + "' to '" + NewName +
+ "' may cause linkage errors");
+ }
+
+ // Put the renaming in the global rename map
+ RenameMapKey Key = makeRenameMapKey(Name, PointerType::get(Ty), ID.S);
+ CurModule.RenameMap[Key] = NewName;
+
+ // Rename it
+ Name = NewName;
+ }
+ }
+
+ // Otherwise there is no existing GV to use, create one now.
+ GlobalVariable *GV =
+ new GlobalVariable(Ty, isConstantGlobal, Linkage, Initializer, Name,
+ CurModule.CurrentModule);
+ InsertValue(GV, CurModule.Values);
+ // Remember the sign of this global.
+ CurModule.NamedValueSigns[Name] = ID.S;
+ return GV;
+}
+
+// setTypeName - Set the specified type to the name given. The name may be
+// null potentially, in which case this is a noop. The string passed in is
+// assumed to be a malloc'd string buffer, and is freed by this function.
+//
+// This function returns true if the type has already been defined, but is
+// allowed to be redefined in the specified context. If the name is a new name
+// for the type plane, it is inserted and false is returned.
+static bool setTypeName(const PATypeInfo& TI, char *NameStr) {
+ assert(!inFunctionScope() && "Can't give types function-local names");
+ if (NameStr == 0) return false;
+
+ std::string Name(NameStr); // Copy string
+ free(NameStr); // Free old string
+
+ const Type* Ty = TI.PAT->get();
+
+ // We don't allow assigning names to void type
+ if (Ty == Type::VoidTy) {
+ error("Can't assign name '" + Name + "' to the void type");
+ return false;
+ }
+
+ // Set the type name, checking for conflicts as we do so.
+ bool AlreadyExists = CurModule.CurrentModule->addTypeName(Name, Ty);
+
+ // Save the sign information for later use
+ CurModule.NamedTypeSigns[Name] = TI.S;
+
+ if (AlreadyExists) { // Inserting a name that is already defined???
+ const Type *Existing = CurModule.CurrentModule->getTypeByName(Name);
+ assert(Existing && "Conflict but no matching type?");
+
+ // There is only one case where this is allowed: when we are refining an
+ // opaque type. In this case, Existing will be an opaque type.
+ if (const OpaqueType *OpTy = dyn_cast<OpaqueType>(Existing)) {
+ // We ARE replacing an opaque type!
+ const_cast<OpaqueType*>(OpTy)->refineAbstractTypeTo(Ty);
+ return true;
+ }
+
+ // Otherwise, this is an attempt to redefine a type. That's okay if
+ // the redefinition is identical to the original. This will be so if
+ // Existing and T point to the same Type object. In this one case we
+ // allow the equivalent redefinition.
+ if (Existing == Ty) return true; // Yes, it's equal.
+
+ // Any other kind of (non-equivalent) redefinition is an error.
+ error("Redefinition of type named '" + Name + "' in the '" +
+ Ty->getDescription() + "' type plane");
+ }
+
+ return false;
+}
+
+//===----------------------------------------------------------------------===//
+// Code for handling upreferences in type names...
+//
+
+// TypeContains - Returns true if Ty directly contains E in it.
+//
+static bool TypeContains(const Type *Ty, const Type *E) {
+ return std::find(Ty->subtype_begin(), Ty->subtype_end(),
+ E) != Ty->subtype_end();
+}
+
+namespace {
+ struct UpRefRecord {
+ // NestingLevel - The number of nesting levels that need to be popped before
+ // this type is resolved.
+ unsigned NestingLevel;
+
+ // LastContainedTy - This is the type at the current binding level for the
+ // type. Every time we reduce the nesting level, this gets updated.
+ const Type *LastContainedTy;
+
+ // UpRefTy - This is the actual opaque type that the upreference is
+ // represented with.
+ OpaqueType *UpRefTy;
+
+ UpRefRecord(unsigned NL, OpaqueType *URTy)
+ : NestingLevel(NL), LastContainedTy(URTy), UpRefTy(URTy) { }
+ };
+}
+
+// UpRefs - A list of the outstanding upreferences that need to be resolved.
+static std::vector<UpRefRecord> UpRefs;
+
+/// HandleUpRefs - Every time we finish a new layer of types, this function is
+/// called. It loops through the UpRefs vector, which is a list of the
+/// currently active types. For each type, if the up reference is contained in
+/// the newly completed type, we decrement the level count. When the level
+/// count reaches zero, the upreferenced type is the type that is passed in:
+/// thus we can complete the cycle.
+///
+static PATypeHolder HandleUpRefs(const Type *ty, const Signedness& Sign) {
+ // If Ty isn't abstract, or if there are no up-references in it, then there is
+ // nothing to resolve here.
+ if (!ty->isAbstract() || UpRefs.empty()) return ty;
+
+ PATypeHolder Ty(ty);
+ UR_OUT("Type '" << Ty->getDescription() <<
+ "' newly formed. Resolving upreferences.\n" <<
+ UpRefs.size() << " upreferences active!\n");
+
+ // If we find any resolvable upreferences (i.e., those whose NestingLevel goes
+ // to zero), we resolve them all together before we resolve them to Ty. At
+ // the end of the loop, if there is anything to resolve to Ty, it will be in
+ // this variable.
+ OpaqueType *TypeToResolve = 0;
+
+ unsigned i = 0;
+ for (; i != UpRefs.size(); ++i) {
+ UR_OUT(" UR#" << i << " - TypeContains(" << Ty->getDescription() << ", "
+ << UpRefs[i].UpRefTy->getDescription() << ") = "
+ << (TypeContains(Ty, UpRefs[i].UpRefTy) ? "true" : "false") << "\n");
+ if (TypeContains(Ty, UpRefs[i].LastContainedTy)) {
+ // Decrement level of upreference
+ unsigned Level = --UpRefs[i].NestingLevel;
+ UpRefs[i].LastContainedTy = Ty;
+ UR_OUT(" Uplevel Ref Level = " << Level << "\n");
+ if (Level == 0) { // Upreference should be resolved!
+ if (!TypeToResolve) {
+ TypeToResolve = UpRefs[i].UpRefTy;
+ } else {
+ UR_OUT(" * Resolving upreference for "
+ << UpRefs[i].UpRefTy->getDescription() << "\n";
+ std::string OldName = UpRefs[i].UpRefTy->getDescription());
+ ResolveTypeSign(UpRefs[i].UpRefTy, Sign);
+ UpRefs[i].UpRefTy->refineAbstractTypeTo(TypeToResolve);
+ UR_OUT(" * Type '" << OldName << "' refined upreference to: "
+ << (const void*)Ty << ", " << Ty->getDescription() << "\n");
+ }
+ UpRefs.erase(UpRefs.begin()+i); // Remove from upreference list...
+ --i; // Do not skip the next element...
+ }
+ }
+ }
+
+ if (TypeToResolve) {
+ UR_OUT(" * Resolving upreference for "
+ << UpRefs[i].UpRefTy->getDescription() << "\n";
+ std::string OldName = TypeToResolve->getDescription());
+ ResolveTypeSign(TypeToResolve, Sign);
+ TypeToResolve->refineAbstractTypeTo(Ty);
+ }
+
+ return Ty;
+}
+
+bool Signedness::operator<(const Signedness &that) const {
+ if (isNamed()) {
+ if (that.isNamed())
+ return *(this->name) < *(that.name);
+ else
+ return CurModule.NamedTypeSigns[*name] < that;
+ } else if (that.isNamed()) {
+ return *this < CurModule.NamedTypeSigns[*that.name];
+ }
+
+ if (isComposite() && that.isComposite()) {
+ if (sv->size() == that.sv->size()) {
+ SignVector::const_iterator thisI = sv->begin(), thisE = sv->end();
+ SignVector::const_iterator thatI = that.sv->begin(),
+ thatE = that.sv->end();
+ for (; thisI != thisE; ++thisI, ++thatI) {
+ if (*thisI < *thatI)
+ return true;
+ else if (!(*thisI == *thatI))
+ return false;
+ }
+ return false;
+ }
+ return sv->size() < that.sv->size();
+ }
+ return kind < that.kind;
+}
+
+bool Signedness::operator==(const Signedness &that) const {
+ if (isNamed())
+ if (that.isNamed())
+ return *(this->name) == *(that.name);
+ else
+ return CurModule.NamedTypeSigns[*(this->name)] == that;
+ else if (that.isNamed())
+ return *this == CurModule.NamedTypeSigns[*(that.name)];
+ if (isComposite() && that.isComposite()) {
+ if (sv->size() == that.sv->size()) {
+ SignVector::const_iterator thisI = sv->begin(), thisE = sv->end();
+ SignVector::const_iterator thatI = that.sv->begin(),
+ thatE = that.sv->end();
+ for (; thisI != thisE; ++thisI, ++thatI) {
+ if (!(*thisI == *thatI))
+ return false;
+ }
+ return true;
+ }
+ return false;
+ }
+ return kind == that.kind;
+}
+
+void Signedness::copy(const Signedness &that) {
+ if (that.isNamed()) {
+ kind = Named;
+ name = new std::string(*that.name);
+ } else if (that.isComposite()) {
+ kind = Composite;
+ sv = new SignVector();
+ *sv = *that.sv;
+ } else {
+ kind = that.kind;
+ sv = 0;
+ }
+}
+
+void Signedness::destroy() {
+ if (isNamed()) {
+ delete name;
+ } else if (isComposite()) {
+ delete sv;
+ }
+}
+
+#ifndef NDEBUG
+void Signedness::dump() const {
+ if (isComposite()) {
+ if (sv->size() == 1) {
+ (*sv)[0].dump();
+ std::cerr << "*";
+ } else {
+ std::cerr << "{ " ;
+ for (unsigned i = 0; i < sv->size(); ++i) {
+ if (i != 0)
+ std::cerr << ", ";
+ (*sv)[i].dump();
+ }
+ std::cerr << "} " ;
+ }
+ } else if (isNamed()) {
+ std::cerr << *name;
+ } else if (isSigned()) {
+ std::cerr << "S";
+ } else if (isUnsigned()) {
+ std::cerr << "U";
+ } else
+ std::cerr << ".";
+}
+#endif
+
+static inline Instruction::TermOps
+getTermOp(TermOps op) {
+ switch (op) {
+ default : assert(0 && "Invalid OldTermOp");
+ case RetOp : return Instruction::Ret;
+ case BrOp : return Instruction::Br;
+ case SwitchOp : return Instruction::Switch;
+ case InvokeOp : return Instruction::Invoke;
+ case UnwindOp : return Instruction::Unwind;
+ case UnreachableOp: return Instruction::Unreachable;
+ }
+}
+
+static inline Instruction::BinaryOps
+getBinaryOp(BinaryOps op, const Type *Ty, const Signedness& Sign) {
+ switch (op) {
+ default : assert(0 && "Invalid OldBinaryOps");
+ case SetEQ :
+ case SetNE :
+ case SetLE :
+ case SetGE :
+ case SetLT :
+ case SetGT : assert(0 && "Should use getCompareOp");
+ case AddOp : return Instruction::Add;
+ case SubOp : return Instruction::Sub;
+ case MulOp : return Instruction::Mul;
+ case DivOp : {
+ // This is an obsolete instruction so we must upgrade it based on the
+ // types of its operands.
+ bool isFP = Ty->isFloatingPoint();
+ if (const VectorType* PTy = dyn_cast<VectorType>(Ty))
+ // If its a vector type we want to use the element type
+ isFP = PTy->getElementType()->isFloatingPoint();
+ if (isFP)
+ return Instruction::FDiv;
+ else if (Sign.isSigned())
+ return Instruction::SDiv;
+ return Instruction::UDiv;
+ }
+ case UDivOp : return Instruction::UDiv;
+ case SDivOp : return Instruction::SDiv;
+ case FDivOp : return Instruction::FDiv;
+ case RemOp : {
+ // This is an obsolete instruction so we must upgrade it based on the
+ // types of its operands.
+ bool isFP = Ty->isFloatingPoint();
+ if (const VectorType* PTy = dyn_cast<VectorType>(Ty))
+ // If its a vector type we want to use the element type
+ isFP = PTy->getElementType()->isFloatingPoint();
+ // Select correct opcode
+ if (isFP)
+ return Instruction::FRem;
+ else if (Sign.isSigned())
+ return Instruction::SRem;
+ return Instruction::URem;
+ }
+ case URemOp : return Instruction::URem;
+ case SRemOp : return Instruction::SRem;
+ case FRemOp : return Instruction::FRem;
+ case LShrOp : return Instruction::LShr;
+ case AShrOp : return Instruction::AShr;
+ case ShlOp : return Instruction::Shl;
+ case ShrOp :
+ if (Sign.isSigned())
+ return Instruction::AShr;
+ return Instruction::LShr;
+ case AndOp : return Instruction::And;
+ case OrOp : return Instruction::Or;
+ case XorOp : return Instruction::Xor;
+ }
+}
+
+static inline Instruction::OtherOps
+getCompareOp(BinaryOps op, unsigned short &predicate, const Type* &Ty,
+ const Signedness &Sign) {
+ bool isSigned = Sign.isSigned();
+ bool isFP = Ty->isFloatingPoint();
+ switch (op) {
+ default : assert(0 && "Invalid OldSetCC");
+ case SetEQ :
+ if (isFP) {
+ predicate = FCmpInst::FCMP_OEQ;
+ return Instruction::FCmp;
+ } else {
+ predicate = ICmpInst::ICMP_EQ;
+ return Instruction::ICmp;
+ }
+ case SetNE :
+ if (isFP) {
+ predicate = FCmpInst::FCMP_UNE;
+ return Instruction::FCmp;
+ } else {
+ predicate = ICmpInst::ICMP_NE;
+ return Instruction::ICmp;
+ }
+ case SetLE :
+ if (isFP) {
+ predicate = FCmpInst::FCMP_OLE;
+ return Instruction::FCmp;
+ } else {
+ if (isSigned)
+ predicate = ICmpInst::ICMP_SLE;
+ else
+ predicate = ICmpInst::ICMP_ULE;
+ return Instruction::ICmp;
+ }
+ case SetGE :
+ if (isFP) {
+ predicate = FCmpInst::FCMP_OGE;
+ return Instruction::FCmp;
+ } else {
+ if (isSigned)
+ predicate = ICmpInst::ICMP_SGE;
+ else
+ predicate = ICmpInst::ICMP_UGE;
+ return Instruction::ICmp;
+ }
+ case SetLT :
+ if (isFP) {
+ predicate = FCmpInst::FCMP_OLT;
+ return Instruction::FCmp;
+ } else {
+ if (isSigned)
+ predicate = ICmpInst::ICMP_SLT;
+ else
+ predicate = ICmpInst::ICMP_ULT;
+ return Instruction::ICmp;
+ }
+ case SetGT :
+ if (isFP) {
+ predicate = FCmpInst::FCMP_OGT;
+ return Instruction::FCmp;
+ } else {
+ if (isSigned)
+ predicate = ICmpInst::ICMP_SGT;
+ else
+ predicate = ICmpInst::ICMP_UGT;
+ return Instruction::ICmp;
+ }
+ }
+}
+
+static inline Instruction::MemoryOps getMemoryOp(MemoryOps op) {
+ switch (op) {
+ default : assert(0 && "Invalid OldMemoryOps");
+ case MallocOp : return Instruction::Malloc;
+ case FreeOp : return Instruction::Free;
+ case AllocaOp : return Instruction::Alloca;
+ case LoadOp : return Instruction::Load;
+ case StoreOp : return Instruction::Store;
+ case GetElementPtrOp : return Instruction::GetElementPtr;
+ }
+}
+
+static inline Instruction::OtherOps
+getOtherOp(OtherOps op, const Signedness &Sign) {
+ switch (op) {
+ default : assert(0 && "Invalid OldOtherOps");
+ case PHIOp : return Instruction::PHI;
+ case CallOp : return Instruction::Call;
+ case SelectOp : return Instruction::Select;
+ case UserOp1 : return Instruction::UserOp1;
+ case UserOp2 : return Instruction::UserOp2;
+ case VAArg : return Instruction::VAArg;
+ case ExtractElementOp : return Instruction::ExtractElement;
+ case InsertElementOp : return Instruction::InsertElement;
+ case ShuffleVectorOp : return Instruction::ShuffleVector;
+ case ICmpOp : return Instruction::ICmp;
+ case FCmpOp : return Instruction::FCmp;
+ };
+}
+
+static inline Value*
+getCast(CastOps op, Value *Src, const Signedness &SrcSign, const Type *DstTy,
+ const Signedness &DstSign, bool ForceInstruction = false) {
+ Instruction::CastOps Opcode;
+ const Type* SrcTy = Src->getType();
+ if (op == CastOp) {
+ if (SrcTy->isFloatingPoint() && isa<PointerType>(DstTy)) {
+ // fp -> ptr cast is no longer supported but we must upgrade this
+ // by doing a double cast: fp -> int -> ptr
+ SrcTy = Type::Int64Ty;
+ Opcode = Instruction::IntToPtr;
+ if (isa<Constant>(Src)) {
+ Src = ConstantExpr::getCast(Instruction::FPToUI,
+ cast<Constant>(Src), SrcTy);
+ } else {
+ std::string NewName(makeNameUnique(Src->getName()));
+ Src = new FPToUIInst(Src, SrcTy, NewName, CurBB);
+ }
+ } else if (isa<IntegerType>(DstTy) &&
+ cast<IntegerType>(DstTy)->getBitWidth() == 1) {
+ // cast type %x to bool was previously defined as setne type %x, null
+ // The cast semantic is now to truncate, not compare so we must retain
+ // the original intent by replacing the cast with a setne
+ Constant* Null = Constant::getNullValue(SrcTy);
+ Instruction::OtherOps Opcode = Instruction::ICmp;
+ unsigned short predicate = ICmpInst::ICMP_NE;
+ if (SrcTy->isFloatingPoint()) {
+ Opcode = Instruction::FCmp;
+ predicate = FCmpInst::FCMP_ONE;
+ } else if (!SrcTy->isInteger() && !isa<PointerType>(SrcTy)) {
+ error("Invalid cast to bool");
+ }
+ if (isa<Constant>(Src) && !ForceInstruction)
+ return ConstantExpr::getCompare(predicate, cast<Constant>(Src), Null);
+ else
+ return CmpInst::create(Opcode, predicate, Src, Null);
+ }
+ // Determine the opcode to use by calling CastInst::getCastOpcode
+ Opcode =
+ CastInst::getCastOpcode(Src, SrcSign.isSigned(), DstTy,
+ DstSign.isSigned());
+
+ } else switch (op) {
+ default: assert(0 && "Invalid cast token");
+ case TruncOp: Opcode = Instruction::Trunc; break;
+ case ZExtOp: Opcode = Instruction::ZExt; break;
+ case SExtOp: Opcode = Instruction::SExt; break;
+ case FPTruncOp: Opcode = Instruction::FPTrunc; break;
+ case FPExtOp: Opcode = Instruction::FPExt; break;
+ case FPToUIOp: Opcode = Instruction::FPToUI; break;
+ case FPToSIOp: Opcode = Instruction::FPToSI; break;
+ case UIToFPOp: Opcode = Instruction::UIToFP; break;
+ case SIToFPOp: Opcode = Instruction::SIToFP; break;
+ case PtrToIntOp: Opcode = Instruction::PtrToInt; break;
+ case IntToPtrOp: Opcode = Instruction::IntToPtr; break;
+ case BitCastOp: Opcode = Instruction::BitCast; break;
+ }
+
+ if (isa<Constant>(Src) && !ForceInstruction)
+ return ConstantExpr::getCast(Opcode, cast<Constant>(Src), DstTy);
+ return CastInst::create(Opcode, Src, DstTy);
+}
+
+static Instruction *
+upgradeIntrinsicCall(const Type* RetTy, const ValID &ID,
+ std::vector<Value*>& Args) {
+
+ std::string Name = ID.Type == ValID::NameVal ? ID.Name : "";
+ if (Name.length() <= 5 || Name[0] != 'l' || Name[1] != 'l' ||
+ Name[2] != 'v' || Name[3] != 'm' || Name[4] != '.')
+ return 0;
+
+ switch (Name[5]) {
+ case 'i':
+ if (Name == "llvm.isunordered.f32" || Name == "llvm.isunordered.f64") {
+ if (Args.size() != 2)
+ error("Invalid prototype for " + Name);
+ return new FCmpInst(FCmpInst::FCMP_UNO, Args[0], Args[1]);
+ }
+ break;
+ case 'b':
+ if (Name.length() == 14 && !memcmp(&Name[5], "bswap.i", 7)) {
+ const Type* ArgTy = Args[0]->getType();
+ Name += ".i" + utostr(cast<IntegerType>(ArgTy)->getBitWidth());
+ Function *F = cast<Function>(
+ CurModule.CurrentModule->getOrInsertFunction(Name, RetTy, ArgTy,
+ (void*)0));
+ return new CallInst(F, Args[0]);
+ }
+ break;
+ case 'c':
+ if ((Name.length() <= 14 && !memcmp(&Name[5], "ctpop.i", 7)) ||
+ (Name.length() <= 13 && !memcmp(&Name[5], "ctlz.i", 6)) ||
+ (Name.length() <= 13 && !memcmp(&Name[5], "cttz.i", 6))) {
+ // These intrinsics changed their result type.
+ const Type* ArgTy = Args[0]->getType();
+ Function *OldF = CurModule.CurrentModule->getFunction(Name);
+ if (OldF)
+ OldF->setName("upgrd.rm." + Name);
+
+ Function *NewF = cast<Function>(
+ CurModule.CurrentModule->getOrInsertFunction(Name, Type::Int32Ty,
+ ArgTy, (void*)0));
+
+ Instruction *Call = new CallInst(NewF, Args[0], "", CurBB);
+ return CastInst::createIntegerCast(Call, RetTy, false);
+ }
+ break;
+
+ case 'v' : {
+ const Type* PtrTy = PointerType::get(Type::Int8Ty);
+ std::vector<const Type*> Params;
+ if (Name == "llvm.va_start" || Name == "llvm.va_end") {
+ if (Args.size() != 1)
+ error("Invalid prototype for " + Name + " prototype");
+ Params.push_back(PtrTy);
+ const FunctionType *FTy =
+ FunctionType::get(Type::VoidTy, Params, false);
+ const PointerType *PFTy = PointerType::get(FTy);
+ Value* Func = getVal(PFTy, ID);
+ Args[0] = new BitCastInst(Args[0], PtrTy, makeNameUnique("va"), CurBB);
+ return new CallInst(Func, &Args[0], Args.size());
+ } else if (Name == "llvm.va_copy") {
+ if (Args.size() != 2)
+ error("Invalid prototype for " + Name + " prototype");
+ Params.push_back(PtrTy);
+ Params.push_back(PtrTy);
+ const FunctionType *FTy =
+ FunctionType::get(Type::VoidTy, Params, false);
+ const PointerType *PFTy = PointerType::get(FTy);
+ Value* Func = getVal(PFTy, ID);
+ std::string InstName0(makeNameUnique("va0"));
+ std::string InstName1(makeNameUnique("va1"));
+ Args[0] = new BitCastInst(Args[0], PtrTy, InstName0, CurBB);
+ Args[1] = new BitCastInst(Args[1], PtrTy, InstName1, CurBB);
+ return new CallInst(Func, &Args[0], Args.size());
+ }
+ }
+ }
+ return 0;
+}
+
+const Type* upgradeGEPCEIndices(const Type* PTy,
+ std::vector<ValueInfo> *Indices,
+ std::vector<Constant*> &Result) {
+ const Type *Ty = PTy;
+ Result.clear();
+ for (unsigned i = 0, e = Indices->size(); i != e ; ++i) {
+ Constant *Index = cast<Constant>((*Indices)[i].V);
+
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(Index)) {
+ // LLVM 1.2 and earlier used ubyte struct indices. Convert any ubyte
+ // struct indices to i32 struct indices with ZExt for compatibility.
+ if (CI->getBitWidth() < 32)
+ Index = ConstantExpr::getCast(Instruction::ZExt, CI, Type::Int32Ty);
+ }
+
+ if (isa<SequentialType>(Ty)) {
+ // Make sure that unsigned SequentialType indices are zext'd to
+ // 64-bits if they were smaller than that because LLVM 2.0 will sext
+ // all indices for SequentialType elements. We must retain the same
+ // semantic (zext) for unsigned types.
+ if (const IntegerType *Ity = dyn_cast<IntegerType>(Index->getType())) {
+ if (Ity->getBitWidth() < 64 && (*Indices)[i].S.isUnsigned()) {
+ Index = ConstantExpr::getCast(Instruction::ZExt, Index,Type::Int64Ty);
+ }
+ }
+ }
+ Result.push_back(Index);
+ Ty = GetElementPtrInst::getIndexedType(PTy, (Value**)&Result[0],
+ Result.size(),true);
+ if (!Ty)
+ error("Index list invalid for constant getelementptr");
+ }
+ return Ty;
+}
+
+const Type* upgradeGEPInstIndices(const Type* PTy,
+ std::vector<ValueInfo> *Indices,
+ std::vector<Value*> &Result) {
+ const Type *Ty = PTy;
+ Result.clear();
+ for (unsigned i = 0, e = Indices->size(); i != e ; ++i) {
+ Value *Index = (*Indices)[i].V;
+
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(Index)) {
+ // LLVM 1.2 and earlier used ubyte struct indices. Convert any ubyte
+ // struct indices to i32 struct indices with ZExt for compatibility.
+ if (CI->getBitWidth() < 32)
+ Index = ConstantExpr::getCast(Instruction::ZExt, CI, Type::Int32Ty);
+ }
+
+
+ if (isa<StructType>(Ty)) { // Only change struct indices
+ if (!isa<Constant>(Index)) {
+ error("Invalid non-constant structure index");
+ return 0;
+ }
+ } else {
+ // Make sure that unsigned SequentialType indices are zext'd to
+ // 64-bits if they were smaller than that because LLVM 2.0 will sext
+ // all indices for SequentialType elements. We must retain the same
+ // semantic (zext) for unsigned types.
+ if (const IntegerType *Ity = dyn_cast<IntegerType>(Index->getType())) {
+ if (Ity->getBitWidth() < 64 && (*Indices)[i].S.isUnsigned()) {
+ if (isa<Constant>(Index))
+ Index = ConstantExpr::getCast(Instruction::ZExt,
+ cast<Constant>(Index), Type::Int64Ty);
+ else
+ Index = CastInst::create(Instruction::ZExt, Index, Type::Int64Ty,
+ makeNameUnique("gep"), CurBB);
+ }
+ }
+ }
+ Result.push_back(Index);
+ Ty = GetElementPtrInst::getIndexedType(PTy, &Result[0], Result.size(),true);
+ if (!Ty)
+ error("Index list invalid for constant getelementptr");
+ }
+ return Ty;
+}
+
+unsigned upgradeCallingConv(unsigned CC) {
+ switch (CC) {
+ case OldCallingConv::C : return CallingConv::C;
+ case OldCallingConv::CSRet : return CallingConv::C;
+ case OldCallingConv::Fast : return CallingConv::Fast;
+ case OldCallingConv::Cold : return CallingConv::Cold;
+ case OldCallingConv::X86_StdCall : return CallingConv::X86_StdCall;
+ case OldCallingConv::X86_FastCall: return CallingConv::X86_FastCall;
+ default:
+ return CC;
+ }
+}
+
+Module* UpgradeAssembly(const std::string &infile, std::istream& in,
+ bool debug, bool addAttrs)
+{
+ Upgradelineno = 1;
+ CurFilename = infile;
+ LexInput = &in;
+ yydebug = debug;
+ AddAttributes = addAttrs;
+ ObsoleteVarArgs = false;
+ NewVarArgs = false;
+
+ CurModule.CurrentModule = new Module(CurFilename);
+
+ // Check to make sure the parser succeeded
+ if (yyparse()) {
+ if (ParserResult)
+ delete ParserResult;
+ std::cerr << "llvm-upgrade: parse failed.\n";
+ return 0;
+ }
+
+ // Check to make sure that parsing produced a result
+ if (!ParserResult) {
+ std::cerr << "llvm-upgrade: no parse result.\n";
+ return 0;
+ }
+
+ // Reset ParserResult variable while saving its value for the result.
+ Module *Result = ParserResult;
+ ParserResult = 0;
+
+ //Not all functions use vaarg, so make a second check for ObsoleteVarArgs
+ {
+ Function* F;
+ if ((F = Result->getFunction("llvm.va_start"))
+ && F->getFunctionType()->getNumParams() == 0)
+ ObsoleteVarArgs = true;
+ if((F = Result->getFunction("llvm.va_copy"))
+ && F->getFunctionType()->getNumParams() == 1)
+ ObsoleteVarArgs = true;
+ }
+
+ if (ObsoleteVarArgs && NewVarArgs) {
+ error("This file is corrupt: it uses both new and old style varargs");
+ return 0;
+ }
+
+ if(ObsoleteVarArgs) {
+ if(Function* F = Result->getFunction("llvm.va_start")) {
+ if (F->arg_size() != 0) {
+ error("Obsolete va_start takes 0 argument");
+ return 0;
+ }
+
+ //foo = va_start()
+ // ->
+ //bar = alloca typeof(foo)
+ //va_start(bar)
+ //foo = load bar
+
+ const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID);
+ const Type* ArgTy = F->getFunctionType()->getReturnType();
+ const Type* ArgTyPtr = PointerType::get(ArgTy);
+ Function* NF = cast<Function>(Result->getOrInsertFunction(
+ "llvm.va_start", RetTy, ArgTyPtr, (Type *)0));
+
+ while (!F->use_empty()) {
+ CallInst* CI = cast<CallInst>(F->use_back());
+ AllocaInst* bar = new AllocaInst(ArgTy, 0, "vastart.fix.1", CI);
+ new CallInst(NF, bar, "", CI);
+ Value* foo = new LoadInst(bar, "vastart.fix.2", CI);
+ CI->replaceAllUsesWith(foo);
+ CI->getParent()->getInstList().erase(CI);
+ }
+ Result->getFunctionList().erase(F);
+ }
+
+ if(Function* F = Result->getFunction("llvm.va_end")) {
+ if(F->arg_size() != 1) {
+ error("Obsolete va_end takes 1 argument");
+ return 0;
+ }
+
+ //vaend foo
+ // ->
+ //bar = alloca 1 of typeof(foo)
+ //vaend bar
+ const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID);
+ const Type* ArgTy = F->getFunctionType()->getParamType(0);
+ const Type* ArgTyPtr = PointerType::get(ArgTy);
+ Function* NF = cast<Function>(Result->getOrInsertFunction(
+ "llvm.va_end", RetTy, ArgTyPtr, (Type *)0));
+
+ while (!F->use_empty()) {
+ CallInst* CI = cast<CallInst>(F->use_back());
+ AllocaInst* bar = new AllocaInst(ArgTy, 0, "vaend.fix.1", CI);
+ new StoreInst(CI->getOperand(1), bar, CI);
+ new CallInst(NF, bar, "", CI);
+ CI->getParent()->getInstList().erase(CI);
+ }
+ Result->getFunctionList().erase(F);
+ }
+
+ if(Function* F = Result->getFunction("llvm.va_copy")) {
+ if(F->arg_size() != 1) {
+ error("Obsolete va_copy takes 1 argument");
+ return 0;
+ }
+ //foo = vacopy(bar)
+ // ->
+ //a = alloca 1 of typeof(foo)
+ //b = alloca 1 of typeof(foo)
+ //store bar -> b
+ //vacopy(a, b)
+ //foo = load a
+
+ const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID);
+ const Type* ArgTy = F->getFunctionType()->getReturnType();
+ const Type* ArgTyPtr = PointerType::get(ArgTy);
+ Function* NF = cast<Function>(Result->getOrInsertFunction(
+ "llvm.va_copy", RetTy, ArgTyPtr, ArgTyPtr, (Type *)0));
+
+ while (!F->use_empty()) {
+ CallInst* CI = cast<CallInst>(F->use_back());
+ AllocaInst* a = new AllocaInst(ArgTy, 0, "vacopy.fix.1", CI);
+ AllocaInst* b = new AllocaInst(ArgTy, 0, "vacopy.fix.2", CI);
+ new StoreInst(CI->getOperand(1), b, CI);
+ new CallInst(NF, a, b, "", CI);
+ Value* foo = new LoadInst(a, "vacopy.fix.3", CI);
+ CI->replaceAllUsesWith(foo);
+ CI->getParent()->getInstList().erase(CI);
+ }
+ Result->getFunctionList().erase(F);
+ }
+ }
+
+ return Result;
+}
+
+} // end llvm namespace
+
+using namespace llvm;
+
+%}
+
+%union {
+ llvm::Module *ModuleVal;
+ llvm::Function *FunctionVal;
+ std::pair<llvm::PATypeInfo, char*> *ArgVal;
+ llvm::BasicBlock *BasicBlockVal;
+ llvm::TermInstInfo TermInstVal;
+ llvm::InstrInfo InstVal;
+ llvm::ConstInfo ConstVal;
+ llvm::ValueInfo ValueVal;
+ llvm::PATypeInfo TypeVal;
+ llvm::TypeInfo PrimType;
+ llvm::PHIListInfo PHIList;
+ std::list<llvm::PATypeInfo> *TypeList;
+ std::vector<llvm::ValueInfo> *ValueList;
+ std::vector<llvm::ConstInfo> *ConstVector;
+
+
+ std::vector<std::pair<llvm::PATypeInfo,char*> > *ArgList;
+ // Represent the RHS of PHI node
+ std::vector<std::pair<llvm::Constant*, llvm::BasicBlock*> > *JumpTable;
+
+ llvm::GlobalValue::LinkageTypes Linkage;
+ int64_t SInt64Val;
+ uint64_t UInt64Val;
+ int SIntVal;
+ unsigned UIntVal;
+ double FPVal;
+ bool BoolVal;
+
+ char *StrVal; // This memory is strdup'd!
+ llvm::ValID ValIDVal; // strdup'd memory maybe!
+
+ llvm::BinaryOps BinaryOpVal;
+ llvm::TermOps TermOpVal;
+ llvm::MemoryOps MemOpVal;
+ llvm::OtherOps OtherOpVal;
+ llvm::CastOps CastOpVal;
+ llvm::ICmpInst::Predicate IPred;
+ llvm::FCmpInst::Predicate FPred;
+ llvm::Module::Endianness Endianness;
+}
+
+%type <ModuleVal> Module FunctionList
+%type <FunctionVal> Function FunctionProto FunctionHeader BasicBlockList
+%type <BasicBlockVal> BasicBlock InstructionList
+%type <TermInstVal> BBTerminatorInst
+%type <InstVal> Inst InstVal MemoryInst
+%type <ConstVal> ConstVal ConstExpr
+%type <ConstVector> ConstVector
+%type <ArgList> ArgList ArgListH
+%type <ArgVal> ArgVal
+%type <PHIList> PHIList
+%type <ValueList> ValueRefList ValueRefListE // For call param lists
+%type <ValueList> IndexList // For GEP derived indices
+%type <TypeList> TypeListI ArgTypeListI
+%type <JumpTable> JumpTable
+%type <BoolVal> GlobalType // GLOBAL or CONSTANT?
+%type <BoolVal> OptVolatile // 'volatile' or not
+%type <BoolVal> OptTailCall // TAIL CALL or plain CALL.
+%type <BoolVal> OptSideEffect // 'sideeffect' or not.
+%type <Linkage> OptLinkage FnDeclareLinkage
+%type <Endianness> BigOrLittle
+
+// ValueRef - Unresolved reference to a definition or BB
+%type <ValIDVal> ValueRef ConstValueRef SymbolicValueRef
+%type <ValueVal> ResolvedVal // <type> <valref> pair
+
+// Tokens and types for handling constant integer values
+//
+// ESINT64VAL - A negative number within long long range
+%token <SInt64Val> ESINT64VAL
+
+// EUINT64VAL - A positive number within uns. long long range
+%token <UInt64Val> EUINT64VAL
+%type <SInt64Val> EINT64VAL
+
+%token <SIntVal> SINTVAL // Signed 32 bit ints...
+%token <UIntVal> UINTVAL // Unsigned 32 bit ints...
+%type <SIntVal> INTVAL
+%token <FPVal> FPVAL // Float or Double constant
+
+// Built in types...
+%type <TypeVal> Types TypesV UpRTypes UpRTypesV
+%type <PrimType> SIntType UIntType IntType FPType PrimType // Classifications
+%token <PrimType> VOID BOOL SBYTE UBYTE SHORT USHORT INT UINT LONG ULONG
+%token <PrimType> FLOAT DOUBLE TYPE LABEL
+
+%token <StrVal> VAR_ID LABELSTR STRINGCONSTANT
+%type <StrVal> Name OptName OptAssign
+%type <UIntVal> OptAlign OptCAlign
+%type <StrVal> OptSection SectionString
+
+%token IMPLEMENTATION ZEROINITIALIZER TRUETOK FALSETOK BEGINTOK ENDTOK
+%token DECLARE GLOBAL CONSTANT SECTION VOLATILE
+%token TO DOTDOTDOT NULL_TOK UNDEF CONST INTERNAL LINKONCE WEAK APPENDING
+%token DLLIMPORT DLLEXPORT EXTERN_WEAK
+%token OPAQUE NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG ALIGN
+%token DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT
+%token CC_TOK CCC_TOK CSRETCC_TOK FASTCC_TOK COLDCC_TOK
+%token X86_STDCALLCC_TOK X86_FASTCALLCC_TOK
+%token DATALAYOUT
+%type <UIntVal> OptCallingConv
+
+// Basic Block Terminating Operators
+%token <TermOpVal> RET BR SWITCH INVOKE UNREACHABLE
+%token UNWIND EXCEPT
+
+// Binary Operators
+%type <BinaryOpVal> ArithmeticOps LogicalOps SetCondOps // Binops Subcatagories
+%type <BinaryOpVal> ShiftOps
+%token <BinaryOpVal> ADD SUB MUL DIV UDIV SDIV FDIV REM UREM SREM FREM
+%token <BinaryOpVal> AND OR XOR SHL SHR ASHR LSHR
+%token <BinaryOpVal> SETLE SETGE SETLT SETGT SETEQ SETNE // Binary Comparators
+%token <OtherOpVal> ICMP FCMP
+
+// Memory Instructions
+%token <MemOpVal> MALLOC ALLOCA FREE LOAD STORE GETELEMENTPTR
+
+// Other Operators
+%token <OtherOpVal> PHI_TOK SELECT VAARG
+%token <OtherOpVal> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR
+%token VAARG_old VANEXT_old //OBSOLETE
+
+// Support for ICmp/FCmp Predicates, which is 1.9++ but not 2.0
+%type <IPred> IPredicates
+%type <FPred> FPredicates
+%token EQ NE SLT SGT SLE SGE ULT UGT ULE UGE
+%token OEQ ONE OLT OGT OLE OGE ORD UNO UEQ UNE
+
+%token <CastOpVal> CAST TRUNC ZEXT SEXT FPTRUNC FPEXT FPTOUI FPTOSI
+%token <CastOpVal> UITOFP SITOFP PTRTOINT INTTOPTR BITCAST
+%type <CastOpVal> CastOps
+
+%start Module
+
+%%
+
+// Handle constant integer size restriction and conversion...
+//
+INTVAL
+ : SINTVAL
+ | UINTVAL {
+ if ($1 > (uint32_t)INT32_MAX) // Outside of my range!
+ error("Value too large for type");
+ $$ = (int32_t)$1;
+ }
+ ;
+
+EINT64VAL
+ : ESINT64VAL // These have same type and can't cause problems...
+ | EUINT64VAL {
+ if ($1 > (uint64_t)INT64_MAX) // Outside of my range!
+ error("Value too large for type");
+ $$ = (int64_t)$1;
+ };
+
+// Operations that are notably excluded from this list include:
+// RET, BR, & SWITCH because they end basic blocks and are treated specially.
+//
+ArithmeticOps
+ : ADD | SUB | MUL | DIV | UDIV | SDIV | FDIV | REM | UREM | SREM | FREM
+ ;
+
+LogicalOps
+ : AND | OR | XOR
+ ;
+
+SetCondOps
+ : SETLE | SETGE | SETLT | SETGT | SETEQ | SETNE
+ ;
+
+IPredicates
+ : EQ { $$ = ICmpInst::ICMP_EQ; } | NE { $$ = ICmpInst::ICMP_NE; }
+ | SLT { $$ = ICmpInst::ICMP_SLT; } | SGT { $$ = ICmpInst::ICMP_SGT; }
+ | SLE { $$ = ICmpInst::ICMP_SLE; } | SGE { $$ = ICmpInst::ICMP_SGE; }
+ | ULT { $$ = ICmpInst::ICMP_ULT; } | UGT { $$ = ICmpInst::ICMP_UGT; }
+ | ULE { $$ = ICmpInst::ICMP_ULE; } | UGE { $$ = ICmpInst::ICMP_UGE; }
+ ;
+
+FPredicates
+ : OEQ { $$ = FCmpInst::FCMP_OEQ; } | ONE { $$ = FCmpInst::FCMP_ONE; }
+ | OLT { $$ = FCmpInst::FCMP_OLT; } | OGT { $$ = FCmpInst::FCMP_OGT; }
+ | OLE { $$ = FCmpInst::FCMP_OLE; } | OGE { $$ = FCmpInst::FCMP_OGE; }
+ | ORD { $$ = FCmpInst::FCMP_ORD; } | UNO { $$ = FCmpInst::FCMP_UNO; }
+ | UEQ { $$ = FCmpInst::FCMP_UEQ; } | UNE { $$ = FCmpInst::FCMP_UNE; }
+ | ULT { $$ = FCmpInst::FCMP_ULT; } | UGT { $$ = FCmpInst::FCMP_UGT; }
+ | ULE { $$ = FCmpInst::FCMP_ULE; } | UGE { $$ = FCmpInst::FCMP_UGE; }
+ | TRUETOK { $$ = FCmpInst::FCMP_TRUE; }
+ | FALSETOK { $$ = FCmpInst::FCMP_FALSE; }
+ ;
+ShiftOps
+ : SHL | SHR | ASHR | LSHR
+ ;
+
+CastOps
+ : TRUNC | ZEXT | SEXT | FPTRUNC | FPEXT | FPTOUI | FPTOSI
+ | UITOFP | SITOFP | PTRTOINT | INTTOPTR | BITCAST | CAST
+ ;
+
+// These are some types that allow classification if we only want a particular
+// thing... for example, only a signed, unsigned, or integral type.
+SIntType
+ : LONG | INT | SHORT | SBYTE
+ ;
+
+UIntType
+ : ULONG | UINT | USHORT | UBYTE
+ ;
+
+IntType
+ : SIntType | UIntType
+ ;
+
+FPType
+ : FLOAT | DOUBLE
+ ;
+
+// OptAssign - Value producing statements have an optional assignment component
+OptAssign
+ : Name '=' {
+ $$ = $1;
+ }
+ | /*empty*/ {
+ $$ = 0;
+ };
+
+OptLinkage
+ : INTERNAL { $$ = GlobalValue::InternalLinkage; }
+ | LINKONCE { $$ = GlobalValue::LinkOnceLinkage; }
+ | WEAK { $$ = GlobalValue::WeakLinkage; }
+ | APPENDING { $$ = GlobalValue::AppendingLinkage; }
+ | DLLIMPORT { $$ = GlobalValue::DLLImportLinkage; }
+ | DLLEXPORT { $$ = GlobalValue::DLLExportLinkage; }
+ | EXTERN_WEAK { $$ = GlobalValue::ExternalWeakLinkage; }
+ | /*empty*/ { $$ = GlobalValue::ExternalLinkage; }
+ ;
+
+OptCallingConv
+ : /*empty*/ { $$ = lastCallingConv = OldCallingConv::C; }
+ | CCC_TOK { $$ = lastCallingConv = OldCallingConv::C; }
+ | CSRETCC_TOK { $$ = lastCallingConv = OldCallingConv::CSRet; }
+ | FASTCC_TOK { $$ = lastCallingConv = OldCallingConv::Fast; }
+ | COLDCC_TOK { $$ = lastCallingConv = OldCallingConv::Cold; }
+ | X86_STDCALLCC_TOK { $$ = lastCallingConv = OldCallingConv::X86_StdCall; }
+ | X86_FASTCALLCC_TOK { $$ = lastCallingConv = OldCallingConv::X86_FastCall; }
+ | CC_TOK EUINT64VAL {
+ if ((unsigned)$2 != $2)
+ error("Calling conv too large");
+ $$ = lastCallingConv = $2;
+ }
+ ;
+
+// OptAlign/OptCAlign - An optional alignment, and an optional alignment with
+// a comma before it.
+OptAlign
+ : /*empty*/ { $$ = 0; }
+ | ALIGN EUINT64VAL {
+ $$ = $2;
+ if ($$ != 0 && !isPowerOf2_32($$))
+ error("Alignment must be a power of two");
+ }
+ ;
+
+OptCAlign
+ : /*empty*/ { $$ = 0; }
+ | ',' ALIGN EUINT64VAL {
+ $$ = $3;
+ if ($$ != 0 && !isPowerOf2_32($$))
+ error("Alignment must be a power of two");
+ }
+ ;
+
+SectionString
+ : SECTION STRINGCONSTANT {
+ for (unsigned i = 0, e = strlen($2); i != e; ++i)
+ if ($2[i] == '"' || $2[i] == '\\')
+ error("Invalid character in section name");
+ $$ = $2;
+ }
+ ;
+
+OptSection
+ : /*empty*/ { $$ = 0; }
+ | SectionString { $$ = $1; }
+ ;
+
+// GlobalVarAttributes - Used to pass the attributes string on a global. CurGV
+// is set to be the global we are processing.
+//
+GlobalVarAttributes
+ : /* empty */ {}
+ | ',' GlobalVarAttribute GlobalVarAttributes {}
+ ;
+
+GlobalVarAttribute
+ : SectionString {
+ CurGV->setSection($1);
+ free($1);
+ }
+ | ALIGN EUINT64VAL {
+ if ($2 != 0 && !isPowerOf2_32($2))
+ error("Alignment must be a power of two");
+ CurGV->setAlignment($2);
+
+ }
+ ;
+
+//===----------------------------------------------------------------------===//
+// Types includes all predefined types... except void, because it can only be
+// used in specific contexts (function returning void for example). To have
+// access to it, a user must explicitly use TypesV.
+//
+
+// TypesV includes all of 'Types', but it also includes the void type.
+TypesV
+ : Types
+ | VOID {
+ $$.PAT = new PATypeHolder($1.T);
+ $$.S.makeSignless();
+ }
+ ;
+
+UpRTypesV
+ : UpRTypes
+ | VOID {
+ $$.PAT = new PATypeHolder($1.T);
+ $$.S.makeSignless();
+ }
+ ;
+
+Types
+ : UpRTypes {
+ if (!UpRefs.empty())
+ error("Invalid upreference in type: " + (*$1.PAT)->getDescription());
+ $$ = $1;
+ }
+ ;
+
+PrimType
+ : BOOL | SBYTE | UBYTE | SHORT | USHORT | INT | UINT
+ | LONG | ULONG | FLOAT | DOUBLE | LABEL
+ ;
+
+// Derived types are added later...
+UpRTypes
+ : PrimType {
+ $$.PAT = new PATypeHolder($1.T);
+ $$.S.copy($1.S);
+ }
+ | OPAQUE {
+ $$.PAT = new PATypeHolder(OpaqueType::get());
+ $$.S.makeSignless();
+ }
+ | SymbolicValueRef { // Named types are also simple types...
+ $$.S.copy(getTypeSign($1));
+ const Type* tmp = getType($1);
+ $$.PAT = new PATypeHolder(tmp);
+ }
+ | '\\' EUINT64VAL { // Type UpReference
+ if ($2 > (uint64_t)~0U)
+ error("Value out of range");
+ OpaqueType *OT = OpaqueType::get(); // Use temporary placeholder
+ UpRefs.push_back(UpRefRecord((unsigned)$2, OT)); // Add to vector...
+ $$.PAT = new PATypeHolder(OT);
+ $$.S.makeSignless();
+ UR_OUT("New Upreference!\n");
+ }
+ | UpRTypesV '(' ArgTypeListI ')' { // Function derived type?
+ $$.S.makeComposite($1.S);
+ std::vector<const Type*> Params;
+ for (std::list<llvm::PATypeInfo>::iterator I = $3->begin(),
+ E = $3->end(); I != E; ++I) {
+ Params.push_back(I->PAT->get());
+ $$.S.add(I->S);
+ }
+ bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
+ if (isVarArg) Params.pop_back();
+
+ ParamAttrsList *PAL = 0;
+ if (lastCallingConv == OldCallingConv::CSRet) {
+ ParamAttrsVector Attrs;
+ ParamAttrsWithIndex PAWI;
+ PAWI.index = 1; PAWI.attrs = ParamAttr::StructRet; // first arg
+ Attrs.push_back(PAWI);
+ PAL = ParamAttrsList::get(Attrs);
+ }
+
+ const FunctionType *FTy =
+ FunctionType::get($1.PAT->get(), Params, isVarArg, PAL);
+
+ $$.PAT = new PATypeHolder( HandleUpRefs(FTy, $$.S) );
+ delete $1.PAT; // Delete the return type handle
+ delete $3; // Delete the argument list
+ }
+ | '[' EUINT64VAL 'x' UpRTypes ']' { // Sized array type?
+ $$.S.makeComposite($4.S);
+ $$.PAT = new PATypeHolder(HandleUpRefs(ArrayType::get($4.PAT->get(),
+ (unsigned)$2), $$.S));
+ delete $4.PAT;
+ }
+ | '<' EUINT64VAL 'x' UpRTypes '>' { // Vector type?
+ const llvm::Type* ElemTy = $4.PAT->get();
+ if ((unsigned)$2 != $2)
+ error("Unsigned result not equal to signed result");
+ if (!(ElemTy->isInteger() || ElemTy->isFloatingPoint()))
+ error("Elements of a VectorType must be integer or floating point");
+ if (!isPowerOf2_32($2))
+ error("VectorType length should be a power of 2");
+ $$.S.makeComposite($4.S);
+ $$.PAT = new PATypeHolder(HandleUpRefs(VectorType::get(ElemTy,
+ (unsigned)$2), $$.S));
+ delete $4.PAT;
+ }
+ | '{' TypeListI '}' { // Structure type?
+ std::vector<const Type*> Elements;
+ $$.S.makeComposite();
+ for (std::list<llvm::PATypeInfo>::iterator I = $2->begin(),
+ E = $2->end(); I != E; ++I) {
+ Elements.push_back(I->PAT->get());
+ $$.S.add(I->S);
+ }
+ $$.PAT = new PATypeHolder(HandleUpRefs(StructType::get(Elements), $$.S));
+ delete $2;
+ }
+ | '{' '}' { // Empty structure type?
+ $$.PAT = new PATypeHolder(StructType::get(std::vector<const Type*>()));
+ $$.S.makeComposite();
+ }
+ | '<' '{' TypeListI '}' '>' { // Packed Structure type?
+ $$.S.makeComposite();
+ std::vector<const Type*> Elements;
+ for (std::list<llvm::PATypeInfo>::iterator I = $3->begin(),
+ E = $3->end(); I != E; ++I) {
+ Elements.push_back(I->PAT->get());
+ $$.S.add(I->S);
+ delete I->PAT;
+ }
+ $$.PAT = new PATypeHolder(HandleUpRefs(StructType::get(Elements, true),
+ $$.S));
+ delete $3;
+ }
+ | '<' '{' '}' '>' { // Empty packed structure type?
+ $$.PAT = new PATypeHolder(StructType::get(std::vector<const Type*>(),true));
+ $$.S.makeComposite();
+ }
+ | UpRTypes '*' { // Pointer type?
+ if ($1.PAT->get() == Type::LabelTy)
+ error("Cannot form a pointer to a basic block");
+ $$.S.makeComposite($1.S);
+ $$.PAT = new PATypeHolder(HandleUpRefs(PointerType::get($1.PAT->get()),
+ $$.S));
+ delete $1.PAT;
+ }
+ ;
+
+// TypeList - Used for struct declarations and as a basis for function type
+// declaration type lists
+//
+TypeListI
+ : UpRTypes {
+ $$ = new std::list<PATypeInfo>();
+ $$->push_back($1);
+ }
+ | TypeListI ',' UpRTypes {
+ ($$=$1)->push_back($3);
+ }
+ ;
+
+// ArgTypeList - List of types for a function type declaration...
+ArgTypeListI
+ : TypeListI
+ | TypeListI ',' DOTDOTDOT {
+ PATypeInfo VoidTI;
+ VoidTI.PAT = new PATypeHolder(Type::VoidTy);
+ VoidTI.S.makeSignless();
+ ($$=$1)->push_back(VoidTI);
+ }
+ | DOTDOTDOT {
+ $$ = new std::list<PATypeInfo>();
+ PATypeInfo VoidTI;
+ VoidTI.PAT = new PATypeHolder(Type::VoidTy);
+ VoidTI.S.makeSignless();
+ $$->push_back(VoidTI);
+ }
+ | /*empty*/ {
+ $$ = new std::list<PATypeInfo>();
+ }
+ ;
+
+// ConstVal - The various declarations that go into the constant pool. This
+// production is used ONLY to represent constants that show up AFTER a 'const',
+// 'constant' or 'global' token at global scope. Constants that can be inlined
+// into other expressions (such as integers and constexprs) are handled by the
+// ResolvedVal, ValueRef and ConstValueRef productions.
+//
+ConstVal
+ : Types '[' ConstVector ']' { // Nonempty unsized arr
+ const ArrayType *ATy = dyn_cast<ArrayType>($1.PAT->get());
+ if (ATy == 0)
+ error("Cannot make array constant with type: '" +
+ $1.PAT->get()->getDescription() + "'");
+ const Type *ETy = ATy->getElementType();
+ int NumElements = ATy->getNumElements();
+
+ // Verify that we have the correct size...
+ if (NumElements != -1 && NumElements != (int)$3->size())
+ error("Type mismatch: constant sized array initialized with " +
+ utostr($3->size()) + " arguments, but has size of " +
+ itostr(NumElements) + "");
+
+ // Verify all elements are correct type!
+ std::vector<Constant*> Elems;
+ for (unsigned i = 0; i < $3->size(); i++) {
+ Constant *C = (*$3)[i].C;
+ const Type* ValTy = C->getType();
+ if (ETy != ValTy)
+ error("Element #" + utostr(i) + " is not of type '" +
+ ETy->getDescription() +"' as required!\nIt is of type '"+
+ ValTy->getDescription() + "'");
+ Elems.push_back(C);
+ }
+ $$.C = ConstantArray::get(ATy, Elems);
+ $$.S.copy($1.S);
+ delete $1.PAT;
+ delete $3;
+ }
+ | Types '[' ']' {
+ const ArrayType *ATy = dyn_cast<ArrayType>($1.PAT->get());
+ if (ATy == 0)
+ error("Cannot make array constant with type: '" +
+ $1.PAT->get()->getDescription() + "'");
+ int NumElements = ATy->getNumElements();
+ if (NumElements != -1 && NumElements != 0)
+ error("Type mismatch: constant sized array initialized with 0"
+ " arguments, but has size of " + itostr(NumElements) +"");
+ $$.C = ConstantArray::get(ATy, std::vector<Constant*>());
+ $$.S.copy($1.S);
+ delete $1.PAT;
+ }
+ | Types 'c' STRINGCONSTANT {
+ const ArrayType *ATy = dyn_cast<ArrayType>($1.PAT->get());
+ if (ATy == 0)
+ error("Cannot make array constant with type: '" +
+ $1.PAT->get()->getDescription() + "'");
+ int NumElements = ATy->getNumElements();
+ const Type *ETy = dyn_cast<IntegerType>(ATy->getElementType());
+ if (!ETy || cast<IntegerType>(ETy)->getBitWidth() != 8)
+ error("String arrays require type i8, not '" + ETy->getDescription() +
+ "'");
+ char *EndStr = UnEscapeLexed($3, true);
+ if (NumElements != -1 && NumElements != (EndStr-$3))
+ error("Can't build string constant of size " +
+ itostr((int)(EndStr-$3)) + " when array has size " +
+ itostr(NumElements) + "");
+ std::vector<Constant*> Vals;
+ for (char *C = (char *)$3; C != (char *)EndStr; ++C)
+ Vals.push_back(ConstantInt::get(ETy, *C));
+ free($3);
+ $$.C = ConstantArray::get(ATy, Vals);
+ $$.S.copy($1.S);
+ delete $1.PAT;
+ }
+ | Types '<' ConstVector '>' { // Nonempty unsized arr
+ const VectorType *PTy = dyn_cast<VectorType>($1.PAT->get());
+ if (PTy == 0)
+ error("Cannot make packed constant with type: '" +
+ $1.PAT->get()->getDescription() + "'");
+ const Type *ETy = PTy->getElementType();
+ int NumElements = PTy->getNumElements();
+ // Verify that we have the correct size...
+ if (NumElements != -1 && NumElements != (int)$3->size())
+ error("Type mismatch: constant sized packed initialized with " +
+ utostr($3->size()) + " arguments, but has size of " +
+ itostr(NumElements) + "");
+ // Verify all elements are correct type!
+ std::vector<Constant*> Elems;
+ for (unsigned i = 0; i < $3->size(); i++) {
+ Constant *C = (*$3)[i].C;
+ const Type* ValTy = C->getType();
+ if (ETy != ValTy)
+ error("Element #" + utostr(i) + " is not of type '" +
+ ETy->getDescription() +"' as required!\nIt is of type '"+
+ ValTy->getDescription() + "'");
+ Elems.push_back(C);
+ }
+ $$.C = ConstantVector::get(PTy, Elems);
+ $$.S.copy($1.S);
+ delete $1.PAT;
+ delete $3;
+ }
+ | Types '{' ConstVector '}' {
+ const StructType *STy = dyn_cast<StructType>($1.PAT->get());
+ if (STy == 0)
+ error("Cannot make struct constant with type: '" +
+ $1.PAT->get()->getDescription() + "'");
+ if ($3->size() != STy->getNumContainedTypes())
+ error("Illegal number of initializers for structure type");
+
+ // Check to ensure that constants are compatible with the type initializer!
+ std::vector<Constant*> Fields;
+ for (unsigned i = 0, e = $3->size(); i != e; ++i) {
+ Constant *C = (*$3)[i].C;
+ if (C->getType() != STy->getElementType(i))
+ error("Expected type '" + STy->getElementType(i)->getDescription() +
+ "' for element #" + utostr(i) + " of structure initializer");
+ Fields.push_back(C);
+ }
+ $$.C = ConstantStruct::get(STy, Fields);
+ $$.S.copy($1.S);
+ delete $1.PAT;
+ delete $3;
+ }
+ | Types '{' '}' {
+ const StructType *STy = dyn_cast<StructType>($1.PAT->get());
+ if (STy == 0)
+ error("Cannot make struct constant with type: '" +
+ $1.PAT->get()->getDescription() + "'");
+ if (STy->getNumContainedTypes() != 0)
+ error("Illegal number of initializers for structure type");
+ $$.C = ConstantStruct::get(STy, std::vector<Constant*>());
+ $$.S.copy($1.S);
+ delete $1.PAT;
+ }
+ | Types '<' '{' ConstVector '}' '>' {
+ const StructType *STy = dyn_cast<StructType>($1.PAT->get());
+ if (STy == 0)
+ error("Cannot make packed struct constant with type: '" +
+ $1.PAT->get()->getDescription() + "'");
+ if ($4->size() != STy->getNumContainedTypes())
+ error("Illegal number of initializers for packed structure type");
+
+ // Check to ensure that constants are compatible with the type initializer!
+ std::vector<Constant*> Fields;
+ for (unsigned i = 0, e = $4->size(); i != e; ++i) {
+ Constant *C = (*$4)[i].C;
+ if (C->getType() != STy->getElementType(i))
+ error("Expected type '" + STy->getElementType(i)->getDescription() +
+ "' for element #" + utostr(i) + " of packed struct initializer");
+ Fields.push_back(C);
+ }
+ $$.C = ConstantStruct::get(STy, Fields);
+ $$.S.copy($1.S);
+ delete $1.PAT;
+ delete $4;
+ }
+ | Types '<' '{' '}' '>' {
+ const StructType *STy = dyn_cast<StructType>($1.PAT->get());
+ if (STy == 0)
+ error("Cannot make packed struct constant with type: '" +
+ $1.PAT->get()->getDescription() + "'");
+ if (STy->getNumContainedTypes() != 0)
+ error("Illegal number of initializers for packed structure type");
+ $$.C = ConstantStruct::get(STy, std::vector<Constant*>());
+ $$.S.copy($1.S);
+ delete $1.PAT;
+ }
+ | Types NULL_TOK {
+ const PointerType *PTy = dyn_cast<PointerType>($1.PAT->get());
+ if (PTy == 0)
+ error("Cannot make null pointer constant with type: '" +
+ $1.PAT->get()->getDescription() + "'");
+ $$.C = ConstantPointerNull::get(PTy);
+ $$.S.copy($1.S);
+ delete $1.PAT;
+ }
+ | Types UNDEF {
+ $$.C = UndefValue::get($1.PAT->get());
+ $$.S.copy($1.S);
+ delete $1.PAT;
+ }
+ | Types SymbolicValueRef {
+ const PointerType *Ty = dyn_cast<PointerType>($1.PAT->get());
+ if (Ty == 0)
+ error("Global const reference must be a pointer type, not" +
+ $1.PAT->get()->getDescription());
+
+ // ConstExprs can exist in the body of a function, thus creating
+ // GlobalValues whenever they refer to a variable. Because we are in
+ // the context of a function, getExistingValue will search the functions
+ // symbol table instead of the module symbol table for the global symbol,
+ // which throws things all off. To get around this, we just tell
+ // getExistingValue that we are at global scope here.
+ //
+ Function *SavedCurFn = CurFun.CurrentFunction;
+ CurFun.CurrentFunction = 0;
+ $2.S.copy($1.S);
+ Value *V = getExistingValue(Ty, $2);
+ CurFun.CurrentFunction = SavedCurFn;
+
+ // If this is an initializer for a constant pointer, which is referencing a
+ // (currently) undefined variable, create a stub now that shall be replaced
+ // in the future with the right type of variable.
+ //
+ if (V == 0) {
+ assert(isa<PointerType>(Ty) && "Globals may only be used as pointers");
+ const PointerType *PT = cast<PointerType>(Ty);
+
+ // First check to see if the forward references value is already created!
+ PerModuleInfo::GlobalRefsType::iterator I =
+ CurModule.GlobalRefs.find(std::make_pair(PT, $2));
+
+ if (I != CurModule.GlobalRefs.end()) {
+ V = I->second; // Placeholder already exists, use it...
+ $2.destroy();
+ } else {
+ std::string Name;
+ if ($2.Type == ValID::NameVal) Name = $2.Name;
+
+ // Create the forward referenced global.
+ GlobalValue *GV;
+ if (const FunctionType *FTy =
+ dyn_cast<FunctionType>(PT->getElementType())) {
+ GV = new Function(FTy, GlobalValue::ExternalLinkage, Name,
+ CurModule.CurrentModule);
+ } else {
+ GV = new GlobalVariable(PT->getElementType(), false,
+ GlobalValue::ExternalLinkage, 0,
+ Name, CurModule.CurrentModule);
+ }
+
+ // Keep track of the fact that we have a forward ref to recycle it
+ CurModule.GlobalRefs.insert(std::make_pair(std::make_pair(PT, $2), GV));
+ V = GV;
+ }
+ }
+ $$.C = cast<GlobalValue>(V);
+ $$.S.copy($1.S);
+ delete $1.PAT; // Free the type handle
+ }
+ | Types ConstExpr {
+ if ($1.PAT->get() != $2.C->getType())
+ error("Mismatched types for constant expression");
+ $$ = $2;
+ $$.S.copy($1.S);
+ delete $1.PAT;
+ }
+ | Types ZEROINITIALIZER {
+ const Type *Ty = $1.PAT->get();
+ if (isa<FunctionType>(Ty) || Ty == Type::LabelTy || isa<OpaqueType>(Ty))
+ error("Cannot create a null initialized value of this type");
+ $$.C = Constant::getNullValue(Ty);
+ $$.S.copy($1.S);
+ delete $1.PAT;
+ }
+ | SIntType EINT64VAL { // integral constants
+ const Type *Ty = $1.T;
+ if (!ConstantInt::isValueValidForType(Ty, $2))
+ error("Constant value doesn't fit in type");
+ $$.C = ConstantInt::get(Ty, $2);
+ $$.S.makeSigned();
+ }
+ | UIntType EUINT64VAL { // integral constants
+ const Type *Ty = $1.T;
+ if (!ConstantInt::isValueValidForType(Ty, $2))
+ error("Constant value doesn't fit in type");
+ $$.C = ConstantInt::get(Ty, $2);
+ $$.S.makeUnsigned();
+ }
+ | BOOL TRUETOK { // Boolean constants
+ $$.C = ConstantInt::get(Type::Int1Ty, true);
+ $$.S.makeUnsigned();
+ }
+ | BOOL FALSETOK { // Boolean constants
+ $$.C = ConstantInt::get(Type::Int1Ty, false);
+ $$.S.makeUnsigned();
+ }
+ | FPType FPVAL { // Float & Double constants
+ if (!ConstantFP::isValueValidForType($1.T, $2))
+ error("Floating point constant invalid for type");
+ $$.C = ConstantFP::get($1.T, $2);
+ $$.S.makeSignless();
+ }
+ ;
+
+ConstExpr
+ : CastOps '(' ConstVal TO Types ')' {
+ const Type* SrcTy = $3.C->getType();
+ const Type* DstTy = $5.PAT->get();
+ Signedness SrcSign($3.S);
+ Signedness DstSign($5.S);
+ if (!SrcTy->isFirstClassType())
+ error("cast constant expression from a non-primitive type: '" +
+ SrcTy->getDescription() + "'");
+ if (!DstTy->isFirstClassType())
+ error("cast constant expression to a non-primitive type: '" +
+ DstTy->getDescription() + "'");
+ $$.C = cast<Constant>(getCast($1, $3.C, SrcSign, DstTy, DstSign));
+ $$.S.copy(DstSign);
+ delete $5.PAT;
+ }
+ | GETELEMENTPTR '(' ConstVal IndexList ')' {
+ const Type *Ty = $3.C->getType();
+ if (!isa<PointerType>(Ty))
+ error("GetElementPtr requires a pointer operand");
+
+ std::vector<Constant*> CIndices;
+ upgradeGEPCEIndices($3.C->getType(), $4, CIndices);
+
+ delete $4;
+ $$.C = ConstantExpr::getGetElementPtr($3.C, &CIndices[0], CIndices.size());
+ $$.S.copy(getElementSign($3, CIndices));
+ }
+ | SELECT '(' ConstVal ',' ConstVal ',' ConstVal ')' {
+ if (!$3.C->getType()->isInteger() ||
+ cast<IntegerType>($3.C->getType())->getBitWidth() != 1)
+ error("Select condition must be bool type");
+ if ($5.C->getType() != $7.C->getType())
+ error("Select operand types must match");
+ $$.C = ConstantExpr::getSelect($3.C, $5.C, $7.C);
+ $$.S.copy($5.S);
+ }
+ | ArithmeticOps '(' ConstVal ',' ConstVal ')' {
+ const Type *Ty = $3.C->getType();
+ if (Ty != $5.C->getType())
+ error("Binary operator types must match");
+ // First, make sure we're dealing with the right opcode by upgrading from
+ // obsolete versions.
+ Instruction::BinaryOps Opcode = getBinaryOp($1, Ty, $3.S);
+
+ // HACK: llvm 1.3 and earlier used to emit invalid pointer constant exprs.
+ // To retain backward compatibility with these early compilers, we emit a
+ // cast to the appropriate integer type automatically if we are in the
+ // broken case. See PR424 for more information.
+ if (!isa<PointerType>(Ty)) {
+ $$.C = ConstantExpr::get(Opcode, $3.C, $5.C);
+ } else {
+ const Type *IntPtrTy = 0;
+ switch (CurModule.CurrentModule->getPointerSize()) {
+ case Module::Pointer32: IntPtrTy = Type::Int32Ty; break;
+ case Module::Pointer64: IntPtrTy = Type::Int64Ty; break;
+ default: error("invalid pointer binary constant expr");
+ }
+ $$.C = ConstantExpr::get(Opcode,
+ ConstantExpr::getCast(Instruction::PtrToInt, $3.C, IntPtrTy),
+ ConstantExpr::getCast(Instruction::PtrToInt, $5.C, IntPtrTy));
+ $$.C = ConstantExpr::getCast(Instruction::IntToPtr, $$.C, Ty);
+ }
+ $$.S.copy($3.S);
+ }
+ | LogicalOps '(' ConstVal ',' ConstVal ')' {
+ const Type* Ty = $3.C->getType();
+ if (Ty != $5.C->getType())
+ error("Logical operator types must match");
+ if (!Ty->isInteger()) {
+ if (!isa<VectorType>(Ty) ||
+ !cast<VectorType>(Ty)->getElementType()->isInteger())
+ error("Logical operator requires integer operands");
+ }
+ Instruction::BinaryOps Opcode = getBinaryOp($1, Ty, $3.S);
+ $$.C = ConstantExpr::get(Opcode, $3.C, $5.C);
+ $$.S.copy($3.S);
+ }
+ | SetCondOps '(' ConstVal ',' ConstVal ')' {
+ const Type* Ty = $3.C->getType();
+ if (Ty != $5.C->getType())
+ error("setcc operand types must match");
+ unsigned short pred;
+ Instruction::OtherOps Opcode = getCompareOp($1, pred, Ty, $3.S);
+ $$.C = ConstantExpr::getCompare(Opcode, $3.C, $5.C);
+ $$.S.makeUnsigned();
+ }
+ | ICMP IPredicates '(' ConstVal ',' ConstVal ')' {
+ if ($4.C->getType() != $6.C->getType())
+ error("icmp operand types must match");
+ $$.C = ConstantExpr::getCompare($2, $4.C, $6.C);
+ $$.S.makeUnsigned();
+ }
+ | FCMP FPredicates '(' ConstVal ',' ConstVal ')' {
+ if ($4.C->getType() != $6.C->getType())
+ error("fcmp operand types must match");
+ $$.C = ConstantExpr::getCompare($2, $4.C, $6.C);
+ $$.S.makeUnsigned();
+ }
+ | ShiftOps '(' ConstVal ',' ConstVal ')' {
+ if (!$5.C->getType()->isInteger() ||
+ cast<IntegerType>($5.C->getType())->getBitWidth() != 8)
+ error("Shift count for shift constant must be unsigned byte");
+ const Type* Ty = $3.C->getType();
+ if (!$3.C->getType()->isInteger())
+ error("Shift constant expression requires integer operand");
+ Constant *ShiftAmt = ConstantExpr::getZExt($5.C, Ty);
+ $$.C = ConstantExpr::get(getBinaryOp($1, Ty, $3.S), $3.C, ShiftAmt);
+ $$.S.copy($3.S);
+ }
+ | EXTRACTELEMENT '(' ConstVal ',' ConstVal ')' {
+ if (!ExtractElementInst::isValidOperands($3.C, $5.C))
+ error("Invalid extractelement operands");
+ $$.C = ConstantExpr::getExtractElement($3.C, $5.C);
+ $$.S.copy($3.S.get(0));
+ }
+ | INSERTELEMENT '(' ConstVal ',' ConstVal ',' ConstVal ')' {
+ if (!InsertElementInst::isValidOperands($3.C, $5.C, $7.C))
+ error("Invalid insertelement operands");
+ $$.C = ConstantExpr::getInsertElement($3.C, $5.C, $7.C);
+ $$.S.copy($3.S);
+ }
+ | SHUFFLEVECTOR '(' ConstVal ',' ConstVal ',' ConstVal ')' {
+ if (!ShuffleVectorInst::isValidOperands($3.C, $5.C, $7.C))
+ error("Invalid shufflevector operands");
+ $$.C = ConstantExpr::getShuffleVector($3.C, $5.C, $7.C);
+ $$.S.copy($3.S);
+ }
+ ;
+
+
+// ConstVector - A list of comma separated constants.
+ConstVector
+ : ConstVector ',' ConstVal { ($$ = $1)->push_back($3); }
+ | ConstVal {
+ $$ = new std::vector<ConstInfo>();
+ $$->push_back($1);
+ }
+ ;
+
+
+// GlobalType - Match either GLOBAL or CONSTANT for global declarations...
+GlobalType
+ : GLOBAL { $$ = false; }
+ | CONSTANT { $$ = true; }
+ ;
+
+
+//===----------------------------------------------------------------------===//
+// Rules to match Modules
+//===----------------------------------------------------------------------===//
+
+// Module rule: Capture the result of parsing the whole file into a result
+// variable...
+//
+Module
+ : FunctionList {
+ $$ = ParserResult = $1;
+ CurModule.ModuleDone();
+ }
+ ;
+
+// FunctionList - A list of functions, preceeded by a constant pool.
+//
+FunctionList
+ : FunctionList Function { $$ = $1; CurFun.FunctionDone(); }
+ | FunctionList FunctionProto { $$ = $1; }
+ | FunctionList MODULE ASM_TOK AsmBlock { $$ = $1; }
+ | FunctionList IMPLEMENTATION { $$ = $1; }
+ | ConstPool {
+ $$ = CurModule.CurrentModule;
+ // Emit an error if there are any unresolved types left.
+ if (!CurModule.LateResolveTypes.empty()) {
+ const ValID &DID = CurModule.LateResolveTypes.begin()->first;
+ if (DID.Type == ValID::NameVal) {
+ error("Reference to an undefined type: '"+DID.getName() + "'");
+ } else {
+ error("Reference to an undefined type: #" + itostr(DID.Num));
+ }
+ }
+ }
+ ;
+
+// ConstPool - Constants with optional names assigned to them.
+ConstPool
+ : ConstPool OptAssign TYPE TypesV {
+ // Eagerly resolve types. This is not an optimization, this is a
+ // requirement that is due to the fact that we could have this:
+ //
+ // %list = type { %list * }
+ // %list = type { %list * } ; repeated type decl
+ //
+ // If types are not resolved eagerly, then the two types will not be
+ // determined to be the same type!
+ //
+ ResolveTypeTo($2, $4.PAT->get(), $4.S);
+
+ if (!setTypeName($4, $2) && !$2) {
+ // If this is a numbered type that is not a redefinition, add it to the
+ // slot table.
+ CurModule.Types.push_back($4.PAT->get());
+ CurModule.TypeSigns.push_back($4.S);
+ }
+ delete $4.PAT;
+ }
+ | ConstPool FunctionProto { // Function prototypes can be in const pool
+ }
+ | ConstPool MODULE ASM_TOK AsmBlock { // Asm blocks can be in the const pool
+ }
+ | ConstPool OptAssign OptLinkage GlobalType ConstVal {
+ if ($5.C == 0)
+ error("Global value initializer is not a constant");
+ CurGV = ParseGlobalVariable($2, $3, $4, $5.C->getType(), $5.C, $5.S);
+ } GlobalVarAttributes {
+ CurGV = 0;
+ }
+ | ConstPool OptAssign EXTERNAL GlobalType Types {
+ const Type *Ty = $5.PAT->get();
+ CurGV = ParseGlobalVariable($2, GlobalValue::ExternalLinkage, $4, Ty, 0,
+ $5.S);
+ delete $5.PAT;
+ } GlobalVarAttributes {
+ CurGV = 0;
+ }
+ | ConstPool OptAssign DLLIMPORT GlobalType Types {
+ const Type *Ty = $5.PAT->get();
+ CurGV = ParseGlobalVariable($2, GlobalValue::DLLImportLinkage, $4, Ty, 0,
+ $5.S);
+ delete $5.PAT;
+ } GlobalVarAttributes {
+ CurGV = 0;
+ }
+ | ConstPool OptAssign EXTERN_WEAK GlobalType Types {
+ const Type *Ty = $5.PAT->get();
+ CurGV =
+ ParseGlobalVariable($2, GlobalValue::ExternalWeakLinkage, $4, Ty, 0,
+ $5.S);
+ delete $5.PAT;
+ } GlobalVarAttributes {
+ CurGV = 0;
+ }
+ | ConstPool TARGET TargetDefinition {
+ }
+ | ConstPool DEPLIBS '=' LibrariesDefinition {
+ }
+ | /* empty: end of list */ {
+ }
+ ;
+
+AsmBlock
+ : STRINGCONSTANT {
+ const std::string &AsmSoFar = CurModule.CurrentModule->getModuleInlineAsm();
+ char *EndStr = UnEscapeLexed($1, true);
+ std::string NewAsm($1, EndStr);
+ free($1);
+
+ if (AsmSoFar.empty())
+ CurModule.CurrentModule->setModuleInlineAsm(NewAsm);
+ else
+ CurModule.CurrentModule->setModuleInlineAsm(AsmSoFar+"\n"+NewAsm);
+ }
+ ;
+
+BigOrLittle
+ : BIG { $$ = Module::BigEndian; }
+ | LITTLE { $$ = Module::LittleEndian; }
+ ;
+
+TargetDefinition
+ : ENDIAN '=' BigOrLittle {
+ CurModule.setEndianness($3);
+ }
+ | POINTERSIZE '=' EUINT64VAL {
+ if ($3 == 32)
+ CurModule.setPointerSize(Module::Pointer32);
+ else if ($3 == 64)
+ CurModule.setPointerSize(Module::Pointer64);
+ else
+ error("Invalid pointer size: '" + utostr($3) + "'");
+ }
+ | TRIPLE '=' STRINGCONSTANT {
+ CurModule.CurrentModule->setTargetTriple($3);
+ free($3);
+ }
+ | DATALAYOUT '=' STRINGCONSTANT {
+ CurModule.CurrentModule->setDataLayout($3);
+ free($3);
+ }
+ ;
+
+LibrariesDefinition
+ : '[' LibList ']'
+ ;
+
+LibList
+ : LibList ',' STRINGCONSTANT {
+ CurModule.CurrentModule->addLibrary($3);
+ free($3);
+ }
+ | STRINGCONSTANT {
+ CurModule.CurrentModule->addLibrary($1);
+ free($1);
+ }
+ | /* empty: end of list */ { }
+ ;
+
+//===----------------------------------------------------------------------===//
+// Rules to match Function Headers
+//===----------------------------------------------------------------------===//
+
+Name
+ : VAR_ID | STRINGCONSTANT
+ ;
+
+OptName
+ : Name
+ | /*empty*/ { $$ = 0; }
+ ;
+
+ArgVal
+ : Types OptName {
+ if ($1.PAT->get() == Type::VoidTy)
+ error("void typed arguments are invalid");
+ $$ = new std::pair<PATypeInfo, char*>($1, $2);
+ }
+ ;
+
+ArgListH
+ : ArgListH ',' ArgVal {
+ $$ = $1;
+ $$->push_back(*$3);
+ delete $3;
+ }
+ | ArgVal {
+ $$ = new std::vector<std::pair<PATypeInfo,char*> >();
+ $$->push_back(*$1);
+ delete $1;
+ }
+ ;
+
+ArgList
+ : ArgListH { $$ = $1; }
+ | ArgListH ',' DOTDOTDOT {
+ $$ = $1;
+ PATypeInfo VoidTI;
+ VoidTI.PAT = new PATypeHolder(Type::VoidTy);
+ VoidTI.S.makeSignless();
+ $$->push_back(std::pair<PATypeInfo, char*>(VoidTI, 0));
+ }
+ | DOTDOTDOT {
+ $$ = new std::vector<std::pair<PATypeInfo,char*> >();
+ PATypeInfo VoidTI;
+ VoidTI.PAT = new PATypeHolder(Type::VoidTy);
+ VoidTI.S.makeSignless();
+ $$->push_back(std::pair<PATypeInfo, char*>(VoidTI, 0));
+ }
+ | /* empty */ { $$ = 0; }
+ ;
+
+FunctionHeaderH
+ : OptCallingConv TypesV Name '(' ArgList ')' OptSection OptAlign {
+ UnEscapeLexed($3);
+ std::string FunctionName($3);
+ free($3); // Free strdup'd memory!
+
+ const Type* RetTy = $2.PAT->get();
+
+ if (!RetTy->isFirstClassType() && RetTy != Type::VoidTy)
+ error("LLVM functions cannot return aggregate types");
+
+ Signedness FTySign;
+ FTySign.makeComposite($2.S);
+ std::vector<const Type*> ParamTyList;
+
+ // In LLVM 2.0 the signatures of three varargs intrinsics changed to take
+ // i8*. We check here for those names and override the parameter list
+ // types to ensure the prototype is correct.
+ if (FunctionName == "llvm.va_start" || FunctionName == "llvm.va_end") {
+ ParamTyList.push_back(PointerType::get(Type::Int8Ty));
+ } else if (FunctionName == "llvm.va_copy") {
+ ParamTyList.push_back(PointerType::get(Type::Int8Ty));
+ ParamTyList.push_back(PointerType::get(Type::Int8Ty));
+ } else if ($5) { // If there are arguments...
+ for (std::vector<std::pair<PATypeInfo,char*> >::iterator
+ I = $5->begin(), E = $5->end(); I != E; ++I) {
+ const Type *Ty = I->first.PAT->get();
+ ParamTyList.push_back(Ty);
+ FTySign.add(I->first.S);
+ }
+ }
+
+ bool isVarArg = ParamTyList.size() && ParamTyList.back() == Type::VoidTy;
+ if (isVarArg)
+ ParamTyList.pop_back();
+
+ // Convert the CSRet calling convention into the corresponding parameter
+ // attribute.
+ ParamAttrsList *PAL = 0;
+ if ($1 == OldCallingConv::CSRet) {
+ ParamAttrsVector Attrs;
+ ParamAttrsWithIndex PAWI;
+ PAWI.index = 1; PAWI.attrs = ParamAttr::StructRet; // first arg
+ Attrs.push_back(PAWI);
+ PAL = ParamAttrsList::get(Attrs);
+ }
+
+ const FunctionType *FT =
+ FunctionType::get(RetTy, ParamTyList, isVarArg, PAL);
+ const PointerType *PFT = PointerType::get(FT);
+ delete $2.PAT;
+
+ ValID ID;
+ if (!FunctionName.empty()) {
+ ID = ValID::create((char*)FunctionName.c_str());
+ } else {
+ ID = ValID::create((int)CurModule.Values[PFT].size());
+ }
+ ID.S.makeComposite(FTySign);
+
+ Function *Fn = 0;
+ Module* M = CurModule.CurrentModule;
+
+ // See if this function was forward referenced. If so, recycle the object.
+ if (GlobalValue *FWRef = CurModule.GetForwardRefForGlobal(PFT, ID)) {
+ // Move the function to the end of the list, from whereever it was
+ // previously inserted.
+ Fn = cast<Function>(FWRef);
+ M->getFunctionList().remove(Fn);
+ M->getFunctionList().push_back(Fn);
+ } else if (!FunctionName.empty()) {
+ GlobalValue *Conflict = M->getFunction(FunctionName);
+ if (!Conflict)
+ Conflict = M->getNamedGlobal(FunctionName);
+ if (Conflict && PFT == Conflict->getType()) {
+ if (!CurFun.isDeclare && !Conflict->isDeclaration()) {
+ // We have two function definitions that conflict, same type, same
+ // name. We should really check to make sure that this is the result
+ // of integer type planes collapsing and generate an error if it is
+ // not, but we'll just rename on the assumption that it is. However,
+ // let's do it intelligently and rename the internal linkage one
+ // if there is one.
+ std::string NewName(makeNameUnique(FunctionName));
+ if (Conflict->hasInternalLinkage()) {
+ Conflict->setName(NewName);
+ RenameMapKey Key =
+ makeRenameMapKey(FunctionName, Conflict->getType(), ID.S);
+ CurModule.RenameMap[Key] = NewName;
+ Fn = new Function(FT, CurFun.Linkage, FunctionName, M);
+ InsertValue(Fn, CurModule.Values);
+ } else {
+ Fn = new Function(FT, CurFun.Linkage, NewName, M);
+ InsertValue(Fn, CurModule.Values);
+ RenameMapKey Key =
+ makeRenameMapKey(FunctionName, PFT, ID.S);
+ CurModule.RenameMap[Key] = NewName;
+ }
+ } else {
+ // If they are not both definitions, then just use the function we
+ // found since the types are the same.
+ Fn = cast<Function>(Conflict);
+
+ // Make sure to strip off any argument names so we can't get
+ // conflicts.
+ if (Fn->isDeclaration())
+ for (Function::arg_iterator AI = Fn->arg_begin(),
+ AE = Fn->arg_end(); AI != AE; ++AI)
+ AI->setName("");
+ }
+ } else if (Conflict) {
+ // We have two globals with the same name and different types.
+ // Previously, this was permitted because the symbol table had
+ // "type planes" and names only needed to be distinct within a
+ // type plane. After PR411 was fixed, this is no loner the case.
+ // To resolve this we must rename one of the two.
+ if (Conflict->hasInternalLinkage()) {
+ // We can safely rename the Conflict.
+ RenameMapKey Key =
+ makeRenameMapKey(Conflict->getName(), Conflict->getType(),
+ CurModule.NamedValueSigns[Conflict->getName()]);
+ Conflict->setName(makeNameUnique(Conflict->getName()));
+ CurModule.RenameMap[Key] = Conflict->getName();
+ Fn = new Function(FT, CurFun.Linkage, FunctionName, M);
+ InsertValue(Fn, CurModule.Values);
+ } else {
+ // We can't quietly rename either of these things, but we must
+ // rename one of them. Only if the function's linkage is internal can
+ // we forgo a warning message about the renamed function.
+ std::string NewName = makeNameUnique(FunctionName);
+ if (CurFun.Linkage != GlobalValue::InternalLinkage) {
+ warning("Renaming function '" + FunctionName + "' as '" + NewName +
+ "' may cause linkage errors");
+ }
+ // Elect to rename the thing we're now defining.
+ Fn = new Function(FT, CurFun.Linkage, NewName, M);
+ InsertValue(Fn, CurModule.Values);
+ RenameMapKey Key = makeRenameMapKey(FunctionName, PFT, ID.S);
+ CurModule.RenameMap[Key] = NewName;
+ }
+ } else {
+ // There's no conflict, just define the function
+ Fn = new Function(FT, CurFun.Linkage, FunctionName, M);
+ InsertValue(Fn, CurModule.Values);
+ }
+ } else {
+ // There's no conflict, just define the function
+ Fn = new Function(FT, CurFun.Linkage, FunctionName, M);
+ InsertValue(Fn, CurModule.Values);
+ }
+
+
+ CurFun.FunctionStart(Fn);
+
+ if (CurFun.isDeclare) {
+ // If we have declaration, always overwrite linkage. This will allow us
+ // to correctly handle cases, when pointer to function is passed as
+ // argument to another function.
+ Fn->setLinkage(CurFun.Linkage);
+ }
+ Fn->setCallingConv(upgradeCallingConv($1));
+ Fn->setAlignment($8);
+ if ($7) {
+ Fn->setSection($7);
+ free($7);
+ }
+
+ // Add all of the arguments we parsed to the function...
+ if ($5) { // Is null if empty...
+ if (isVarArg) { // Nuke the last entry
+ assert($5->back().first.PAT->get() == Type::VoidTy &&
+ $5->back().second == 0 && "Not a varargs marker");
+ delete $5->back().first.PAT;
+ $5->pop_back(); // Delete the last entry
+ }
+ Function::arg_iterator ArgIt = Fn->arg_begin();
+ Function::arg_iterator ArgEnd = Fn->arg_end();
+ std::vector<std::pair<PATypeInfo,char*> >::iterator I = $5->begin();
+ std::vector<std::pair<PATypeInfo,char*> >::iterator E = $5->end();
+ for ( ; I != E && ArgIt != ArgEnd; ++I, ++ArgIt) {
+ delete I->first.PAT; // Delete the typeholder...
+ ValueInfo VI; VI.V = ArgIt; VI.S.copy(I->first.S);
+ setValueName(VI, I->second); // Insert arg into symtab...
+ InsertValue(ArgIt);
+ }
+ delete $5; // We're now done with the argument list
+ }
+ lastCallingConv = OldCallingConv::C;
+ }
+ ;
+
+BEGIN
+ : BEGINTOK | '{' // Allow BEGIN or '{' to start a function
+ ;
+
+FunctionHeader
+ : OptLinkage { CurFun.Linkage = $1; } FunctionHeaderH BEGIN {
+ $$ = CurFun.CurrentFunction;
+
+ // Make sure that we keep track of the linkage type even if there was a
+ // previous "declare".
+ $$->setLinkage($1);
+ }
+ ;
+
+END
+ : ENDTOK | '}' // Allow end of '}' to end a function
+ ;
+
+Function
+ : BasicBlockList END {
+ $$ = $1;
+ };
+
+FnDeclareLinkage
+ : /*default*/ { $$ = GlobalValue::ExternalLinkage; }
+ | DLLIMPORT { $$ = GlobalValue::DLLImportLinkage; }
+ | EXTERN_WEAK { $$ = GlobalValue::ExternalWeakLinkage; }
+ ;
+
+FunctionProto
+ : DECLARE { CurFun.isDeclare = true; }
+ FnDeclareLinkage { CurFun.Linkage = $3; } FunctionHeaderH {
+ $$ = CurFun.CurrentFunction;
+ CurFun.FunctionDone();
+
+ }
+ ;
+
+//===----------------------------------------------------------------------===//
+// Rules to match Basic Blocks
+//===----------------------------------------------------------------------===//
+
+OptSideEffect
+ : /* empty */ { $$ = false; }
+ | SIDEEFFECT { $$ = true; }
+ ;
+
+ConstValueRef
+ // A reference to a direct constant
+ : ESINT64VAL { $$ = ValID::create($1); }
+ | EUINT64VAL { $$ = ValID::create($1); }
+ | FPVAL { $$ = ValID::create($1); }
+ | TRUETOK {
+ $$ = ValID::create(ConstantInt::get(Type::Int1Ty, true));
+ $$.S.makeUnsigned();
+ }
+ | FALSETOK {
+ $$ = ValID::create(ConstantInt::get(Type::Int1Ty, false));
+ $$.S.makeUnsigned();
+ }
+ | NULL_TOK { $$ = ValID::createNull(); }
+ | UNDEF { $$ = ValID::createUndef(); }
+ | ZEROINITIALIZER { $$ = ValID::createZeroInit(); }
+ | '<' ConstVector '>' { // Nonempty unsized packed vector
+ const Type *ETy = (*$2)[0].C->getType();
+ int NumElements = $2->size();
+ VectorType* pt = VectorType::get(ETy, NumElements);
+ $$.S.makeComposite((*$2)[0].S);
+ PATypeHolder* PTy = new PATypeHolder(HandleUpRefs(pt, $$.S));
+
+ // Verify all elements are correct type!
+ std::vector<Constant*> Elems;
+ for (unsigned i = 0; i < $2->size(); i++) {
+ Constant *C = (*$2)[i].C;
+ const Type *CTy = C->getType();
+ if (ETy != CTy)
+ error("Element #" + utostr(i) + " is not of type '" +
+ ETy->getDescription() +"' as required!\nIt is of type '" +
+ CTy->getDescription() + "'");
+ Elems.push_back(C);
+ }
+ $$ = ValID::create(ConstantVector::get(pt, Elems));
+ delete PTy; delete $2;
+ }
+ | ConstExpr {
+ $$ = ValID::create($1.C);
+ $$.S.copy($1.S);
+ }
+ | ASM_TOK OptSideEffect STRINGCONSTANT ',' STRINGCONSTANT {
+ char *End = UnEscapeLexed($3, true);
+ std::string AsmStr = std::string($3, End);
+ End = UnEscapeLexed($5, true);
+ std::string Constraints = std::string($5, End);
+ $$ = ValID::createInlineAsm(AsmStr, Constraints, $2);
+ free($3);
+ free($5);
+ }
+ ;
+
+// SymbolicValueRef - Reference to one of two ways of symbolically refering to // another value.
+//
+SymbolicValueRef
+ : INTVAL { $$ = ValID::create($1); $$.S.makeSignless(); }
+ | Name { $$ = ValID::create($1); $$.S.makeSignless(); }
+ ;
+
+// ValueRef - A reference to a definition... either constant or symbolic
+ValueRef
+ : SymbolicValueRef | ConstValueRef
+ ;
+
+
+// ResolvedVal - a <type> <value> pair. This is used only in cases where the
+// type immediately preceeds the value reference, and allows complex constant
+// pool references (for things like: 'ret [2 x int] [ int 12, int 42]')
+ResolvedVal
+ : Types ValueRef {
+ const Type *Ty = $1.PAT->get();
+ $2.S.copy($1.S);
+ $$.V = getVal(Ty, $2);
+ $$.S.copy($1.S);
+ delete $1.PAT;
+ }
+ ;
+
+BasicBlockList
+ : BasicBlockList BasicBlock {
+ $$ = $1;
+ }
+ | FunctionHeader BasicBlock { // Do not allow functions with 0 basic blocks
+ $$ = $1;
+ };
+
+
+// Basic blocks are terminated by branching instructions:
+// br, br/cc, switch, ret
+//
+BasicBlock
+ : InstructionList OptAssign BBTerminatorInst {
+ ValueInfo VI; VI.V = $3.TI; VI.S.copy($3.S);
+ setValueName(VI, $2);
+ InsertValue($3.TI);
+ $1->getInstList().push_back($3.TI);
+ InsertValue($1);
+ $$ = $1;
+ }
+ ;
+
+InstructionList
+ : InstructionList Inst {
+ if ($2.I)
+ $1->getInstList().push_back($2.I);
+ $$ = $1;
+ }
+ | /* empty */ {
+ $$ = CurBB = getBBVal(ValID::create((int)CurFun.NextBBNum++),true);
+ // Make sure to move the basic block to the correct location in the
+ // function, instead of leaving it inserted wherever it was first
+ // referenced.
+ Function::BasicBlockListType &BBL =
+ CurFun.CurrentFunction->getBasicBlockList();
+ BBL.splice(BBL.end(), BBL, $$);
+ }
+ | LABELSTR {
+ $$ = CurBB = getBBVal(ValID::create($1), true);
+ // Make sure to move the basic block to the correct location in the
+ // function, instead of leaving it inserted wherever it was first
+ // referenced.
+ Function::BasicBlockListType &BBL =
+ CurFun.CurrentFunction->getBasicBlockList();
+ BBL.splice(BBL.end(), BBL, $$);
+ }
+ ;
+
+Unwind : UNWIND | EXCEPT;
+
+BBTerminatorInst
+ : RET ResolvedVal { // Return with a result...
+ $$.TI = new ReturnInst($2.V);
+ $$.S.makeSignless();
+ }
+ | RET VOID { // Return with no result...
+ $$.TI = new ReturnInst();
+ $$.S.makeSignless();
+ }
+ | BR LABEL ValueRef { // Unconditional Branch...
+ BasicBlock* tmpBB = getBBVal($3);
+ $$.TI = new BranchInst(tmpBB);
+ $$.S.makeSignless();
+ } // Conditional Branch...
+ | BR BOOL ValueRef ',' LABEL ValueRef ',' LABEL ValueRef {
+ $6.S.makeSignless();
+ $9.S.makeSignless();
+ BasicBlock* tmpBBA = getBBVal($6);
+ BasicBlock* tmpBBB = getBBVal($9);
+ $3.S.makeUnsigned();
+ Value* tmpVal = getVal(Type::Int1Ty, $3);
+ $$.TI = new BranchInst(tmpBBA, tmpBBB, tmpVal);
+ $$.S.makeSignless();
+ }
+ | SWITCH IntType ValueRef ',' LABEL ValueRef '[' JumpTable ']' {
+ $3.S.copy($2.S);
+ Value* tmpVal = getVal($2.T, $3);
+ $6.S.makeSignless();
+ BasicBlock* tmpBB = getBBVal($6);
+ SwitchInst *S = new SwitchInst(tmpVal, tmpBB, $8->size());
+ $$.TI = S;
+ $$.S.makeSignless();
+ std::vector<std::pair<Constant*,BasicBlock*> >::iterator I = $8->begin(),
+ E = $8->end();
+ for (; I != E; ++I) {
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(I->first))
+ S->addCase(CI, I->second);
+ else
+ error("Switch case is constant, but not a simple integer");
+ }
+ delete $8;
+ }
+ | SWITCH IntType ValueRef ',' LABEL ValueRef '[' ']' {
+ $3.S.copy($2.S);
+ Value* tmpVal = getVal($2.T, $3);
+ $6.S.makeSignless();
+ BasicBlock* tmpBB = getBBVal($6);
+ SwitchInst *S = new SwitchInst(tmpVal, tmpBB, 0);
+ $$.TI = S;
+ $$.S.makeSignless();
+ }
+ | INVOKE OptCallingConv TypesV ValueRef '(' ValueRefListE ')'
+ TO LABEL ValueRef Unwind LABEL ValueRef {
+ const PointerType *PFTy;
+ const FunctionType *Ty;
+ Signedness FTySign;
+
+ if (!(PFTy = dyn_cast<PointerType>($3.PAT->get())) ||
+ !(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) {
+ // Pull out the types of all of the arguments...
+ std::vector<const Type*> ParamTypes;
+ FTySign.makeComposite($3.S);
+ if ($6) {
+ for (std::vector<ValueInfo>::iterator I = $6->begin(), E = $6->end();
+ I != E; ++I) {
+ ParamTypes.push_back((*I).V->getType());
+ FTySign.add(I->S);
+ }
+ }
+ ParamAttrsList *PAL = 0;
+ if ($2 == OldCallingConv::CSRet) {
+ ParamAttrsVector Attrs;
+ ParamAttrsWithIndex PAWI;
+ PAWI.index = 1; PAWI.attrs = ParamAttr::StructRet; // first arg
+ Attrs.push_back(PAWI);
+ PAL = ParamAttrsList::get(Attrs);
+ }
+ bool isVarArg = ParamTypes.size() && ParamTypes.back() == Type::VoidTy;
+ if (isVarArg) ParamTypes.pop_back();
+ Ty = FunctionType::get($3.PAT->get(), ParamTypes, isVarArg, PAL);
+ PFTy = PointerType::get(Ty);
+ $$.S.copy($3.S);
+ } else {
+ FTySign = $3.S;
+ // Get the signedness of the result type. $3 is the pointer to the
+ // function type so we get the 0th element to extract the function type,
+ // and then the 0th element again to get the result type.
+ $$.S.copy($3.S.get(0).get(0));
+ }
+
+ $4.S.makeComposite(FTySign);
+ Value *V = getVal(PFTy, $4); // Get the function we're calling...
+ BasicBlock *Normal = getBBVal($10);
+ BasicBlock *Except = getBBVal($13);
+
+ // Create the call node...
+ if (!$6) { // Has no arguments?
+ $$.TI = new InvokeInst(V, Normal, Except, 0, 0);
+ } else { // Has arguments?
+ // Loop through FunctionType's arguments and ensure they are specified
+ // correctly!
+ //
+ FunctionType::param_iterator I = Ty->param_begin();
+ FunctionType::param_iterator E = Ty->param_end();
+ std::vector<ValueInfo>::iterator ArgI = $6->begin(), ArgE = $6->end();
+
+ std::vector<Value*> Args;
+ for (; ArgI != ArgE && I != E; ++ArgI, ++I) {
+ if ((*ArgI).V->getType() != *I)
+ error("Parameter " +(*ArgI).V->getName()+ " is not of type '" +
+ (*I)->getDescription() + "'");
+ Args.push_back((*ArgI).V);
+ }
+
+ if (I != E || (ArgI != ArgE && !Ty->isVarArg()))
+ error("Invalid number of parameters detected");
+
+ $$.TI = new InvokeInst(V, Normal, Except, &Args[0], Args.size());
+ }
+ cast<InvokeInst>($$.TI)->setCallingConv(upgradeCallingConv($2));
+ delete $3.PAT;
+ delete $6;
+ lastCallingConv = OldCallingConv::C;
+ }
+ | Unwind {
+ $$.TI = new UnwindInst();
+ $$.S.makeSignless();
+ }
+ | UNREACHABLE {
+ $$.TI = new UnreachableInst();
+ $$.S.makeSignless();
+ }
+ ;
+
+JumpTable
+ : JumpTable IntType ConstValueRef ',' LABEL ValueRef {
+ $$ = $1;
+ $3.S.copy($2.S);
+ Constant *V = cast<Constant>(getExistingValue($2.T, $3));
+
+ if (V == 0)
+ error("May only switch on a constant pool value");
+
+ $6.S.makeSignless();
+ BasicBlock* tmpBB = getBBVal($6);
+ $$->push_back(std::make_pair(V, tmpBB));
+ }
+ | IntType ConstValueRef ',' LABEL ValueRef {
+ $$ = new std::vector<std::pair<Constant*, BasicBlock*> >();
+ $2.S.copy($1.S);
+ Constant *V = cast<Constant>(getExistingValue($1.T, $2));
+
+ if (V == 0)
+ error("May only switch on a constant pool value");
+
+ $5.S.makeSignless();
+ BasicBlock* tmpBB = getBBVal($5);
+ $$->push_back(std::make_pair(V, tmpBB));
+ }
+ ;
+
+Inst
+ : OptAssign InstVal {
+ bool omit = false;
+ if ($1)
+ if (BitCastInst *BCI = dyn_cast<BitCastInst>($2.I))
+ if (BCI->getSrcTy() == BCI->getDestTy() &&
+ BCI->getOperand(0)->getName() == $1)
+ // This is a useless bit cast causing a name redefinition. It is
+ // a bit cast from a type to the same type of an operand with the
+ // same name as the name we would give this instruction. Since this
+ // instruction results in no code generation, it is safe to omit
+ // the instruction. This situation can occur because of collapsed
+ // type planes. For example:
+ // %X = add int %Y, %Z
+ // %X = cast int %Y to uint
+ // After upgrade, this looks like:
+ // %X = add i32 %Y, %Z
+ // %X = bitcast i32 to i32
+ // The bitcast is clearly useless so we omit it.
+ omit = true;
+ if (omit) {
+ $$.I = 0;
+ $$.S.makeSignless();
+ } else {
+ ValueInfo VI; VI.V = $2.I; VI.S.copy($2.S);
+ setValueName(VI, $1);
+ InsertValue($2.I);
+ $$ = $2;
+ }
+ };
+
+PHIList : Types '[' ValueRef ',' ValueRef ']' { // Used for PHI nodes
+ $$.P = new std::list<std::pair<Value*, BasicBlock*> >();
+ $$.S.copy($1.S);
+ $3.S.copy($1.S);
+ Value* tmpVal = getVal($1.PAT->get(), $3);
+ $5.S.makeSignless();
+ BasicBlock* tmpBB = getBBVal($5);
+ $$.P->push_back(std::make_pair(tmpVal, tmpBB));
+ delete $1.PAT;
+ }
+ | PHIList ',' '[' ValueRef ',' ValueRef ']' {
+ $$ = $1;
+ $4.S.copy($1.S);
+ Value* tmpVal = getVal($1.P->front().first->getType(), $4);
+ $6.S.makeSignless();
+ BasicBlock* tmpBB = getBBVal($6);
+ $1.P->push_back(std::make_pair(tmpVal, tmpBB));
+ }
+ ;
+
+ValueRefList : ResolvedVal { // Used for call statements, and memory insts...
+ $$ = new std::vector<ValueInfo>();
+ $$->push_back($1);
+ }
+ | ValueRefList ',' ResolvedVal {
+ $$ = $1;
+ $1->push_back($3);
+ };
+
+// ValueRefListE - Just like ValueRefList, except that it may also be empty!
+ValueRefListE
+ : ValueRefList
+ | /*empty*/ { $$ = 0; }
+ ;
+
+OptTailCall
+ : TAIL CALL {
+ $$ = true;
+ }
+ | CALL {
+ $$ = false;
+ }
+ ;
+
+InstVal
+ : ArithmeticOps Types ValueRef ',' ValueRef {
+ $3.S.copy($2.S);
+ $5.S.copy($2.S);
+ const Type* Ty = $2.PAT->get();
+ if (!Ty->isInteger() && !Ty->isFloatingPoint() && !isa<VectorType>(Ty))
+ error("Arithmetic operator requires integer, FP, or packed operands");
+ if (isa<VectorType>(Ty) &&
+ ($1 == URemOp || $1 == SRemOp || $1 == FRemOp || $1 == RemOp))
+ error("Remainder not supported on vector types");
+ // Upgrade the opcode from obsolete versions before we do anything with it.
+ Instruction::BinaryOps Opcode = getBinaryOp($1, Ty, $2.S);
+ Value* val1 = getVal(Ty, $3);
+ Value* val2 = getVal(Ty, $5);
+ $$.I = BinaryOperator::create(Opcode, val1, val2);
+ if ($$.I == 0)
+ error("binary operator returned null");
+ $$.S.copy($2.S);
+ delete $2.PAT;
+ }
+ | LogicalOps Types ValueRef ',' ValueRef {
+ $3.S.copy($2.S);
+ $5.S.copy($2.S);
+ const Type *Ty = $2.PAT->get();
+ if (!Ty->isInteger()) {
+ if (!isa<VectorType>(Ty) ||
+ !cast<VectorType>(Ty)->getElementType()->isInteger())
+ error("Logical operator requires integral operands");
+ }
+ Instruction::BinaryOps Opcode = getBinaryOp($1, Ty, $2.S);
+ Value* tmpVal1 = getVal(Ty, $3);
+ Value* tmpVal2 = getVal(Ty, $5);
+ $$.I = BinaryOperator::create(Opcode, tmpVal1, tmpVal2);
+ if ($$.I == 0)
+ error("binary operator returned null");
+ $$.S.copy($2.S);
+ delete $2.PAT;
+ }
+ | SetCondOps Types ValueRef ',' ValueRef {
+ $3.S.copy($2.S);
+ $5.S.copy($2.S);
+ const Type* Ty = $2.PAT->get();
+ if(isa<VectorType>(Ty))
+ error("VectorTypes currently not supported in setcc instructions");
+ unsigned short pred;
+ Instruction::OtherOps Opcode = getCompareOp($1, pred, Ty, $2.S);
+ Value* tmpVal1 = getVal(Ty, $3);
+ Value* tmpVal2 = getVal(Ty, $5);
+ $$.I = CmpInst::create(Opcode, pred, tmpVal1, tmpVal2);
+ if ($$.I == 0)
+ error("binary operator returned null");
+ $$.S.makeUnsigned();
+ delete $2.PAT;
+ }
+ | ICMP IPredicates Types ValueRef ',' ValueRef {
+ $4.S.copy($3.S);
+ $6.S.copy($3.S);
+ const Type *Ty = $3.PAT->get();
+ if (isa<VectorType>(Ty))
+ error("VectorTypes currently not supported in icmp instructions");
+ else if (!Ty->isInteger() && !isa<PointerType>(Ty))
+ error("icmp requires integer or pointer typed operands");
+ Value* tmpVal1 = getVal(Ty, $4);
+ Value* tmpVal2 = getVal(Ty, $6);
+ $$.I = new ICmpInst($2, tmpVal1, tmpVal2);
+ $$.S.makeUnsigned();
+ delete $3.PAT;
+ }
+ | FCMP FPredicates Types ValueRef ',' ValueRef {
+ $4.S.copy($3.S);
+ $6.S.copy($3.S);
+ const Type *Ty = $3.PAT->get();
+ if (isa<VectorType>(Ty))
+ error("VectorTypes currently not supported in fcmp instructions");
+ else if (!Ty->isFloatingPoint())
+ error("fcmp instruction requires floating point operands");
+ Value* tmpVal1 = getVal(Ty, $4);
+ Value* tmpVal2 = getVal(Ty, $6);
+ $$.I = new FCmpInst($2, tmpVal1, tmpVal2);
+ $$.S.makeUnsigned();
+ delete $3.PAT;
+ }
+ | NOT ResolvedVal {
+ warning("Use of obsolete 'not' instruction: Replacing with 'xor");
+ const Type *Ty = $2.V->getType();
+ Value *Ones = ConstantInt::getAllOnesValue(Ty);
+ if (Ones == 0)
+ error("Expected integral type for not instruction");
+ $$.I = BinaryOperator::create(Instruction::Xor, $2.V, Ones);
+ if ($$.I == 0)
+ error("Could not create a xor instruction");
+ $$.S.copy($2.S);
+ }
+ | ShiftOps ResolvedVal ',' ResolvedVal {
+ if (!$4.V->getType()->isInteger() ||
+ cast<IntegerType>($4.V->getType())->getBitWidth() != 8)
+ error("Shift amount must be int8");
+ const Type* Ty = $2.V->getType();
+ if (!Ty->isInteger())
+ error("Shift constant expression requires integer operand");
+ Value* ShiftAmt = 0;
+ if (cast<IntegerType>(Ty)->getBitWidth() > Type::Int8Ty->getBitWidth())
+ if (Constant *C = dyn_cast<Constant>($4.V))
+ ShiftAmt = ConstantExpr::getZExt(C, Ty);
+ else
+ ShiftAmt = new ZExtInst($4.V, Ty, makeNameUnique("shift"), CurBB);
+ else
+ ShiftAmt = $4.V;
+ $$.I = BinaryOperator::create(getBinaryOp($1, Ty, $2.S), $2.V, ShiftAmt);
+ $$.S.copy($2.S);
+ }
+ | CastOps ResolvedVal TO Types {
+ const Type *DstTy = $4.PAT->get();
+ if (!DstTy->isFirstClassType())
+ error("cast instruction to a non-primitive type: '" +
+ DstTy->getDescription() + "'");
+ $$.I = cast<Instruction>(getCast($1, $2.V, $2.S, DstTy, $4.S, true));
+ $$.S.copy($4.S);
+ delete $4.PAT;
+ }
+ | SELECT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
+ if (!$2.V->getType()->isInteger() ||
+ cast<IntegerType>($2.V->getType())->getBitWidth() != 1)
+ error("select condition must be bool");
+ if ($4.V->getType() != $6.V->getType())
+ error("select value types should match");
+ $$.I = new SelectInst($2.V, $4.V, $6.V);
+ $$.S.copy($4.S);
+ }
+ | VAARG ResolvedVal ',' Types {
+ const Type *Ty = $4.PAT->get();
+ NewVarArgs = true;
+ $$.I = new VAArgInst($2.V, Ty);
+ $$.S.copy($4.S);
+ delete $4.PAT;
+ }
+ | VAARG_old ResolvedVal ',' Types {
+ const Type* ArgTy = $2.V->getType();
+ const Type* DstTy = $4.PAT->get();
+ ObsoleteVarArgs = true;
+ Function* NF = cast<Function>(CurModule.CurrentModule->
+ getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, (Type *)0));
+
+ //b = vaarg a, t ->
+ //foo = alloca 1 of t
+ //bar = vacopy a
+ //store bar -> foo
+ //b = vaarg foo, t
+ AllocaInst* foo = new AllocaInst(ArgTy, 0, "vaarg.fix");
+ CurBB->getInstList().push_back(foo);
+ CallInst* bar = new CallInst(NF, $2.V);
+ CurBB->getInstList().push_back(bar);
+ CurBB->getInstList().push_back(new StoreInst(bar, foo));
+ $$.I = new VAArgInst(foo, DstTy);
+ $$.S.copy($4.S);
+ delete $4.PAT;
+ }
+ | VANEXT_old ResolvedVal ',' Types {
+ const Type* ArgTy = $2.V->getType();
+ const Type* DstTy = $4.PAT->get();
+ ObsoleteVarArgs = true;
+ Function* NF = cast<Function>(CurModule.CurrentModule->
+ getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, (Type *)0));
+
+ //b = vanext a, t ->
+ //foo = alloca 1 of t
+ //bar = vacopy a
+ //store bar -> foo
+ //tmp = vaarg foo, t
+ //b = load foo
+ AllocaInst* foo = new AllocaInst(ArgTy, 0, "vanext.fix");
+ CurBB->getInstList().push_back(foo);
+ CallInst* bar = new CallInst(NF, $2.V);
+ CurBB->getInstList().push_back(bar);
+ CurBB->getInstList().push_back(new StoreInst(bar, foo));
+ Instruction* tmp = new VAArgInst(foo, DstTy);
+ CurBB->getInstList().push_back(tmp);
+ $$.I = new LoadInst(foo);
+ $$.S.copy($4.S);
+ delete $4.PAT;
+ }
+ | EXTRACTELEMENT ResolvedVal ',' ResolvedVal {
+ if (!ExtractElementInst::isValidOperands($2.V, $4.V))
+ error("Invalid extractelement operands");
+ $$.I = new ExtractElementInst($2.V, $4.V);
+ $$.S.copy($2.S.get(0));
+ }
+ | INSERTELEMENT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
+ if (!InsertElementInst::isValidOperands($2.V, $4.V, $6.V))
+ error("Invalid insertelement operands");
+ $$.I = new InsertElementInst($2.V, $4.V, $6.V);
+ $$.S.copy($2.S);
+ }
+ | SHUFFLEVECTOR ResolvedVal ',' ResolvedVal ',' ResolvedVal {
+ if (!ShuffleVectorInst::isValidOperands($2.V, $4.V, $6.V))
+ error("Invalid shufflevector operands");
+ $$.I = new ShuffleVectorInst($2.V, $4.V, $6.V);
+ $$.S.copy($2.S);
+ }
+ | PHI_TOK PHIList {
+ const Type *Ty = $2.P->front().first->getType();
+ if (!Ty->isFirstClassType())
+ error("PHI node operands must be of first class type");
+ PHINode *PHI = new PHINode(Ty);
+ PHI->reserveOperandSpace($2.P->size());
+ while ($2.P->begin() != $2.P->end()) {
+ if ($2.P->front().first->getType() != Ty)
+ error("All elements of a PHI node must be of the same type");
+ PHI->addIncoming($2.P->front().first, $2.P->front().second);
+ $2.P->pop_front();
+ }
+ $$.I = PHI;
+ $$.S.copy($2.S);
+ delete $2.P; // Free the list...
+ }
+ | OptTailCall OptCallingConv TypesV ValueRef '(' ValueRefListE ')' {
+ // Handle the short call syntax
+ const PointerType *PFTy;
+ const FunctionType *FTy;
+ Signedness FTySign;
+ if (!(PFTy = dyn_cast<PointerType>($3.PAT->get())) ||
+ !(FTy = dyn_cast<FunctionType>(PFTy->getElementType()))) {
+ // Pull out the types of all of the arguments...
+ std::vector<const Type*> ParamTypes;
+ FTySign.makeComposite($3.S);
+ if ($6) {
+ for (std::vector<ValueInfo>::iterator I = $6->begin(), E = $6->end();
+ I != E; ++I) {
+ ParamTypes.push_back((*I).V->getType());
+ FTySign.add(I->S);
+ }
+ }
+
+ bool isVarArg = ParamTypes.size() && ParamTypes.back() == Type::VoidTy;
+ if (isVarArg) ParamTypes.pop_back();
+
+ const Type *RetTy = $3.PAT->get();
+ if (!RetTy->isFirstClassType() && RetTy != Type::VoidTy)
+ error("Functions cannot return aggregate types");
+
+ // Deal with CSRetCC
+ ParamAttrsList *PAL = 0;
+ if ($2 == OldCallingConv::CSRet) {
+ ParamAttrsVector Attrs;
+ ParamAttrsWithIndex PAWI;
+ PAWI.index = 1; PAWI.attrs = ParamAttr::StructRet; // first arg
+ Attrs.push_back(PAWI);
+ PAL = ParamAttrsList::get(Attrs);
+ }
+
+ FTy = FunctionType::get(RetTy, ParamTypes, isVarArg, PAL);
+ PFTy = PointerType::get(FTy);
+ $$.S.copy($3.S);
+ } else {
+ FTySign = $3.S;
+ // Get the signedness of the result type. $3 is the pointer to the
+ // function type so we get the 0th element to extract the function type,
+ // and then the 0th element again to get the result type.
+ $$.S.copy($3.S.get(0).get(0));
+ }
+ $4.S.makeComposite(FTySign);
+
+ // First upgrade any intrinsic calls.
+ std::vector<Value*> Args;
+ if ($6)
+ for (unsigned i = 0, e = $6->size(); i < e; ++i)
+ Args.push_back((*$6)[i].V);
+ Instruction *Inst = upgradeIntrinsicCall(FTy->getReturnType(), $4, Args);
+
+ // If we got an upgraded intrinsic
+ if (Inst) {
+ $$.I = Inst;
+ } else {
+ // Get the function we're calling
+ Value *V = getVal(PFTy, $4);
+
+ // Check the argument values match
+ if (!$6) { // Has no arguments?
+ // Make sure no arguments is a good thing!
+ if (FTy->getNumParams() != 0)
+ error("No arguments passed to a function that expects arguments");
+ } else { // Has arguments?
+ // Loop through FunctionType's arguments and ensure they are specified
+ // correctly!
+ //
+ FunctionType::param_iterator I = FTy->param_begin();
+ FunctionType::param_iterator E = FTy->param_end();
+ std::vector<ValueInfo>::iterator ArgI = $6->begin(), ArgE = $6->end();
+
+ for (; ArgI != ArgE && I != E; ++ArgI, ++I)
+ if ((*ArgI).V->getType() != *I)
+ error("Parameter " +(*ArgI).V->getName()+ " is not of type '" +
+ (*I)->getDescription() + "'");
+
+ if (I != E || (ArgI != ArgE && !FTy->isVarArg()))
+ error("Invalid number of parameters detected");
+ }
+
+ // Create the call instruction
+ CallInst *CI = new CallInst(V, &Args[0], Args.size());
+ CI->setTailCall($1);
+ CI->setCallingConv(upgradeCallingConv($2));
+ $$.I = CI;
+ }
+ delete $3.PAT;
+ delete $6;
+ lastCallingConv = OldCallingConv::C;
+ }
+ | MemoryInst {
+ $$ = $1;
+ }
+ ;
+
+
+// IndexList - List of indices for GEP based instructions...
+IndexList
+ : ',' ValueRefList { $$ = $2; }
+ | /* empty */ { $$ = new std::vector<ValueInfo>(); }
+ ;
+
+OptVolatile
+ : VOLATILE { $$ = true; }
+ | /* empty */ { $$ = false; }
+ ;
+
+MemoryInst
+ : MALLOC Types OptCAlign {
+ const Type *Ty = $2.PAT->get();
+ $$.S.makeComposite($2.S);
+ $$.I = new MallocInst(Ty, 0, $3);
+ delete $2.PAT;
+ }
+ | MALLOC Types ',' UINT ValueRef OptCAlign {
+ const Type *Ty = $2.PAT->get();
+ $5.S.makeUnsigned();
+ $$.S.makeComposite($2.S);
+ $$.I = new MallocInst(Ty, getVal($4.T, $5), $6);
+ delete $2.PAT;
+ }
+ | ALLOCA Types OptCAlign {
+ const Type *Ty = $2.PAT->get();
+ $$.S.makeComposite($2.S);
+ $$.I = new AllocaInst(Ty, 0, $3);
+ delete $2.PAT;
+ }
+ | ALLOCA Types ',' UINT ValueRef OptCAlign {
+ const Type *Ty = $2.PAT->get();
+ $5.S.makeUnsigned();
+ $$.S.makeComposite($4.S);
+ $$.I = new AllocaInst(Ty, getVal($4.T, $5), $6);
+ delete $2.PAT;
+ }
+ | FREE ResolvedVal {
+ const Type *PTy = $2.V->getType();
+ if (!isa<PointerType>(PTy))
+ error("Trying to free nonpointer type '" + PTy->getDescription() + "'");
+ $$.I = new FreeInst($2.V);
+ $$.S.makeSignless();
+ }
+ | OptVolatile LOAD Types ValueRef {
+ const Type* Ty = $3.PAT->get();
+ $4.S.copy($3.S);
+ if (!isa<PointerType>(Ty))
+ error("Can't load from nonpointer type: " + Ty->getDescription());
+ if (!cast<PointerType>(Ty)->getElementType()->isFirstClassType())
+ error("Can't load from pointer of non-first-class type: " +
+ Ty->getDescription());
+ Value* tmpVal = getVal(Ty, $4);
+ $$.I = new LoadInst(tmpVal, "", $1);
+ $$.S.copy($3.S.get(0));
+ delete $3.PAT;
+ }
+ | OptVolatile STORE ResolvedVal ',' Types ValueRef {
+ $6.S.copy($5.S);
+ const PointerType *PTy = dyn_cast<PointerType>($5.PAT->get());
+ if (!PTy)
+ error("Can't store to a nonpointer type: " +
+ $5.PAT->get()->getDescription());
+ const Type *ElTy = PTy->getElementType();
+ Value *StoreVal = $3.V;
+ Value* tmpVal = getVal(PTy, $6);
+ if (ElTy != $3.V->getType()) {
+ StoreVal = handleSRetFuncTypeMerge($3.V, ElTy);
+ if (!StoreVal)
+ error("Can't store '" + $3.V->getType()->getDescription() +
+ "' into space of type '" + ElTy->getDescription() + "'");
+ else {
+ PTy = PointerType::get(StoreVal->getType());
+ if (Constant *C = dyn_cast<Constant>(tmpVal))
+ tmpVal = ConstantExpr::getBitCast(C, PTy);
+ else
+ tmpVal = new BitCastInst(tmpVal, PTy, "upgrd.cast", CurBB);
+ }
+ }
+ $$.I = new StoreInst(StoreVal, tmpVal, $1);
+ $$.S.makeSignless();
+ delete $5.PAT;
+ }
+ | GETELEMENTPTR Types ValueRef IndexList {
+ $3.S.copy($2.S);
+ const Type* Ty = $2.PAT->get();
+ if (!isa<PointerType>(Ty))
+ error("getelementptr insn requires pointer operand");
+
+ std::vector<Value*> VIndices;
+ upgradeGEPInstIndices(Ty, $4, VIndices);
+
+ Value* tmpVal = getVal(Ty, $3);
+ $$.I = new GetElementPtrInst(tmpVal, &VIndices[0], VIndices.size());
+ ValueInfo VI; VI.V = tmpVal; VI.S.copy($2.S);
+ $$.S.copy(getElementSign(VI, VIndices));
+ delete $2.PAT;
+ delete $4;
+ };
+
+
+%%
+
+int yyerror(const char *ErrorMsg) {
+ std::string where
+ = std::string((CurFilename == "-") ? std::string("<stdin>") : CurFilename)
+ + ":" + llvm::utostr((unsigned) Upgradelineno) + ": ";
+ std::string errMsg = where + "error: " + std::string(ErrorMsg);
+ if (yychar != YYEMPTY && yychar != 0)
+ errMsg += " while reading token '" + std::string(Upgradetext, Upgradeleng) +
+ "'.";
+ std::cerr << "llvm-upgrade: " << errMsg << '\n';
+ std::cout << "llvm-upgrade: parse failed.\n";
+ exit(1);
+}
+
+void warning(const std::string& ErrorMsg) {
+ std::string where
+ = std::string((CurFilename == "-") ? std::string("<stdin>") : CurFilename)
+ + ":" + llvm::utostr((unsigned) Upgradelineno) + ": ";
+ std::string errMsg = where + "warning: " + std::string(ErrorMsg);
+ if (yychar != YYEMPTY && yychar != 0)
+ errMsg += " while reading token '" + std::string(Upgradetext, Upgradeleng) +
+ "'.";
+ std::cerr << "llvm-upgrade: " << errMsg << '\n';
+}
+
+void error(const std::string& ErrorMsg, int LineNo) {
+ if (LineNo == -1) LineNo = Upgradelineno;
+ Upgradelineno = LineNo;
+ yyerror(ErrorMsg.c_str());
+}
+
diff --git a/tools/llvm-upgrade/llvm-upgrade.cpp b/tools/llvm-upgrade/llvm-upgrade.cpp
new file mode 100644
index 0000000..9425e3e
--- /dev/null
+++ b/tools/llvm-upgrade/llvm-upgrade.cpp
@@ -0,0 +1,144 @@
+//===--- llvm-upgrade.cpp - The LLVM Assembly Upgrader --------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This utility will upgrade LLVM 1.9 Assembly to 2.0 format. It may be
+// invoked as a filter, like this:
+// llvm-1.9/bin/llvm-dis < 1.9.bc | llvm-upgrade | llvm-as > 2.0.bc
+//
+// or, you can directly upgrade, like this:
+// llvm-upgrade -o 2.0.ll < 1.9.ll
+//
+// llvm-upgrade won't overwrite files by default. Use -f to force it to
+// overwrite the output file.
+//
+//===----------------------------------------------------------------------===//
+
+#include "UpgradeInternals.h"
+#include "llvm/Module.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/Streams.h"
+#include "llvm/Support/SystemUtils.h"
+#include "llvm/System/Signals.h"
+#include <fstream>
+#include <iostream>
+#include <memory>
+using namespace llvm;
+
+static cl::opt<std::string>
+InputFilename(cl::Positional, cl::desc("<input .llvm file>"), cl::init("-"));
+
+static cl::opt<std::string>
+OutputFilename("o", cl::desc("Override output filename"),
+ cl::value_desc("filename"), cl::init("-"));
+
+static cl::opt<bool>
+Force("f", cl::desc("Overwrite output files"), cl::init(false));
+
+static cl::opt<bool>
+AddAttrs("add-attrs", cl::desc("Add function result and argument attributes"),
+ cl::init(false));
+
+static cl::opt<bool>
+Debug("debug-upgrade-yacc", cl::desc("Print debug output from yacc parser"),
+ cl::Hidden, cl::init(false));
+
+int main(int argc, char **argv) {
+ llvm_shutdown_obj X; // Call llvm_shutdown() on exit.
+ cl::ParseCommandLineOptions(argc, argv, " llvm .ll -> .bc assembler\n");
+ sys::PrintStackTraceOnErrorSignal();
+
+ int exitCode = 0;
+ std::ostream *Out = 0;
+ std::istream *In = 0;
+ try {
+ if (OutputFilename != "") { // Specified an output filename?
+ if (OutputFilename != "-") { // Not stdout?
+ if (!Force && std::ifstream(OutputFilename.c_str())) {
+ // If force is not specified, make sure not to overwrite a file!
+ cerr << argv[0] << ": error opening '" << OutputFilename
+ << "': file exists!\n"
+ << "Use -f command line argument to force output\n";
+ return 1;
+ }
+ Out = new std::ofstream(OutputFilename.c_str(), std::ios::out |
+ std::ios::trunc);
+ } else { // Specified stdout
+ Out = &std::cout;
+ }
+ } else {
+ if (InputFilename == "-") {
+ OutputFilename = "-";
+ Out = &std::cout;
+ } else {
+ std::string IFN = InputFilename;
+ int Len = IFN.length();
+ if (IFN[Len-3] == '.' && IFN[Len-2] == 'l' && IFN[Len-1] == 'l') {
+ // Source ends in .ll
+ OutputFilename = std::string(IFN.begin(), IFN.end()-3);
+ } else {
+ OutputFilename = IFN; // Append to it
+ }
+ OutputFilename += ".llu";
+
+ if (!Force && std::ifstream(OutputFilename.c_str())) {
+ // If force is not specified, make sure not to overwrite a file!
+ cerr << argv[0] << ": error opening '" << OutputFilename
+ << "': file exists!\n"
+ << "Use -f command line argument to force output\n";
+ return 1;
+ }
+
+ Out = new std::ofstream(OutputFilename.c_str(), std::ios::out |
+ std::ios::trunc);
+ // Make sure that the Out file gets unlinked from the disk if we get a
+ // SIGINT
+ sys::RemoveFileOnSignal(sys::Path(OutputFilename));
+ }
+ }
+
+ if (InputFilename == "-") {
+ In = &std::cin;
+ InputFilename = "<stdin>";
+ } else {
+ In = new std::ifstream(InputFilename.c_str());
+ }
+
+ if (!Out->good()) {
+ cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
+ return 1;
+ }
+
+ if (!In->good()) {
+ cerr << argv[0] << ": error opening " << InputFilename << "!\n";
+ return 1;
+ }
+
+ Module *M = UpgradeAssembly(InputFilename, *In, Debug, AddAttrs);
+ if (!M) {
+ cerr << argv[0] << ": No module returned from assembly parsing\n";
+ *Out << argv[0] << ": parse failed.";
+ exit(1);
+ }
+
+ // Finally, print the module on the output stream.
+ M->print(Out);
+
+ } catch (const std::string& caught_message) {
+ cerr << argv[0] << ": " << caught_message << "\n";
+ exitCode = 1;
+ } catch (...) {
+ cerr << argv[0] << ": Unexpected unknown exception occurred.\n";
+ exitCode = 1;
+ }
+
+ if (Out != &std::cout) delete Out;
+ return exitCode;
+}
+
diff --git a/tools/llvm2cpp/CppWriter.cpp b/tools/llvm2cpp/CppWriter.cpp
new file mode 100644
index 0000000..b1ba001
--- /dev/null
+++ b/tools/llvm2cpp/CppWriter.cpp
@@ -0,0 +1,1884 @@
+//===-- CppWriter.cpp - Printing LLVM IR as a C++ Source File -------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the writing of the LLVM IR as a set of C++ calls to the
+// LLVM IR interface. The input module is assumed to be verified.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CallingConv.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/InlineAsm.h"
+#include "llvm/Instruction.h"
+#include "llvm/Instructions.h"
+#include "llvm/ParameterAttributes.h"
+#include "llvm/Module.h"
+#include "llvm/TypeSymbolTable.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/CFG.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Config/config.h"
+#include <algorithm>
+#include <iostream>
+#include <set>
+
+using namespace llvm;
+
+static cl::opt<std::string>
+FuncName("funcname", cl::desc("Specify the name of the generated function"),
+ cl::value_desc("function name"));
+
+enum WhatToGenerate {
+ GenProgram,
+ GenModule,
+ GenContents,
+ GenFunction,
+ GenInline,
+ GenVariable,
+ GenType
+};
+
+static cl::opt<WhatToGenerate> GenerationType(cl::Optional,
+ cl::desc("Choose what kind of output to generate"),
+ cl::init(GenProgram),
+ cl::values(
+ clEnumValN(GenProgram, "gen-program", "Generate a complete program"),
+ clEnumValN(GenModule, "gen-module", "Generate a module definition"),
+ clEnumValN(GenContents,"gen-contents", "Generate contents of a module"),
+ clEnumValN(GenFunction,"gen-function", "Generate a function definition"),
+ clEnumValN(GenInline, "gen-inline", "Generate an inline function"),
+ clEnumValN(GenVariable,"gen-variable", "Generate a variable definition"),
+ clEnumValN(GenType, "gen-type", "Generate a type definition"),
+ clEnumValEnd
+ )
+);
+
+static cl::opt<std::string> NameToGenerate("for", cl::Optional,
+ cl::desc("Specify the name of the thing to generate"),
+ cl::init("!bad!"));
+
+namespace {
+typedef std::vector<const Type*> TypeList;
+typedef std::map<const Type*,std::string> TypeMap;
+typedef std::map<const Value*,std::string> ValueMap;
+typedef std::set<std::string> NameSet;
+typedef std::set<const Type*> TypeSet;
+typedef std::set<const Value*> ValueSet;
+typedef std::map<const Value*,std::string> ForwardRefMap;
+
+class CppWriter {
+ const char* progname;
+ std::ostream &Out;
+ const Module *TheModule;
+ uint64_t uniqueNum;
+ TypeMap TypeNames;
+ ValueMap ValueNames;
+ TypeMap UnresolvedTypes;
+ TypeList TypeStack;
+ NameSet UsedNames;
+ TypeSet DefinedTypes;
+ ValueSet DefinedValues;
+ ForwardRefMap ForwardRefs;
+ bool is_inline;
+
+public:
+ inline CppWriter(std::ostream &o, const Module *M, const char* pn="llvm2cpp")
+ : progname(pn), Out(o), TheModule(M), uniqueNum(0), TypeNames(),
+ ValueNames(), UnresolvedTypes(), TypeStack(), is_inline(false) { }
+
+ const Module* getModule() { return TheModule; }
+
+ void printProgram(const std::string& fname, const std::string& modName );
+ void printModule(const std::string& fname, const std::string& modName );
+ void printContents(const std::string& fname, const std::string& modName );
+ void printFunction(const std::string& fname, const std::string& funcName );
+ void printInline(const std::string& fname, const std::string& funcName );
+ void printVariable(const std::string& fname, const std::string& varName );
+ void printType(const std::string& fname, const std::string& typeName );
+
+ void error(const std::string& msg);
+
+private:
+ void printLinkageType(GlobalValue::LinkageTypes LT);
+ void printCallingConv(unsigned cc);
+ void printEscapedString(const std::string& str);
+ void printCFP(const ConstantFP* CFP);
+
+ std::string getCppName(const Type* val);
+ inline void printCppName(const Type* val);
+
+ std::string getCppName(const Value* val);
+ inline void printCppName(const Value* val);
+
+ bool printTypeInternal(const Type* Ty);
+ inline void printType(const Type* Ty);
+ void printTypes(const Module* M);
+
+ void printConstant(const Constant *CPV);
+ void printConstants(const Module* M);
+
+ void printVariableUses(const GlobalVariable *GV);
+ void printVariableHead(const GlobalVariable *GV);
+ void printVariableBody(const GlobalVariable *GV);
+
+ void printFunctionUses(const Function *F);
+ void printFunctionHead(const Function *F);
+ void printFunctionBody(const Function *F);
+ void printInstruction(const Instruction *I, const std::string& bbname);
+ std::string getOpName(Value*);
+
+ void printModuleBody();
+
+};
+
+static unsigned indent_level = 0;
+inline std::ostream& nl(std::ostream& Out, int delta = 0) {
+ Out << "\n";
+ if (delta >= 0 || indent_level >= unsigned(-delta))
+ indent_level += delta;
+ for (unsigned i = 0; i < indent_level; ++i)
+ Out << " ";
+ return Out;
+}
+
+inline void in() { indent_level++; }
+inline void out() { if (indent_level >0) indent_level--; }
+
+inline void
+sanitize(std::string& str) {
+ for (size_t i = 0; i < str.length(); ++i)
+ if (!isalnum(str[i]) && str[i] != '_')
+ str[i] = '_';
+}
+
+inline std::string
+getTypePrefix(const Type* Ty ) {
+ switch (Ty->getTypeID()) {
+ case Type::VoidTyID: return "void_";
+ case Type::IntegerTyID:
+ return std::string("int") + utostr(cast<IntegerType>(Ty)->getBitWidth()) +
+ "_";
+ case Type::FloatTyID: return "float_";
+ case Type::DoubleTyID: return "double_";
+ case Type::LabelTyID: return "label_";
+ case Type::FunctionTyID: return "func_";
+ case Type::StructTyID: return "struct_";
+ case Type::ArrayTyID: return "array_";
+ case Type::PointerTyID: return "ptr_";
+ case Type::VectorTyID: return "packed_";
+ case Type::OpaqueTyID: return "opaque_";
+ default: return "other_";
+ }
+ return "unknown_";
+}
+
+// Looks up the type in the symbol table and returns a pointer to its name or
+// a null pointer if it wasn't found. Note that this isn't the same as the
+// Mode::getTypeName function which will return an empty string, not a null
+// pointer if the name is not found.
+inline const std::string*
+findTypeName(const TypeSymbolTable& ST, const Type* Ty)
+{
+ TypeSymbolTable::const_iterator TI = ST.begin();
+ TypeSymbolTable::const_iterator TE = ST.end();
+ for (;TI != TE; ++TI)
+ if (TI->second == Ty)
+ return &(TI->first);
+ return 0;
+}
+
+void
+CppWriter::error(const std::string& msg) {
+ std::cerr << progname << ": " << msg << "\n";
+ exit(2);
+}
+
+// printCFP - Print a floating point constant .. very carefully :)
+// This makes sure that conversion to/from floating yields the same binary
+// result so that we don't lose precision.
+void
+CppWriter::printCFP(const ConstantFP *CFP) {
+ Out << "ConstantFP::get(";
+ if (CFP->getType() == Type::DoubleTy)
+ Out << "Type::DoubleTy, ";
+ else
+ Out << "Type::FloatTy, ";
+#if HAVE_PRINTF_A
+ char Buffer[100];
+ sprintf(Buffer, "%A", CFP->getValue());
+ if ((!strncmp(Buffer, "0x", 2) ||
+ !strncmp(Buffer, "-0x", 3) ||
+ !strncmp(Buffer, "+0x", 3)) &&
+ (atof(Buffer) == CFP->getValue()))
+ if (CFP->getType() == Type::DoubleTy)
+ Out << "BitsToDouble(" << Buffer << ")";
+ else
+ Out << "BitsToFloat(" << Buffer << ")";
+ else {
+#endif
+ std::string StrVal = ftostr(CFP->getValue());
+
+ while (StrVal[0] == ' ')
+ StrVal.erase(StrVal.begin());
+
+ // Check to make sure that the stringized number is not some string like
+ // "Inf" or NaN. Check that the string matches the "[-+]?[0-9]" regex.
+ if (((StrVal[0] >= '0' && StrVal[0] <= '9') ||
+ ((StrVal[0] == '-' || StrVal[0] == '+') &&
+ (StrVal[1] >= '0' && StrVal[1] <= '9'))) &&
+ (atof(StrVal.c_str()) == CFP->getValue()))
+ if (CFP->getType() == Type::DoubleTy)
+ Out << StrVal;
+ else
+ Out << StrVal;
+ else if (CFP->getType() == Type::DoubleTy)
+ Out << "BitsToDouble(0x" << std::hex << DoubleToBits(CFP->getValue())
+ << std::dec << "ULL) /* " << StrVal << " */";
+ else
+ Out << "BitsToFloat(0x" << std::hex << FloatToBits(CFP->getValue())
+ << std::dec << "U) /* " << StrVal << " */";
+#if HAVE_PRINTF_A
+ }
+#endif
+ Out << ")";
+}
+
+void
+CppWriter::printCallingConv(unsigned cc){
+ // Print the calling convention.
+ switch (cc) {
+ case CallingConv::C: Out << "CallingConv::C"; break;
+ case CallingConv::Fast: Out << "CallingConv::Fast"; break;
+ case CallingConv::Cold: Out << "CallingConv::Cold"; break;
+ case CallingConv::FirstTargetCC: Out << "CallingConv::FirstTargetCC"; break;
+ default: Out << cc; break;
+ }
+}
+
+void
+CppWriter::printLinkageType(GlobalValue::LinkageTypes LT) {
+ switch (LT) {
+ case GlobalValue::InternalLinkage:
+ Out << "GlobalValue::InternalLinkage"; break;
+ case GlobalValue::LinkOnceLinkage:
+ Out << "GlobalValue::LinkOnceLinkage "; break;
+ case GlobalValue::WeakLinkage:
+ Out << "GlobalValue::WeakLinkage"; break;
+ case GlobalValue::AppendingLinkage:
+ Out << "GlobalValue::AppendingLinkage"; break;
+ case GlobalValue::ExternalLinkage:
+ Out << "GlobalValue::ExternalLinkage"; break;
+ case GlobalValue::DLLImportLinkage:
+ Out << "GlobalValue::DLLImportLinkage"; break;
+ case GlobalValue::DLLExportLinkage:
+ Out << "GlobalValue::DLLExportLinkage"; break;
+ case GlobalValue::ExternalWeakLinkage:
+ Out << "GlobalValue::ExternalWeakLinkage"; break;
+ case GlobalValue::GhostLinkage:
+ Out << "GlobalValue::GhostLinkage"; break;
+ }
+}
+
+// printEscapedString - Print each character of the specified string, escaping
+// it if it is not printable or if it is an escape char.
+void
+CppWriter::printEscapedString(const std::string &Str) {
+ for (unsigned i = 0, e = Str.size(); i != e; ++i) {
+ unsigned char C = Str[i];
+ if (isprint(C) && C != '"' && C != '\\') {
+ Out << C;
+ } else {
+ Out << "\\x"
+ << (char) ((C/16 < 10) ? ( C/16 +'0') : ( C/16 -10+'A'))
+ << (char)(((C&15) < 10) ? ((C&15)+'0') : ((C&15)-10+'A'));
+ }
+ }
+}
+
+std::string
+CppWriter::getCppName(const Type* Ty)
+{
+ // First, handle the primitive types .. easy
+ if (Ty->isPrimitiveType() || Ty->isInteger()) {
+ switch (Ty->getTypeID()) {
+ case Type::VoidTyID: return "Type::VoidTy";
+ case Type::IntegerTyID: {
+ unsigned BitWidth = cast<IntegerType>(Ty)->getBitWidth();
+ return "IntegerType::get(" + utostr(BitWidth) + ")";
+ }
+ case Type::FloatTyID: return "Type::FloatTy";
+ case Type::DoubleTyID: return "Type::DoubleTy";
+ case Type::LabelTyID: return "Type::LabelTy";
+ default:
+ error("Invalid primitive type");
+ break;
+ }
+ return "Type::VoidTy"; // shouldn't be returned, but make it sensible
+ }
+
+ // Now, see if we've seen the type before and return that
+ TypeMap::iterator I = TypeNames.find(Ty);
+ if (I != TypeNames.end())
+ return I->second;
+
+ // Okay, let's build a new name for this type. Start with a prefix
+ const char* prefix = 0;
+ switch (Ty->getTypeID()) {
+ case Type::FunctionTyID: prefix = "FuncTy_"; break;
+ case Type::StructTyID: prefix = "StructTy_"; break;
+ case Type::ArrayTyID: prefix = "ArrayTy_"; break;
+ case Type::PointerTyID: prefix = "PointerTy_"; break;
+ case Type::OpaqueTyID: prefix = "OpaqueTy_"; break;
+ case Type::VectorTyID: prefix = "VectorTy_"; break;
+ default: prefix = "OtherTy_"; break; // prevent breakage
+ }
+
+ // See if the type has a name in the symboltable and build accordingly
+ const std::string* tName = findTypeName(TheModule->getTypeSymbolTable(), Ty);
+ std::string name;
+ if (tName)
+ name = std::string(prefix) + *tName;
+ else
+ name = std::string(prefix) + utostr(uniqueNum++);
+ sanitize(name);
+
+ // Save the name
+ return TypeNames[Ty] = name;
+}
+
+void
+CppWriter::printCppName(const Type* Ty)
+{
+ printEscapedString(getCppName(Ty));
+}
+
+std::string
+CppWriter::getCppName(const Value* val) {
+ std::string name;
+ ValueMap::iterator I = ValueNames.find(val);
+ if (I != ValueNames.end() && I->first == val)
+ return I->second;
+
+ if (const GlobalVariable* GV = dyn_cast<GlobalVariable>(val)) {
+ name = std::string("gvar_") +
+ getTypePrefix(GV->getType()->getElementType());
+ } else if (isa<Function>(val)) {
+ name = std::string("func_");
+ } else if (const Constant* C = dyn_cast<Constant>(val)) {
+ name = std::string("const_") + getTypePrefix(C->getType());
+ } else if (const Argument* Arg = dyn_cast<Argument>(val)) {
+ if (is_inline) {
+ unsigned argNum = std::distance(Arg->getParent()->arg_begin(),
+ Function::const_arg_iterator(Arg)) + 1;
+ name = std::string("arg_") + utostr(argNum);
+ NameSet::iterator NI = UsedNames.find(name);
+ if (NI != UsedNames.end())
+ name += std::string("_") + utostr(uniqueNum++);
+ UsedNames.insert(name);
+ return ValueNames[val] = name;
+ } else {
+ name = getTypePrefix(val->getType());
+ }
+ } else {
+ name = getTypePrefix(val->getType());
+ }
+ name += (val->hasName() ? val->getName() : utostr(uniqueNum++));
+ sanitize(name);
+ NameSet::iterator NI = UsedNames.find(name);
+ if (NI != UsedNames.end())
+ name += std::string("_") + utostr(uniqueNum++);
+ UsedNames.insert(name);
+ return ValueNames[val] = name;
+}
+
+void
+CppWriter::printCppName(const Value* val) {
+ printEscapedString(getCppName(val));
+}
+
+bool
+CppWriter::printTypeInternal(const Type* Ty) {
+ // We don't print definitions for primitive types
+ if (Ty->isPrimitiveType() || Ty->isInteger())
+ return false;
+
+ // If we already defined this type, we don't need to define it again.
+ if (DefinedTypes.find(Ty) != DefinedTypes.end())
+ return false;
+
+ // Everything below needs the name for the type so get it now.
+ std::string typeName(getCppName(Ty));
+
+ // Search the type stack for recursion. If we find it, then generate this
+ // as an OpaqueType, but make sure not to do this multiple times because
+ // the type could appear in multiple places on the stack. Once the opaque
+ // definition is issued, it must not be re-issued. Consequently we have to
+ // check the UnresolvedTypes list as well.
+ TypeList::const_iterator TI = std::find(TypeStack.begin(),TypeStack.end(),Ty);
+ if (TI != TypeStack.end()) {
+ TypeMap::const_iterator I = UnresolvedTypes.find(Ty);
+ if (I == UnresolvedTypes.end()) {
+ Out << "PATypeHolder " << typeName << "_fwd = OpaqueType::get();";
+ nl(Out);
+ UnresolvedTypes[Ty] = typeName;
+ }
+ return true;
+ }
+
+ // We're going to print a derived type which, by definition, contains other
+ // types. So, push this one we're printing onto the type stack to assist with
+ // recursive definitions.
+ TypeStack.push_back(Ty);
+
+ // Print the type definition
+ switch (Ty->getTypeID()) {
+ case Type::FunctionTyID: {
+ const FunctionType* FT = cast<FunctionType>(Ty);
+ Out << "std::vector<const Type*>" << typeName << "_args;";
+ nl(Out);
+ FunctionType::param_iterator PI = FT->param_begin();
+ FunctionType::param_iterator PE = FT->param_end();
+ for (; PI != PE; ++PI) {
+ const Type* argTy = static_cast<const Type*>(*PI);
+ bool isForward = printTypeInternal(argTy);
+ std::string argName(getCppName(argTy));
+ Out << typeName << "_args.push_back(" << argName;
+ if (isForward)
+ Out << "_fwd";
+ Out << ");";
+ nl(Out);
+ }
+ const ParamAttrsList *PAL = FT->getParamAttrs();
+ Out << "ParamAttrsList *" << typeName << "_PAL = 0;";
+ nl(Out);
+ if (PAL) {
+ Out << '{'; in(); nl(Out);
+ Out << "ParamAttrsVector Attrs;"; nl(Out);
+ Out << "ParamAttrsWithIndex PAWI;"; nl(Out);
+ for (unsigned i = 0; i < PAL->size(); ++i) {
+ uint16_t index = PAL->getParamIndex(i);
+ uint16_t attrs = PAL->getParamAttrs(index);
+ Out << "PAWI.index = " << index << "; PAWI.attrs = 0 ";
+ if (attrs & ParamAttr::SExt)
+ Out << " | ParamAttr::SExt";
+ if (attrs & ParamAttr::ZExt)
+ Out << " | ParamAttr::ZExt";
+ if (attrs & ParamAttr::NoAlias)
+ Out << " | ParamAttr::NoAlias";
+ if (attrs & ParamAttr::StructRet)
+ Out << " | ParamAttr::StructRet";
+ if (attrs & ParamAttr::InReg)
+ Out << " | ParamAttr::InReg";
+ if (attrs & ParamAttr::NoReturn)
+ Out << " | ParamAttr::NoReturn";
+ if (attrs & ParamAttr::NoUnwind)
+ Out << " | ParamAttr::NoUnwind";
+ Out << ";";
+ nl(Out);
+ Out << "Attrs.push_back(PAWI);";
+ nl(Out);
+ }
+ Out << typeName << "_PAL = ParamAttrsList::get(Attrs);";
+ nl(Out);
+ out(); nl(Out);
+ Out << '}'; nl(Out);
+ }
+ bool isForward = printTypeInternal(FT->getReturnType());
+ std::string retTypeName(getCppName(FT->getReturnType()));
+ Out << "FunctionType* " << typeName << " = FunctionType::get(";
+ in(); nl(Out) << "/*Result=*/" << retTypeName;
+ if (isForward)
+ Out << "_fwd";
+ Out << ",";
+ nl(Out) << "/*Params=*/" << typeName << "_args,";
+ nl(Out) << "/*isVarArg=*/" << (FT->isVarArg() ? "true," : "false,") ;
+ nl(Out) << "/*ParamAttrs=*/" << typeName << "_PAL" << ");";
+ out();
+ nl(Out);
+ break;
+ }
+ case Type::StructTyID: {
+ const StructType* ST = cast<StructType>(Ty);
+ Out << "std::vector<const Type*>" << typeName << "_fields;";
+ nl(Out);
+ StructType::element_iterator EI = ST->element_begin();
+ StructType::element_iterator EE = ST->element_end();
+ for (; EI != EE; ++EI) {
+ const Type* fieldTy = static_cast<const Type*>(*EI);
+ bool isForward = printTypeInternal(fieldTy);
+ std::string fieldName(getCppName(fieldTy));
+ Out << typeName << "_fields.push_back(" << fieldName;
+ if (isForward)
+ Out << "_fwd";
+ Out << ");";
+ nl(Out);
+ }
+ Out << "StructType* " << typeName << " = StructType::get("
+ << typeName << "_fields, /*isPacked=*/"
+ << (ST->isPacked() ? "true" : "false") << ");";
+ nl(Out);
+ break;
+ }
+ case Type::ArrayTyID: {
+ const ArrayType* AT = cast<ArrayType>(Ty);
+ const Type* ET = AT->getElementType();
+ bool isForward = printTypeInternal(ET);
+ std::string elemName(getCppName(ET));
+ Out << "ArrayType* " << typeName << " = ArrayType::get("
+ << elemName << (isForward ? "_fwd" : "")
+ << ", " << utostr(AT->getNumElements()) << ");";
+ nl(Out);
+ break;
+ }
+ case Type::PointerTyID: {
+ const PointerType* PT = cast<PointerType>(Ty);
+ const Type* ET = PT->getElementType();
+ bool isForward = printTypeInternal(ET);
+ std::string elemName(getCppName(ET));
+ Out << "PointerType* " << typeName << " = PointerType::get("
+ << elemName << (isForward ? "_fwd" : "") << ");";
+ nl(Out);
+ break;
+ }
+ case Type::VectorTyID: {
+ const VectorType* PT = cast<VectorType>(Ty);
+ const Type* ET = PT->getElementType();
+ bool isForward = printTypeInternal(ET);
+ std::string elemName(getCppName(ET));
+ Out << "VectorType* " << typeName << " = VectorType::get("
+ << elemName << (isForward ? "_fwd" : "")
+ << ", " << utostr(PT->getNumElements()) << ");";
+ nl(Out);
+ break;
+ }
+ case Type::OpaqueTyID: {
+ Out << "OpaqueType* " << typeName << " = OpaqueType::get();";
+ nl(Out);
+ break;
+ }
+ default:
+ error("Invalid TypeID");
+ }
+
+ // If the type had a name, make sure we recreate it.
+ const std::string* progTypeName =
+ findTypeName(TheModule->getTypeSymbolTable(),Ty);
+ if (progTypeName) {
+ Out << "mod->addTypeName(\"" << *progTypeName << "\", "
+ << typeName << ");";
+ nl(Out);
+ }
+
+ // Pop us off the type stack
+ TypeStack.pop_back();
+
+ // Indicate that this type is now defined.
+ DefinedTypes.insert(Ty);
+
+ // Early resolve as many unresolved types as possible. Search the unresolved
+ // types map for the type we just printed. Now that its definition is complete
+ // we can resolve any previous references to it. This prevents a cascade of
+ // unresolved types.
+ TypeMap::iterator I = UnresolvedTypes.find(Ty);
+ if (I != UnresolvedTypes.end()) {
+ Out << "cast<OpaqueType>(" << I->second
+ << "_fwd.get())->refineAbstractTypeTo(" << I->second << ");";
+ nl(Out);
+ Out << I->second << " = cast<";
+ switch (Ty->getTypeID()) {
+ case Type::FunctionTyID: Out << "FunctionType"; break;
+ case Type::ArrayTyID: Out << "ArrayType"; break;
+ case Type::StructTyID: Out << "StructType"; break;
+ case Type::VectorTyID: Out << "VectorType"; break;
+ case Type::PointerTyID: Out << "PointerType"; break;
+ case Type::OpaqueTyID: Out << "OpaqueType"; break;
+ default: Out << "NoSuchDerivedType"; break;
+ }
+ Out << ">(" << I->second << "_fwd.get());";
+ nl(Out); nl(Out);
+ UnresolvedTypes.erase(I);
+ }
+
+ // Finally, separate the type definition from other with a newline.
+ nl(Out);
+
+ // We weren't a recursive type
+ return false;
+}
+
+// Prints a type definition. Returns true if it could not resolve all the types
+// in the definition but had to use a forward reference.
+void
+CppWriter::printType(const Type* Ty) {
+ assert(TypeStack.empty());
+ TypeStack.clear();
+ printTypeInternal(Ty);
+ assert(TypeStack.empty());
+}
+
+void
+CppWriter::printTypes(const Module* M) {
+
+ // Walk the symbol table and print out all its types
+ const TypeSymbolTable& symtab = M->getTypeSymbolTable();
+ for (TypeSymbolTable::const_iterator TI = symtab.begin(), TE = symtab.end();
+ TI != TE; ++TI) {
+
+ // For primitive types and types already defined, just add a name
+ TypeMap::const_iterator TNI = TypeNames.find(TI->second);
+ if (TI->second->isInteger() || TI->second->isPrimitiveType() ||
+ TNI != TypeNames.end()) {
+ Out << "mod->addTypeName(\"";
+ printEscapedString(TI->first);
+ Out << "\", " << getCppName(TI->second) << ");";
+ nl(Out);
+ // For everything else, define the type
+ } else {
+ printType(TI->second);
+ }
+ }
+
+ // Add all of the global variables to the value table...
+ for (Module::const_global_iterator I = TheModule->global_begin(),
+ E = TheModule->global_end(); I != E; ++I) {
+ if (I->hasInitializer())
+ printType(I->getInitializer()->getType());
+ printType(I->getType());
+ }
+
+ // Add all the functions to the table
+ for (Module::const_iterator FI = TheModule->begin(), FE = TheModule->end();
+ FI != FE; ++FI) {
+ printType(FI->getReturnType());
+ printType(FI->getFunctionType());
+ // Add all the function arguments
+ for(Function::const_arg_iterator AI = FI->arg_begin(),
+ AE = FI->arg_end(); AI != AE; ++AI) {
+ printType(AI->getType());
+ }
+
+ // Add all of the basic blocks and instructions
+ for (Function::const_iterator BB = FI->begin(),
+ E = FI->end(); BB != E; ++BB) {
+ printType(BB->getType());
+ for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E;
+ ++I) {
+ printType(I->getType());
+ for (unsigned i = 0; i < I->getNumOperands(); ++i)
+ printType(I->getOperand(i)->getType());
+ }
+ }
+ }
+}
+
+
+// printConstant - Print out a constant pool entry...
+void CppWriter::printConstant(const Constant *CV) {
+ // First, if the constant is actually a GlobalValue (variable or function) or
+ // its already in the constant list then we've printed it already and we can
+ // just return.
+ if (isa<GlobalValue>(CV) || ValueNames.find(CV) != ValueNames.end())
+ return;
+
+ std::string constName(getCppName(CV));
+ std::string typeName(getCppName(CV->getType()));
+ if (CV->isNullValue()) {
+ Out << "Constant* " << constName << " = Constant::getNullValue("
+ << typeName << ");";
+ nl(Out);
+ return;
+ }
+ if (isa<GlobalValue>(CV)) {
+ // Skip variables and functions, we emit them elsewhere
+ return;
+ }
+ if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
+ Out << "ConstantInt* " << constName << " = ConstantInt::get(APInt("
+ << cast<IntegerType>(CI->getType())->getBitWidth() << ", "
+ << " \"" << CI->getValue().toStringSigned(10) << "\", 10));";
+ } else if (isa<ConstantAggregateZero>(CV)) {
+ Out << "ConstantAggregateZero* " << constName
+ << " = ConstantAggregateZero::get(" << typeName << ");";
+ } else if (isa<ConstantPointerNull>(CV)) {
+ Out << "ConstantPointerNull* " << constName
+ << " = ConstanPointerNull::get(" << typeName << ");";
+ } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
+ Out << "ConstantFP* " << constName << " = ";
+ printCFP(CFP);
+ Out << ";";
+ } else if (const ConstantArray *CA = dyn_cast<ConstantArray>(CV)) {
+ if (CA->isString() && CA->getType()->getElementType() == Type::Int8Ty) {
+ Out << "Constant* " << constName << " = ConstantArray::get(\"";
+ std::string tmp = CA->getAsString();
+ bool nullTerminate = false;
+ if (tmp[tmp.length()-1] == 0) {
+ tmp.erase(tmp.length()-1);
+ nullTerminate = true;
+ }
+ printEscapedString(tmp);
+ // Determine if we want null termination or not.
+ if (nullTerminate)
+ Out << "\", true"; // Indicate that the null terminator should be added.
+ else
+ Out << "\", false";// No null terminator
+ Out << ");";
+ } else {
+ Out << "std::vector<Constant*> " << constName << "_elems;";
+ nl(Out);
+ unsigned N = CA->getNumOperands();
+ for (unsigned i = 0; i < N; ++i) {
+ printConstant(CA->getOperand(i)); // recurse to print operands
+ Out << constName << "_elems.push_back("
+ << getCppName(CA->getOperand(i)) << ");";
+ nl(Out);
+ }
+ Out << "Constant* " << constName << " = ConstantArray::get("
+ << typeName << ", " << constName << "_elems);";
+ }
+ } else if (const ConstantStruct *CS = dyn_cast<ConstantStruct>(CV)) {
+ Out << "std::vector<Constant*> " << constName << "_fields;";
+ nl(Out);
+ unsigned N = CS->getNumOperands();
+ for (unsigned i = 0; i < N; i++) {
+ printConstant(CS->getOperand(i));
+ Out << constName << "_fields.push_back("
+ << getCppName(CS->getOperand(i)) << ");";
+ nl(Out);
+ }
+ Out << "Constant* " << constName << " = ConstantStruct::get("
+ << typeName << ", " << constName << "_fields);";
+ } else if (const ConstantVector *CP = dyn_cast<ConstantVector>(CV)) {
+ Out << "std::vector<Constant*> " << constName << "_elems;";
+ nl(Out);
+ unsigned N = CP->getNumOperands();
+ for (unsigned i = 0; i < N; ++i) {
+ printConstant(CP->getOperand(i));
+ Out << constName << "_elems.push_back("
+ << getCppName(CP->getOperand(i)) << ");";
+ nl(Out);
+ }
+ Out << "Constant* " << constName << " = ConstantVector::get("
+ << typeName << ", " << constName << "_elems);";
+ } else if (isa<UndefValue>(CV)) {
+ Out << "UndefValue* " << constName << " = UndefValue::get("
+ << typeName << ");";
+ } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
+ if (CE->getOpcode() == Instruction::GetElementPtr) {
+ Out << "std::vector<Constant*> " << constName << "_indices;";
+ nl(Out);
+ printConstant(CE->getOperand(0));
+ for (unsigned i = 1; i < CE->getNumOperands(); ++i ) {
+ printConstant(CE->getOperand(i));
+ Out << constName << "_indices.push_back("
+ << getCppName(CE->getOperand(i)) << ");";
+ nl(Out);
+ }
+ Out << "Constant* " << constName
+ << " = ConstantExpr::getGetElementPtr("
+ << getCppName(CE->getOperand(0)) << ", "
+ << "&" << constName << "_indices[0], " << CE->getNumOperands() - 1
+ << " );";
+ } else if (CE->isCast()) {
+ printConstant(CE->getOperand(0));
+ Out << "Constant* " << constName << " = ConstantExpr::getCast(";
+ switch (CE->getOpcode()) {
+ default: assert(0 && "Invalid cast opcode");
+ case Instruction::Trunc: Out << "Instruction::Trunc"; break;
+ case Instruction::ZExt: Out << "Instruction::ZExt"; break;
+ case Instruction::SExt: Out << "Instruction::SExt"; break;
+ case Instruction::FPTrunc: Out << "Instruction::FPTrunc"; break;
+ case Instruction::FPExt: Out << "Instruction::FPExt"; break;
+ case Instruction::FPToUI: Out << "Instruction::FPToUI"; break;
+ case Instruction::FPToSI: Out << "Instruction::FPToSI"; break;
+ case Instruction::UIToFP: Out << "Instruction::UIToFP"; break;
+ case Instruction::SIToFP: Out << "Instruction::SIToFP"; break;
+ case Instruction::PtrToInt: Out << "Instruction::PtrToInt"; break;
+ case Instruction::IntToPtr: Out << "Instruction::IntToPtr"; break;
+ case Instruction::BitCast: Out << "Instruction::BitCast"; break;
+ }
+ Out << ", " << getCppName(CE->getOperand(0)) << ", "
+ << getCppName(CE->getType()) << ");";
+ } else {
+ unsigned N = CE->getNumOperands();
+ for (unsigned i = 0; i < N; ++i ) {
+ printConstant(CE->getOperand(i));
+ }
+ Out << "Constant* " << constName << " = ConstantExpr::";
+ switch (CE->getOpcode()) {
+ case Instruction::Add: Out << "getAdd("; break;
+ case Instruction::Sub: Out << "getSub("; break;
+ case Instruction::Mul: Out << "getMul("; break;
+ case Instruction::UDiv: Out << "getUDiv("; break;
+ case Instruction::SDiv: Out << "getSDiv("; break;
+ case Instruction::FDiv: Out << "getFDiv("; break;
+ case Instruction::URem: Out << "getURem("; break;
+ case Instruction::SRem: Out << "getSRem("; break;
+ case Instruction::FRem: Out << "getFRem("; break;
+ case Instruction::And: Out << "getAnd("; break;
+ case Instruction::Or: Out << "getOr("; break;
+ case Instruction::Xor: Out << "getXor("; break;
+ case Instruction::ICmp:
+ Out << "getICmp(ICmpInst::ICMP_";
+ switch (CE->getPredicate()) {
+ case ICmpInst::ICMP_EQ: Out << "EQ"; break;
+ case ICmpInst::ICMP_NE: Out << "NE"; break;
+ case ICmpInst::ICMP_SLT: Out << "SLT"; break;
+ case ICmpInst::ICMP_ULT: Out << "ULT"; break;
+ case ICmpInst::ICMP_SGT: Out << "SGT"; break;
+ case ICmpInst::ICMP_UGT: Out << "UGT"; break;
+ case ICmpInst::ICMP_SLE: Out << "SLE"; break;
+ case ICmpInst::ICMP_ULE: Out << "ULE"; break;
+ case ICmpInst::ICMP_SGE: Out << "SGE"; break;
+ case ICmpInst::ICMP_UGE: Out << "UGE"; break;
+ default: error("Invalid ICmp Predicate");
+ }
+ break;
+ case Instruction::FCmp:
+ Out << "getFCmp(FCmpInst::FCMP_";
+ switch (CE->getPredicate()) {
+ case FCmpInst::FCMP_FALSE: Out << "FALSE"; break;
+ case FCmpInst::FCMP_ORD: Out << "ORD"; break;
+ case FCmpInst::FCMP_UNO: Out << "UNO"; break;
+ case FCmpInst::FCMP_OEQ: Out << "OEQ"; break;
+ case FCmpInst::FCMP_UEQ: Out << "UEQ"; break;
+ case FCmpInst::FCMP_ONE: Out << "ONE"; break;
+ case FCmpInst::FCMP_UNE: Out << "UNE"; break;
+ case FCmpInst::FCMP_OLT: Out << "OLT"; break;
+ case FCmpInst::FCMP_ULT: Out << "ULT"; break;
+ case FCmpInst::FCMP_OGT: Out << "OGT"; break;
+ case FCmpInst::FCMP_UGT: Out << "UGT"; break;
+ case FCmpInst::FCMP_OLE: Out << "OLE"; break;
+ case FCmpInst::FCMP_ULE: Out << "ULE"; break;
+ case FCmpInst::FCMP_OGE: Out << "OGE"; break;
+ case FCmpInst::FCMP_UGE: Out << "UGE"; break;
+ case FCmpInst::FCMP_TRUE: Out << "TRUE"; break;
+ default: error("Invalid FCmp Predicate");
+ }
+ break;
+ case Instruction::Shl: Out << "getShl("; break;
+ case Instruction::LShr: Out << "getLShr("; break;
+ case Instruction::AShr: Out << "getAShr("; break;
+ case Instruction::Select: Out << "getSelect("; break;
+ case Instruction::ExtractElement: Out << "getExtractElement("; break;
+ case Instruction::InsertElement: Out << "getInsertElement("; break;
+ case Instruction::ShuffleVector: Out << "getShuffleVector("; break;
+ default:
+ error("Invalid constant expression");
+ break;
+ }
+ Out << getCppName(CE->getOperand(0));
+ for (unsigned i = 1; i < CE->getNumOperands(); ++i)
+ Out << ", " << getCppName(CE->getOperand(i));
+ Out << ");";
+ }
+ } else {
+ error("Bad Constant");
+ Out << "Constant* " << constName << " = 0; ";
+ }
+ nl(Out);
+}
+
+void
+CppWriter::printConstants(const Module* M) {
+ // Traverse all the global variables looking for constant initializers
+ for (Module::const_global_iterator I = TheModule->global_begin(),
+ E = TheModule->global_end(); I != E; ++I)
+ if (I->hasInitializer())
+ printConstant(I->getInitializer());
+
+ // Traverse the LLVM functions looking for constants
+ for (Module::const_iterator FI = TheModule->begin(), FE = TheModule->end();
+ FI != FE; ++FI) {
+ // Add all of the basic blocks and instructions
+ for (Function::const_iterator BB = FI->begin(),
+ E = FI->end(); BB != E; ++BB) {
+ for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E;
+ ++I) {
+ for (unsigned i = 0; i < I->getNumOperands(); ++i) {
+ if (Constant* C = dyn_cast<Constant>(I->getOperand(i))) {
+ printConstant(C);
+ }
+ }
+ }
+ }
+ }
+}
+
+void CppWriter::printVariableUses(const GlobalVariable *GV) {
+ nl(Out) << "// Type Definitions";
+ nl(Out);
+ printType(GV->getType());
+ if (GV->hasInitializer()) {
+ Constant* Init = GV->getInitializer();
+ printType(Init->getType());
+ if (Function* F = dyn_cast<Function>(Init)) {
+ nl(Out)<< "/ Function Declarations"; nl(Out);
+ printFunctionHead(F);
+ } else if (GlobalVariable* gv = dyn_cast<GlobalVariable>(Init)) {
+ nl(Out) << "// Global Variable Declarations"; nl(Out);
+ printVariableHead(gv);
+ } else {
+ nl(Out) << "// Constant Definitions"; nl(Out);
+ printConstant(gv);
+ }
+ if (GlobalVariable* gv = dyn_cast<GlobalVariable>(Init)) {
+ nl(Out) << "// Global Variable Definitions"; nl(Out);
+ printVariableBody(gv);
+ }
+ }
+}
+
+void CppWriter::printVariableHead(const GlobalVariable *GV) {
+ nl(Out) << "GlobalVariable* " << getCppName(GV);
+ if (is_inline) {
+ Out << " = mod->getGlobalVariable(";
+ printEscapedString(GV->getName());
+ Out << ", " << getCppName(GV->getType()->getElementType()) << ",true)";
+ nl(Out) << "if (!" << getCppName(GV) << ") {";
+ in(); nl(Out) << getCppName(GV);
+ }
+ Out << " = new GlobalVariable(";
+ nl(Out) << "/*Type=*/";
+ printCppName(GV->getType()->getElementType());
+ Out << ",";
+ nl(Out) << "/*isConstant=*/" << (GV->isConstant()?"true":"false");
+ Out << ",";
+ nl(Out) << "/*Linkage=*/";
+ printLinkageType(GV->getLinkage());
+ Out << ",";
+ nl(Out) << "/*Initializer=*/0, ";
+ if (GV->hasInitializer()) {
+ Out << "// has initializer, specified below";
+ }
+ nl(Out) << "/*Name=*/\"";
+ printEscapedString(GV->getName());
+ Out << "\",";
+ nl(Out) << "mod);";
+ nl(Out);
+
+ if (GV->hasSection()) {
+ printCppName(GV);
+ Out << "->setSection(\"";
+ printEscapedString(GV->getSection());
+ Out << "\");";
+ nl(Out);
+ }
+ if (GV->getAlignment()) {
+ printCppName(GV);
+ Out << "->setAlignment(" << utostr(GV->getAlignment()) << ");";
+ nl(Out);
+ };
+ if (is_inline) {
+ out(); Out << "}"; nl(Out);
+ }
+}
+
+void
+CppWriter::printVariableBody(const GlobalVariable *GV) {
+ if (GV->hasInitializer()) {
+ printCppName(GV);
+ Out << "->setInitializer(";
+ //if (!isa<GlobalValue(GV->getInitializer()))
+ //else
+ Out << getCppName(GV->getInitializer()) << ");";
+ nl(Out);
+ }
+}
+
+std::string
+CppWriter::getOpName(Value* V) {
+ if (!isa<Instruction>(V) || DefinedValues.find(V) != DefinedValues.end())
+ return getCppName(V);
+
+ // See if its alread in the map of forward references, if so just return the
+ // name we already set up for it
+ ForwardRefMap::const_iterator I = ForwardRefs.find(V);
+ if (I != ForwardRefs.end())
+ return I->second;
+
+ // This is a new forward reference. Generate a unique name for it
+ std::string result(std::string("fwdref_") + utostr(uniqueNum++));
+
+ // Yes, this is a hack. An Argument is the smallest instantiable value that
+ // we can make as a placeholder for the real value. We'll replace these
+ // Argument instances later.
+ Out << "Argument* " << result << " = new Argument("
+ << getCppName(V->getType()) << ");";
+ nl(Out);
+ ForwardRefs[V] = result;
+ return result;
+}
+
+// printInstruction - This member is called for each Instruction in a function.
+void
+CppWriter::printInstruction(const Instruction *I, const std::string& bbname) {
+ std::string iName(getCppName(I));
+
+ // Before we emit this instruction, we need to take care of generating any
+ // forward references. So, we get the names of all the operands in advance
+ std::string* opNames = new std::string[I->getNumOperands()];
+ for (unsigned i = 0; i < I->getNumOperands(); i++) {
+ opNames[i] = getOpName(I->getOperand(i));
+ }
+
+ switch (I->getOpcode()) {
+ case Instruction::Ret: {
+ const ReturnInst* ret = cast<ReturnInst>(I);
+ Out << "new ReturnInst("
+ << (ret->getReturnValue() ? opNames[0] + ", " : "") << bbname << ");";
+ break;
+ }
+ case Instruction::Br: {
+ const BranchInst* br = cast<BranchInst>(I);
+ Out << "new BranchInst(" ;
+ if (br->getNumOperands() == 3 ) {
+ Out << opNames[0] << ", "
+ << opNames[1] << ", "
+ << opNames[2] << ", ";
+
+ } else if (br->getNumOperands() == 1) {
+ Out << opNames[0] << ", ";
+ } else {
+ error("Branch with 2 operands?");
+ }
+ Out << bbname << ");";
+ break;
+ }
+ case Instruction::Switch: {
+ const SwitchInst* sw = cast<SwitchInst>(I);
+ Out << "SwitchInst* " << iName << " = new SwitchInst("
+ << opNames[0] << ", "
+ << opNames[1] << ", "
+ << sw->getNumCases() << ", " << bbname << ");";
+ nl(Out);
+ for (unsigned i = 2; i < sw->getNumOperands(); i += 2 ) {
+ Out << iName << "->addCase("
+ << opNames[i] << ", "
+ << opNames[i+1] << ");";
+ nl(Out);
+ }
+ break;
+ }
+ case Instruction::Invoke: {
+ const InvokeInst* inv = cast<InvokeInst>(I);
+ Out << "std::vector<Value*> " << iName << "_params;";
+ nl(Out);
+ for (unsigned i = 3; i < inv->getNumOperands(); ++i) {
+ Out << iName << "_params.push_back("
+ << opNames[i] << ");";
+ nl(Out);
+ }
+ Out << "InvokeInst *" << iName << " = new InvokeInst("
+ << opNames[0] << ", "
+ << opNames[1] << ", "
+ << opNames[2] << ", "
+ << "&" << iName << "_params[0], " << inv->getNumOperands() - 3
+ << ", \"";
+ printEscapedString(inv->getName());
+ Out << "\", " << bbname << ");";
+ nl(Out) << iName << "->setCallingConv(";
+ printCallingConv(inv->getCallingConv());
+ Out << ");";
+ break;
+ }
+ case Instruction::Unwind: {
+ Out << "new UnwindInst("
+ << bbname << ");";
+ break;
+ }
+ case Instruction::Unreachable:{
+ Out << "new UnreachableInst("
+ << bbname << ");";
+ break;
+ }
+ case Instruction::Add:
+ case Instruction::Sub:
+ case Instruction::Mul:
+ case Instruction::UDiv:
+ case Instruction::SDiv:
+ case Instruction::FDiv:
+ case Instruction::URem:
+ case Instruction::SRem:
+ case Instruction::FRem:
+ case Instruction::And:
+ case Instruction::Or:
+ case Instruction::Xor:
+ case Instruction::Shl:
+ case Instruction::LShr:
+ case Instruction::AShr:{
+ Out << "BinaryOperator* " << iName << " = BinaryOperator::create(";
+ switch (I->getOpcode()) {
+ case Instruction::Add: Out << "Instruction::Add"; break;
+ case Instruction::Sub: Out << "Instruction::Sub"; break;
+ case Instruction::Mul: Out << "Instruction::Mul"; break;
+ case Instruction::UDiv:Out << "Instruction::UDiv"; break;
+ case Instruction::SDiv:Out << "Instruction::SDiv"; break;
+ case Instruction::FDiv:Out << "Instruction::FDiv"; break;
+ case Instruction::URem:Out << "Instruction::URem"; break;
+ case Instruction::SRem:Out << "Instruction::SRem"; break;
+ case Instruction::FRem:Out << "Instruction::FRem"; break;
+ case Instruction::And: Out << "Instruction::And"; break;
+ case Instruction::Or: Out << "Instruction::Or"; break;
+ case Instruction::Xor: Out << "Instruction::Xor"; break;
+ case Instruction::Shl: Out << "Instruction::Shl"; break;
+ case Instruction::LShr:Out << "Instruction::LShr"; break;
+ case Instruction::AShr:Out << "Instruction::AShr"; break;
+ default: Out << "Instruction::BadOpCode"; break;
+ }
+ Out << ", " << opNames[0] << ", " << opNames[1] << ", \"";
+ printEscapedString(I->getName());
+ Out << "\", " << bbname << ");";
+ break;
+ }
+ case Instruction::FCmp: {
+ Out << "FCmpInst* " << iName << " = new FCmpInst(";
+ switch (cast<FCmpInst>(I)->getPredicate()) {
+ case FCmpInst::FCMP_FALSE: Out << "FCmpInst::FCMP_FALSE"; break;
+ case FCmpInst::FCMP_OEQ : Out << "FCmpInst::FCMP_OEQ"; break;
+ case FCmpInst::FCMP_OGT : Out << "FCmpInst::FCMP_OGT"; break;
+ case FCmpInst::FCMP_OGE : Out << "FCmpInst::FCMP_OGE"; break;
+ case FCmpInst::FCMP_OLT : Out << "FCmpInst::FCMP_OLT"; break;
+ case FCmpInst::FCMP_OLE : Out << "FCmpInst::FCMP_OLE"; break;
+ case FCmpInst::FCMP_ONE : Out << "FCmpInst::FCMP_ONE"; break;
+ case FCmpInst::FCMP_ORD : Out << "FCmpInst::FCMP_ORD"; break;
+ case FCmpInst::FCMP_UNO : Out << "FCmpInst::FCMP_UNO"; break;
+ case FCmpInst::FCMP_UEQ : Out << "FCmpInst::FCMP_UEQ"; break;
+ case FCmpInst::FCMP_UGT : Out << "FCmpInst::FCMP_UGT"; break;
+ case FCmpInst::FCMP_UGE : Out << "FCmpInst::FCMP_UGE"; break;
+ case FCmpInst::FCMP_ULT : Out << "FCmpInst::FCMP_ULT"; break;
+ case FCmpInst::FCMP_ULE : Out << "FCmpInst::FCMP_ULE"; break;
+ case FCmpInst::FCMP_UNE : Out << "FCmpInst::FCMP_UNE"; break;
+ case FCmpInst::FCMP_TRUE : Out << "FCmpInst::FCMP_TRUE"; break;
+ default: Out << "FCmpInst::BAD_ICMP_PREDICATE"; break;
+ }
+ Out << ", " << opNames[0] << ", " << opNames[1] << ", \"";
+ printEscapedString(I->getName());
+ Out << "\", " << bbname << ");";
+ break;
+ }
+ case Instruction::ICmp: {
+ Out << "ICmpInst* " << iName << " = new ICmpInst(";
+ switch (cast<ICmpInst>(I)->getPredicate()) {
+ case ICmpInst::ICMP_EQ: Out << "ICmpInst::ICMP_EQ"; break;
+ case ICmpInst::ICMP_NE: Out << "ICmpInst::ICMP_NE"; break;
+ case ICmpInst::ICMP_ULE: Out << "ICmpInst::ICMP_ULE"; break;
+ case ICmpInst::ICMP_SLE: Out << "ICmpInst::ICMP_SLE"; break;
+ case ICmpInst::ICMP_UGE: Out << "ICmpInst::ICMP_UGE"; break;
+ case ICmpInst::ICMP_SGE: Out << "ICmpInst::ICMP_SGE"; break;
+ case ICmpInst::ICMP_ULT: Out << "ICmpInst::ICMP_ULT"; break;
+ case ICmpInst::ICMP_SLT: Out << "ICmpInst::ICMP_SLT"; break;
+ case ICmpInst::ICMP_UGT: Out << "ICmpInst::ICMP_UGT"; break;
+ case ICmpInst::ICMP_SGT: Out << "ICmpInst::ICMP_SGT"; break;
+ default: Out << "ICmpInst::BAD_ICMP_PREDICATE"; break;
+ }
+ Out << ", " << opNames[0] << ", " << opNames[1] << ", \"";
+ printEscapedString(I->getName());
+ Out << "\", " << bbname << ");";
+ break;
+ }
+ case Instruction::Malloc: {
+ const MallocInst* mallocI = cast<MallocInst>(I);
+ Out << "MallocInst* " << iName << " = new MallocInst("
+ << getCppName(mallocI->getAllocatedType()) << ", ";
+ if (mallocI->isArrayAllocation())
+ Out << opNames[0] << ", " ;
+ Out << "\"";
+ printEscapedString(mallocI->getName());
+ Out << "\", " << bbname << ");";
+ if (mallocI->getAlignment())
+ nl(Out) << iName << "->setAlignment("
+ << mallocI->getAlignment() << ");";
+ break;
+ }
+ case Instruction::Free: {
+ Out << "FreeInst* " << iName << " = new FreeInst("
+ << getCppName(I->getOperand(0)) << ", " << bbname << ");";
+ break;
+ }
+ case Instruction::Alloca: {
+ const AllocaInst* allocaI = cast<AllocaInst>(I);
+ Out << "AllocaInst* " << iName << " = new AllocaInst("
+ << getCppName(allocaI->getAllocatedType()) << ", ";
+ if (allocaI->isArrayAllocation())
+ Out << opNames[0] << ", ";
+ Out << "\"";
+ printEscapedString(allocaI->getName());
+ Out << "\", " << bbname << ");";
+ if (allocaI->getAlignment())
+ nl(Out) << iName << "->setAlignment("
+ << allocaI->getAlignment() << ");";
+ break;
+ }
+ case Instruction::Load:{
+ const LoadInst* load = cast<LoadInst>(I);
+ Out << "LoadInst* " << iName << " = new LoadInst("
+ << opNames[0] << ", \"";
+ printEscapedString(load->getName());
+ Out << "\", " << (load->isVolatile() ? "true" : "false" )
+ << ", " << bbname << ");";
+ break;
+ }
+ case Instruction::Store: {
+ const StoreInst* store = cast<StoreInst>(I);
+ Out << "StoreInst* " << iName << " = new StoreInst("
+ << opNames[0] << ", "
+ << opNames[1] << ", "
+ << (store->isVolatile() ? "true" : "false")
+ << ", " << bbname << ");";
+ break;
+ }
+ case Instruction::GetElementPtr: {
+ const GetElementPtrInst* gep = cast<GetElementPtrInst>(I);
+ if (gep->getNumOperands() <= 2) {
+ Out << "GetElementPtrInst* " << iName << " = new GetElementPtrInst("
+ << opNames[0];
+ if (gep->getNumOperands() == 2)
+ Out << ", " << opNames[1];
+ } else {
+ Out << "std::vector<Value*> " << iName << "_indices;";
+ nl(Out);
+ for (unsigned i = 1; i < gep->getNumOperands(); ++i ) {
+ Out << iName << "_indices.push_back("
+ << opNames[i] << ");";
+ nl(Out);
+ }
+ Out << "Instruction* " << iName << " = new GetElementPtrInst("
+ << opNames[0] << ", &" << iName << "_indices[0], "
+ << gep->getNumOperands() - 1;
+ }
+ Out << ", \"";
+ printEscapedString(gep->getName());
+ Out << "\", " << bbname << ");";
+ break;
+ }
+ case Instruction::PHI: {
+ const PHINode* phi = cast<PHINode>(I);
+
+ Out << "PHINode* " << iName << " = new PHINode("
+ << getCppName(phi->getType()) << ", \"";
+ printEscapedString(phi->getName());
+ Out << "\", " << bbname << ");";
+ nl(Out) << iName << "->reserveOperandSpace("
+ << phi->getNumIncomingValues()
+ << ");";
+ nl(Out);
+ for (unsigned i = 0; i < phi->getNumOperands(); i+=2) {
+ Out << iName << "->addIncoming("
+ << opNames[i] << ", " << opNames[i+1] << ");";
+ nl(Out);
+ }
+ break;
+ }
+ case Instruction::Trunc:
+ case Instruction::ZExt:
+ case Instruction::SExt:
+ case Instruction::FPTrunc:
+ case Instruction::FPExt:
+ case Instruction::FPToUI:
+ case Instruction::FPToSI:
+ case Instruction::UIToFP:
+ case Instruction::SIToFP:
+ case Instruction::PtrToInt:
+ case Instruction::IntToPtr:
+ case Instruction::BitCast: {
+ const CastInst* cst = cast<CastInst>(I);
+ Out << "CastInst* " << iName << " = new ";
+ switch (I->getOpcode()) {
+ case Instruction::Trunc: Out << "TruncInst"; break;
+ case Instruction::ZExt: Out << "ZExtInst"; break;
+ case Instruction::SExt: Out << "SExtInst"; break;
+ case Instruction::FPTrunc: Out << "FPTruncInst"; break;
+ case Instruction::FPExt: Out << "FPExtInst"; break;
+ case Instruction::FPToUI: Out << "FPToUIInst"; break;
+ case Instruction::FPToSI: Out << "FPToSIInst"; break;
+ case Instruction::UIToFP: Out << "UIToFPInst"; break;
+ case Instruction::SIToFP: Out << "SIToFPInst"; break;
+ case Instruction::PtrToInt: Out << "PtrToIntInst"; break;
+ case Instruction::IntToPtr: Out << "IntToPtrInst"; break;
+ case Instruction::BitCast: Out << "BitCastInst"; break;
+ default: assert(!"Unreachable"); break;
+ }
+ Out << "(" << opNames[0] << ", "
+ << getCppName(cst->getType()) << ", \"";
+ printEscapedString(cst->getName());
+ Out << "\", " << bbname << ");";
+ break;
+ }
+ case Instruction::Call:{
+ const CallInst* call = cast<CallInst>(I);
+ if (InlineAsm* ila = dyn_cast<InlineAsm>(call->getOperand(0))) {
+ Out << "InlineAsm* " << getCppName(ila) << " = InlineAsm::get("
+ << getCppName(ila->getFunctionType()) << ", \""
+ << ila->getAsmString() << "\", \""
+ << ila->getConstraintString() << "\","
+ << (ila->hasSideEffects() ? "true" : "false") << ");";
+ nl(Out);
+ }
+ if (call->getNumOperands() > 3) {
+ Out << "std::vector<Value*> " << iName << "_params;";
+ nl(Out);
+ for (unsigned i = 1; i < call->getNumOperands(); ++i) {
+ Out << iName << "_params.push_back(" << opNames[i] << ");";
+ nl(Out);
+ }
+ Out << "CallInst* " << iName << " = new CallInst("
+ << opNames[0] << ", &" << iName << "_params[0], "
+ << call->getNumOperands() - 1 << ", \"";
+ } else if (call->getNumOperands() == 3) {
+ Out << "CallInst* " << iName << " = new CallInst("
+ << opNames[0] << ", " << opNames[1] << ", " << opNames[2] << ", \"";
+ } else if (call->getNumOperands() == 2) {
+ Out << "CallInst* " << iName << " = new CallInst("
+ << opNames[0] << ", " << opNames[1] << ", \"";
+ } else {
+ Out << "CallInst* " << iName << " = new CallInst(" << opNames[0]
+ << ", \"";
+ }
+ printEscapedString(call->getName());
+ Out << "\", " << bbname << ");";
+ nl(Out) << iName << "->setCallingConv(";
+ printCallingConv(call->getCallingConv());
+ Out << ");";
+ nl(Out) << iName << "->setTailCall("
+ << (call->isTailCall() ? "true":"false");
+ Out << ");";
+ break;
+ }
+ case Instruction::Select: {
+ const SelectInst* sel = cast<SelectInst>(I);
+ Out << "SelectInst* " << getCppName(sel) << " = new SelectInst(";
+ Out << opNames[0] << ", " << opNames[1] << ", " << opNames[2] << ", \"";
+ printEscapedString(sel->getName());
+ Out << "\", " << bbname << ");";
+ break;
+ }
+ case Instruction::UserOp1:
+ /// FALL THROUGH
+ case Instruction::UserOp2: {
+ /// FIXME: What should be done here?
+ break;
+ }
+ case Instruction::VAArg: {
+ const VAArgInst* va = cast<VAArgInst>(I);
+ Out << "VAArgInst* " << getCppName(va) << " = new VAArgInst("
+ << opNames[0] << ", " << getCppName(va->getType()) << ", \"";
+ printEscapedString(va->getName());
+ Out << "\", " << bbname << ");";
+ break;
+ }
+ case Instruction::ExtractElement: {
+ const ExtractElementInst* eei = cast<ExtractElementInst>(I);
+ Out << "ExtractElementInst* " << getCppName(eei)
+ << " = new ExtractElementInst(" << opNames[0]
+ << ", " << opNames[1] << ", \"";
+ printEscapedString(eei->getName());
+ Out << "\", " << bbname << ");";
+ break;
+ }
+ case Instruction::InsertElement: {
+ const InsertElementInst* iei = cast<InsertElementInst>(I);
+ Out << "InsertElementInst* " << getCppName(iei)
+ << " = new InsertElementInst(" << opNames[0]
+ << ", " << opNames[1] << ", " << opNames[2] << ", \"";
+ printEscapedString(iei->getName());
+ Out << "\", " << bbname << ");";
+ break;
+ }
+ case Instruction::ShuffleVector: {
+ const ShuffleVectorInst* svi = cast<ShuffleVectorInst>(I);
+ Out << "ShuffleVectorInst* " << getCppName(svi)
+ << " = new ShuffleVectorInst(" << opNames[0]
+ << ", " << opNames[1] << ", " << opNames[2] << ", \"";
+ printEscapedString(svi->getName());
+ Out << "\", " << bbname << ");";
+ break;
+ }
+ }
+ DefinedValues.insert(I);
+ nl(Out);
+ delete [] opNames;
+}
+
+// Print out the types, constants and declarations needed by one function
+void CppWriter::printFunctionUses(const Function* F) {
+
+ nl(Out) << "// Type Definitions"; nl(Out);
+ if (!is_inline) {
+ // Print the function's return type
+ printType(F->getReturnType());
+
+ // Print the function's function type
+ printType(F->getFunctionType());
+
+ // Print the types of each of the function's arguments
+ for(Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
+ AI != AE; ++AI) {
+ printType(AI->getType());
+ }
+ }
+
+ // Print type definitions for every type referenced by an instruction and
+ // make a note of any global values or constants that are referenced
+ SmallPtrSet<GlobalValue*,64> gvs;
+ SmallPtrSet<Constant*,64> consts;
+ for (Function::const_iterator BB = F->begin(), BE = F->end(); BB != BE; ++BB){
+ for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
+ I != E; ++I) {
+ // Print the type of the instruction itself
+ printType(I->getType());
+
+ // Print the type of each of the instruction's operands
+ for (unsigned i = 0; i < I->getNumOperands(); ++i) {
+ Value* operand = I->getOperand(i);
+ printType(operand->getType());
+
+ // If the operand references a GVal or Constant, make a note of it
+ if (GlobalValue* GV = dyn_cast<GlobalValue>(operand)) {
+ gvs.insert(GV);
+ if (GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV))
+ if (GVar->hasInitializer())
+ consts.insert(GVar->getInitializer());
+ } else if (Constant* C = dyn_cast<Constant>(operand))
+ consts.insert(C);
+ }
+ }
+ }
+
+ // Print the function declarations for any functions encountered
+ nl(Out) << "// Function Declarations"; nl(Out);
+ for (SmallPtrSet<GlobalValue*,64>::iterator I = gvs.begin(), E = gvs.end();
+ I != E; ++I) {
+ if (Function* Fun = dyn_cast<Function>(*I)) {
+ if (!is_inline || Fun != F)
+ printFunctionHead(Fun);
+ }
+ }
+
+ // Print the global variable declarations for any variables encountered
+ nl(Out) << "// Global Variable Declarations"; nl(Out);
+ for (SmallPtrSet<GlobalValue*,64>::iterator I = gvs.begin(), E = gvs.end();
+ I != E; ++I) {
+ if (GlobalVariable* F = dyn_cast<GlobalVariable>(*I))
+ printVariableHead(F);
+ }
+
+ // Print the constants found
+ nl(Out) << "// Constant Definitions"; nl(Out);
+ for (SmallPtrSet<Constant*,64>::iterator I = consts.begin(), E = consts.end();
+ I != E; ++I) {
+ printConstant(*I);
+ }
+
+ // Process the global variables definitions now that all the constants have
+ // been emitted. These definitions just couple the gvars with their constant
+ // initializers.
+ nl(Out) << "// Global Variable Definitions"; nl(Out);
+ for (SmallPtrSet<GlobalValue*,64>::iterator I = gvs.begin(), E = gvs.end();
+ I != E; ++I) {
+ if (GlobalVariable* GV = dyn_cast<GlobalVariable>(*I))
+ printVariableBody(GV);
+ }
+}
+
+void CppWriter::printFunctionHead(const Function* F) {
+ nl(Out) << "Function* " << getCppName(F);
+ if (is_inline) {
+ Out << " = mod->getFunction(\"";
+ printEscapedString(F->getName());
+ Out << "\", " << getCppName(F->getFunctionType()) << ");";
+ nl(Out) << "if (!" << getCppName(F) << ") {";
+ nl(Out) << getCppName(F);
+ }
+ Out<< " = new Function(";
+ nl(Out,1) << "/*Type=*/" << getCppName(F->getFunctionType()) << ",";
+ nl(Out) << "/*Linkage=*/";
+ printLinkageType(F->getLinkage());
+ Out << ",";
+ nl(Out) << "/*Name=*/\"";
+ printEscapedString(F->getName());
+ Out << "\", mod); " << (F->isDeclaration()? "// (external, no body)" : "");
+ nl(Out,-1);
+ printCppName(F);
+ Out << "->setCallingConv(";
+ printCallingConv(F->getCallingConv());
+ Out << ");";
+ nl(Out);
+ if (F->hasSection()) {
+ printCppName(F);
+ Out << "->setSection(\"" << F->getSection() << "\");";
+ nl(Out);
+ }
+ if (F->getAlignment()) {
+ printCppName(F);
+ Out << "->setAlignment(" << F->getAlignment() << ");";
+ nl(Out);
+ }
+ if (is_inline) {
+ Out << "}";
+ nl(Out);
+ }
+}
+
+void CppWriter::printFunctionBody(const Function *F) {
+ if (F->isDeclaration())
+ return; // external functions have no bodies.
+
+ // Clear the DefinedValues and ForwardRefs maps because we can't have
+ // cross-function forward refs
+ ForwardRefs.clear();
+ DefinedValues.clear();
+
+ // Create all the argument values
+ if (!is_inline) {
+ if (!F->arg_empty()) {
+ Out << "Function::arg_iterator args = " << getCppName(F)
+ << "->arg_begin();";
+ nl(Out);
+ }
+ for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
+ AI != AE; ++AI) {
+ Out << "Value* " << getCppName(AI) << " = args++;";
+ nl(Out);
+ if (AI->hasName()) {
+ Out << getCppName(AI) << "->setName(\"" << AI->getName() << "\");";
+ nl(Out);
+ }
+ }
+ }
+
+ // Create all the basic blocks
+ nl(Out);
+ for (Function::const_iterator BI = F->begin(), BE = F->end();
+ BI != BE; ++BI) {
+ std::string bbname(getCppName(BI));
+ Out << "BasicBlock* " << bbname << " = new BasicBlock(\"";
+ if (BI->hasName())
+ printEscapedString(BI->getName());
+ Out << "\"," << getCppName(BI->getParent()) << ",0);";
+ nl(Out);
+ }
+
+ // Output all of its basic blocks... for the function
+ for (Function::const_iterator BI = F->begin(), BE = F->end();
+ BI != BE; ++BI) {
+ std::string bbname(getCppName(BI));
+ nl(Out) << "// Block " << BI->getName() << " (" << bbname << ")";
+ nl(Out);
+
+ // Output all of the instructions in the basic block...
+ for (BasicBlock::const_iterator I = BI->begin(), E = BI->end();
+ I != E; ++I) {
+ printInstruction(I,bbname);
+ }
+ }
+
+ // Loop over the ForwardRefs and resolve them now that all instructions
+ // are generated.
+ if (!ForwardRefs.empty()) {
+ nl(Out) << "// Resolve Forward References";
+ nl(Out);
+ }
+
+ while (!ForwardRefs.empty()) {
+ ForwardRefMap::iterator I = ForwardRefs.begin();
+ Out << I->second << "->replaceAllUsesWith("
+ << getCppName(I->first) << "); delete " << I->second << ";";
+ nl(Out);
+ ForwardRefs.erase(I);
+ }
+}
+
+void CppWriter::printInline(const std::string& fname, const std::string& func) {
+ const Function* F = TheModule->getFunction(func);
+ if (!F) {
+ error(std::string("Function '") + func + "' not found in input module");
+ return;
+ }
+ if (F->isDeclaration()) {
+ error(std::string("Function '") + func + "' is external!");
+ return;
+ }
+ nl(Out) << "BasicBlock* " << fname << "(Module* mod, Function *"
+ << getCppName(F);
+ unsigned arg_count = 1;
+ for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
+ AI != AE; ++AI) {
+ Out << ", Value* arg_" << arg_count;
+ }
+ Out << ") {";
+ nl(Out);
+ is_inline = true;
+ printFunctionUses(F);
+ printFunctionBody(F);
+ is_inline = false;
+ Out << "return " << getCppName(F->begin()) << ";";
+ nl(Out) << "}";
+ nl(Out);
+}
+
+void CppWriter::printModuleBody() {
+ // Print out all the type definitions
+ nl(Out) << "// Type Definitions"; nl(Out);
+ printTypes(TheModule);
+
+ // Functions can call each other and global variables can reference them so
+ // define all the functions first before emitting their function bodies.
+ nl(Out) << "// Function Declarations"; nl(Out);
+ for (Module::const_iterator I = TheModule->begin(), E = TheModule->end();
+ I != E; ++I)
+ printFunctionHead(I);
+
+ // Process the global variables declarations. We can't initialze them until
+ // after the constants are printed so just print a header for each global
+ nl(Out) << "// Global Variable Declarations\n"; nl(Out);
+ for (Module::const_global_iterator I = TheModule->global_begin(),
+ E = TheModule->global_end(); I != E; ++I) {
+ printVariableHead(I);
+ }
+
+ // Print out all the constants definitions. Constants don't recurse except
+ // through GlobalValues. All GlobalValues have been declared at this point
+ // so we can proceed to generate the constants.
+ nl(Out) << "// Constant Definitions"; nl(Out);
+ printConstants(TheModule);
+
+ // Process the global variables definitions now that all the constants have
+ // been emitted. These definitions just couple the gvars with their constant
+ // initializers.
+ nl(Out) << "// Global Variable Definitions"; nl(Out);
+ for (Module::const_global_iterator I = TheModule->global_begin(),
+ E = TheModule->global_end(); I != E; ++I) {
+ printVariableBody(I);
+ }
+
+ // Finally, we can safely put out all of the function bodies.
+ nl(Out) << "// Function Definitions"; nl(Out);
+ for (Module::const_iterator I = TheModule->begin(), E = TheModule->end();
+ I != E; ++I) {
+ if (!I->isDeclaration()) {
+ nl(Out) << "// Function: " << I->getName() << " (" << getCppName(I)
+ << ")";
+ nl(Out) << "{";
+ nl(Out,1);
+ printFunctionBody(I);
+ nl(Out,-1) << "}";
+ nl(Out);
+ }
+ }
+}
+
+void CppWriter::printProgram(
+ const std::string& fname,
+ const std::string& mName
+) {
+ Out << "#include <llvm/Module.h>\n";
+ Out << "#include <llvm/DerivedTypes.h>\n";
+ Out << "#include <llvm/Constants.h>\n";
+ Out << "#include <llvm/GlobalVariable.h>\n";
+ Out << "#include <llvm/Function.h>\n";
+ Out << "#include <llvm/CallingConv.h>\n";
+ Out << "#include <llvm/BasicBlock.h>\n";
+ Out << "#include <llvm/Instructions.h>\n";
+ Out << "#include <llvm/InlineAsm.h>\n";
+ Out << "#include <llvm/ParameterAttributes.h>\n";
+ Out << "#include <llvm/Support/MathExtras.h>\n";
+ Out << "#include <llvm/Pass.h>\n";
+ Out << "#include <llvm/PassManager.h>\n";
+ Out << "#include <llvm/Analysis/Verifier.h>\n";
+ Out << "#include <llvm/Assembly/PrintModulePass.h>\n";
+ Out << "#include <algorithm>\n";
+ Out << "#include <iostream>\n\n";
+ Out << "using namespace llvm;\n\n";
+ Out << "Module* " << fname << "();\n\n";
+ Out << "int main(int argc, char**argv) {\n";
+ Out << " Module* Mod = " << fname << "();\n";
+ Out << " verifyModule(*Mod, PrintMessageAction);\n";
+ Out << " std::cerr.flush();\n";
+ Out << " std::cout.flush();\n";
+ Out << " PassManager PM;\n";
+ Out << " PM.add(new PrintModulePass(&llvm::cout));\n";
+ Out << " PM.run(*Mod);\n";
+ Out << " return 0;\n";
+ Out << "}\n\n";
+ printModule(fname,mName);
+}
+
+void CppWriter::printModule(
+ const std::string& fname,
+ const std::string& mName
+) {
+ nl(Out) << "Module* " << fname << "() {";
+ nl(Out,1) << "// Module Construction";
+ nl(Out) << "Module* mod = new Module(\"" << mName << "\");";
+ if (!TheModule->getTargetTriple().empty()) {
+ nl(Out) << "mod->setDataLayout(\"" << TheModule->getDataLayout() << "\");";
+ }
+ if (!TheModule->getTargetTriple().empty()) {
+ nl(Out) << "mod->setTargetTriple(\"" << TheModule->getTargetTriple()
+ << "\");";
+ }
+
+ if (!TheModule->getModuleInlineAsm().empty()) {
+ nl(Out) << "mod->setModuleInlineAsm(\"";
+ printEscapedString(TheModule->getModuleInlineAsm());
+ Out << "\");";
+ }
+ nl(Out);
+
+ // Loop over the dependent libraries and emit them.
+ Module::lib_iterator LI = TheModule->lib_begin();
+ Module::lib_iterator LE = TheModule->lib_end();
+ while (LI != LE) {
+ Out << "mod->addLibrary(\"" << *LI << "\");";
+ nl(Out);
+ ++LI;
+ }
+ printModuleBody();
+ nl(Out) << "return mod;";
+ nl(Out,-1) << "}";
+ nl(Out);
+}
+
+void CppWriter::printContents(
+ const std::string& fname, // Name of generated function
+ const std::string& mName // Name of module generated module
+) {
+ Out << "\nModule* " << fname << "(Module *mod) {\n";
+ Out << "\nmod->setModuleIdentifier(\"" << mName << "\");\n";
+ printModuleBody();
+ Out << "\nreturn mod;\n";
+ Out << "\n}\n";
+}
+
+void CppWriter::printFunction(
+ const std::string& fname, // Name of generated function
+ const std::string& funcName // Name of function to generate
+) {
+ const Function* F = TheModule->getFunction(funcName);
+ if (!F) {
+ error(std::string("Function '") + funcName + "' not found in input module");
+ return;
+ }
+ Out << "\nFunction* " << fname << "(Module *mod) {\n";
+ printFunctionUses(F);
+ printFunctionHead(F);
+ printFunctionBody(F);
+ Out << "return " << getCppName(F) << ";\n";
+ Out << "}\n";
+}
+
+void CppWriter::printVariable(
+ const std::string& fname, /// Name of generated function
+ const std::string& varName // Name of variable to generate
+) {
+ const GlobalVariable* GV = TheModule->getNamedGlobal(varName);
+
+ if (!GV) {
+ error(std::string("Variable '") + varName + "' not found in input module");
+ return;
+ }
+ Out << "\nGlobalVariable* " << fname << "(Module *mod) {\n";
+ printVariableUses(GV);
+ printVariableHead(GV);
+ printVariableBody(GV);
+ Out << "return " << getCppName(GV) << ";\n";
+ Out << "}\n";
+}
+
+void CppWriter::printType(
+ const std::string& fname, /// Name of generated function
+ const std::string& typeName // Name of type to generate
+) {
+ const Type* Ty = TheModule->getTypeByName(typeName);
+ if (!Ty) {
+ error(std::string("Type '") + typeName + "' not found in input module");
+ return;
+ }
+ Out << "\nType* " << fname << "(Module *mod) {\n";
+ printType(Ty);
+ Out << "return " << getCppName(Ty) << ";\n";
+ Out << "}\n";
+}
+
+} // end anonymous llvm
+
+namespace llvm {
+
+void WriteModuleToCppFile(Module* mod, std::ostream& o) {
+ // Initialize a CppWriter for us to use
+ CppWriter W(o, mod);
+
+ // Emit a header
+ o << "// Generated by llvm2cpp - DO NOT MODIFY!\n\n";
+
+ // Get the name of the function we're supposed to generate
+ std::string fname = FuncName.getValue();
+
+ // Get the name of the thing we are to generate
+ std::string tgtname = NameToGenerate.getValue();
+ if (GenerationType == GenModule ||
+ GenerationType == GenContents ||
+ GenerationType == GenProgram) {
+ if (tgtname == "!bad!") {
+ if (mod->getModuleIdentifier() == "-")
+ tgtname = "<stdin>";
+ else
+ tgtname = mod->getModuleIdentifier();
+ }
+ } else if (tgtname == "!bad!") {
+ W.error("You must use the -for option with -gen-{function,variable,type}");
+ }
+
+ switch (WhatToGenerate(GenerationType)) {
+ case GenProgram:
+ if (fname.empty())
+ fname = "makeLLVMModule";
+ W.printProgram(fname,tgtname);
+ break;
+ case GenModule:
+ if (fname.empty())
+ fname = "makeLLVMModule";
+ W.printModule(fname,tgtname);
+ break;
+ case GenContents:
+ if (fname.empty())
+ fname = "makeLLVMModuleContents";
+ W.printContents(fname,tgtname);
+ break;
+ case GenFunction:
+ if (fname.empty())
+ fname = "makeLLVMFunction";
+ W.printFunction(fname,tgtname);
+ break;
+ case GenInline:
+ if (fname.empty())
+ fname = "makeLLVMInline";
+ W.printInline(fname,tgtname);
+ break;
+ case GenVariable:
+ if (fname.empty())
+ fname = "makeLLVMVariable";
+ W.printVariable(fname,tgtname);
+ break;
+ case GenType:
+ if (fname.empty())
+ fname = "makeLLVMType";
+ W.printType(fname,tgtname);
+ break;
+ default:
+ W.error("Invalid generation option");
+ }
+}
+
+}
diff --git a/tools/llvm2cpp/CppWriter.h b/tools/llvm2cpp/CppWriter.h
new file mode 100644
index 0000000..16ba30e
--- /dev/null
+++ b/tools/llvm2cpp/CppWriter.h
@@ -0,0 +1,18 @@
+//===--- CppWriter.h - Generate C++ IR to C++ Source Interface ------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares a function, WriteModuleToCppFile that will convert a
+// Module into the corresponding C++ code to construct the same module.
+//
+//===------------------------------------------------------------------------===
+#include <ostream>
+namespace llvm {
+class Module;
+void WriteModuleToCppFile(Module* mod, std::ostream& out);
+}
diff --git a/tools/llvm2cpp/Makefile b/tools/llvm2cpp/Makefile
new file mode 100644
index 0000000..3bb68b8
--- /dev/null
+++ b/tools/llvm2cpp/Makefile
@@ -0,0 +1,15 @@
+##===- tools/llvm2cpp/Makefile -----------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file was developed by the LLVM research group and is distributed under
+# the University of Illinois Open Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+LEVEL = ../..
+TOOLNAME = llvm2cpp
+LINK_COMPONENTS = bitreader
+
+include $(LEVEL)/Makefile.common
+
+CompileCommonOpts := $(CompileCommonOpts) -Wno-format
diff --git a/tools/llvm2cpp/llvm2cpp.cpp b/tools/llvm2cpp/llvm2cpp.cpp
new file mode 100644
index 0000000..2db7543
--- /dev/null
+++ b/tools/llvm2cpp/llvm2cpp.cpp
@@ -0,0 +1,122 @@
+//===--- llvm2cpp.cpp - LLVM IR to C++ Translator -------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This program converts an input LLVM assembly file (.ll) into a C++ source
+// file that makes calls to the LLVM C++ API to produce the same module. The
+// generated program verifies what it built and then runs the PrintAssemblyPass
+// to reproduce the input originally given to llvm2cpp.
+//
+// Use the --help option for help with command line options.
+//
+//===------------------------------------------------------------------------===
+
+#include "llvm/Module.h"
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/Analysis/Verifier.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/SystemUtils.h"
+#include "llvm/System/Signals.h"
+#include "CppWriter.h"
+#include <fstream>
+#include <iostream>
+#include <memory>
+using namespace llvm;
+
+static cl::opt<std::string>
+InputFilename(cl::Positional, cl::desc("<input LLVM bitcode file>"),
+ cl::init("-"));
+
+static cl::opt<std::string>
+OutputFilename("o", cl::desc("Override output filename"),
+ cl::value_desc("filename"));
+
+static cl::opt<bool>
+Force("f", cl::desc("Overwrite output files"));
+
+int main(int argc, char **argv) {
+ llvm_shutdown_obj X; // Call llvm_shutdown() on exit.
+ cl::ParseCommandLineOptions(argc, argv, " llvm .ll -> .cpp assembler\n");
+ sys::PrintStackTraceOnErrorSignal();
+
+ int exitCode = 0;
+ std::ostream *Out = 0;
+ std::string ErrorMessage;
+
+ std::auto_ptr<Module> M;
+ std::auto_ptr<MemoryBuffer> Buffer(
+ MemoryBuffer::getFileOrSTDIN(InputFilename, &ErrorMessage));
+ if (Buffer.get())
+ M.reset(ParseBitcodeFile(Buffer.get(), &ErrorMessage));
+ if (M.get() == 0) {
+ std::cerr << argv[0] << ": ";
+ if (ErrorMessage.size())
+ std::cerr << ErrorMessage << "\n";
+ else
+ std::cerr << "bitcode didn't read correctly.\n";
+ return 1;
+ }
+
+ if (OutputFilename != "") { // Specified an output filename?
+ if (OutputFilename != "-") { // Not stdout?
+ if (!Force && std::ifstream(OutputFilename.c_str())) {
+ // If force is not specified, make sure not to overwrite a file!
+ std::cerr << argv[0] << ": error opening '" << OutputFilename
+ << "': file exists!\n"
+ << "Use -f command line argument to force output\n";
+ return 1;
+ }
+ Out = new std::ofstream(OutputFilename.c_str(), std::ios::out |
+ std::ios::trunc | std::ios::binary);
+ } else { // Specified stdout
+ Out = &std::cout;
+ }
+ } else {
+ if (InputFilename == "-") {
+ OutputFilename = "-";
+ Out = &std::cout;
+ } else {
+ std::string IFN = InputFilename;
+ int Len = IFN.length();
+ if (IFN[Len-3] == '.' && IFN[Len-2] == 'l' && IFN[Len-1] == 'l') {
+ // Source ends in .ll
+ OutputFilename = std::string(IFN.begin(), IFN.end()-3);
+ } else {
+ OutputFilename = IFN; // Append a .cpp to it
+ }
+ OutputFilename += ".cpp";
+
+ if (!Force && std::ifstream(OutputFilename.c_str())) {
+ // If force is not specified, make sure not to overwrite a file!
+ std::cerr << argv[0] << ": error opening '" << OutputFilename
+ << "': file exists!\n"
+ << "Use -f command line argument to force output\n";
+ return 1;
+ }
+
+ Out = new std::ofstream(OutputFilename.c_str(), std::ios::out |
+ std::ios::trunc | std::ios::binary);
+ // Make sure that the Out file gets unlinked from the disk if we get a
+ // SIGINT
+ sys::RemoveFileOnSignal(sys::Path(OutputFilename));
+ }
+ }
+
+ if (!Out->good()) {
+ std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
+ return 1;
+ }
+
+ WriteModuleToCppFile(M.get(), *Out);
+
+ if (Out != &std::cout) delete Out;
+ return exitCode;
+}
+
diff --git a/tools/llvmc/CompilerDriver.cpp b/tools/llvmc/CompilerDriver.cpp
new file mode 100644
index 0000000..4be9f13
--- /dev/null
+++ b/tools/llvmc/CompilerDriver.cpp
@@ -0,0 +1,1032 @@
+//===- CompilerDriver.cpp - The LLVM Compiler Driver ------------*- C++ -*-===//
+//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the bulk of the LLVM Compiler Driver (llvmc).
+//
+//===----------------------------------------------------------------------===//
+
+#include "CompilerDriver.h"
+#include "ConfigLexer.h"
+#include "llvm/Module.h"
+#include "llvm/ModuleProvider.h"
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Timer.h"
+#include "llvm/System/Signals.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Config/alloca.h"
+#include <iostream>
+using namespace llvm;
+
+
+namespace {
+
+void WriteAction(CompilerDriver::Action* action ) {
+ std::cerr << action->program.c_str();
+ std::vector<std::string>::const_iterator I = action->args.begin();
+ while (I != action->args.end()) {
+ std::cerr << ' ' << *I;
+ ++I;
+ }
+ std::cerr << '\n';
+}
+
+void DumpAction(CompilerDriver::Action* action) {
+ std::cerr << "command = " << action->program.c_str();
+ std::vector<std::string>::const_iterator I = action->args.begin();
+ while (I != action->args.end()) {
+ std::cerr << ' ' << *I;
+ ++I;
+ }
+ std::cerr << '\n';
+ std::cerr << "flags = " << action->flags << '\n';
+}
+
+void DumpConfigData(CompilerDriver::ConfigData* cd, const std::string& type ){
+ std::cerr << "Configuration Data For '" << cd->langName << "' (" << type
+ << ")\n";
+ std::cerr << "PreProcessor: ";
+ DumpAction(&cd->PreProcessor);
+ std::cerr << "Translator: ";
+ DumpAction(&cd->Translator);
+ std::cerr << "Optimizer: ";
+ DumpAction(&cd->Optimizer);
+ std::cerr << "Assembler: ";
+ DumpAction(&cd->Assembler);
+ std::cerr << "Linker: ";
+ DumpAction(&cd->Linker);
+}
+
+static bool GetBitcodeDependentLibraries(const std::string &fname,
+ Module::LibraryListType& deplibs,
+ std::string* ErrMsg) {
+ ModuleProvider *MP = 0;
+ if (MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(fname)) {
+ MP = getBitcodeModuleProvider(Buffer);
+ if (MP == 0) delete Buffer;
+ }
+ if (!MP) {
+ deplibs.clear();
+ return true;
+ }
+ deplibs = MP->getModule()->getLibraries();
+ delete MP;
+ return false;
+}
+
+
+class CompilerDriverImpl : public CompilerDriver {
+/// @name Constructors
+/// @{
+public:
+ CompilerDriverImpl(ConfigDataProvider& confDatProv )
+ : cdp(&confDatProv)
+ , finalPhase(LINKING)
+ , optLevel(OPT_FAST_COMPILE)
+ , Flags(0)
+ , machine()
+ , LibraryPaths()
+ , TempDir()
+ , AdditionalArgs()
+ {
+ AdditionalArgs.reserve(NUM_PHASES);
+ StringVector emptyVec;
+ for (unsigned i = 0; i < NUM_PHASES; ++i)
+ AdditionalArgs.push_back(emptyVec);
+ }
+
+ virtual ~CompilerDriverImpl() {
+ cleanup();
+ cdp = 0;
+ LibraryPaths.clear();
+ IncludePaths.clear();
+ Defines.clear();
+ TempDir.clear();
+ AdditionalArgs.clear();
+ fOptions.clear();
+ MOptions.clear();
+ WOptions.clear();
+ }
+
+/// @}
+/// @name Methods
+/// @{
+public:
+ virtual void setFinalPhase(Phases phase) {
+ finalPhase = phase;
+ }
+
+ virtual void setOptimization(OptimizationLevels level) {
+ optLevel = level;
+ }
+
+ virtual void setDriverFlags(unsigned flags) {
+ Flags = flags & DRIVER_FLAGS_MASK;
+ }
+
+ virtual void setOutputMachine(const std::string& machineName) {
+ machine = machineName;
+ }
+
+ virtual void setPhaseArgs(Phases phase, const StringVector& opts) {
+ assert(phase <= LINKING && phase >= PREPROCESSING);
+ AdditionalArgs[phase] = opts;
+ }
+
+ virtual void setIncludePaths(const StringVector& paths) {
+ StringVector::const_iterator I = paths.begin();
+ StringVector::const_iterator E = paths.end();
+ while (I != E) {
+ sys::Path tmp;
+ tmp.set(*I);
+ IncludePaths.push_back(tmp);
+ ++I;
+ }
+ }
+
+ virtual void setSymbolDefines(const StringVector& defs) {
+ Defines = defs;
+ }
+
+ virtual void setLibraryPaths(const StringVector& paths) {
+ StringVector::const_iterator I = paths.begin();
+ StringVector::const_iterator E = paths.end();
+ while (I != E) {
+ sys::Path tmp;
+ tmp.set(*I);
+ LibraryPaths.push_back(tmp);
+ ++I;
+ }
+ }
+
+ virtual void addLibraryPath(const sys::Path& libPath) {
+ LibraryPaths.push_back(libPath);
+ }
+
+ virtual void addToolPath(const sys::Path& toolPath) {
+ ToolPaths.push_back(toolPath);
+ }
+
+ virtual void setfPassThrough(const StringVector& fOpts) {
+ fOptions = fOpts;
+ }
+
+ /// @brief Set the list of -M options to be passed through
+ virtual void setMPassThrough(const StringVector& MOpts) {
+ MOptions = MOpts;
+ }
+
+ /// @brief Set the list of -W options to be passed through
+ virtual void setWPassThrough(const StringVector& WOpts) {
+ WOptions = WOpts;
+ }
+
+/// @}
+/// @name Functions
+/// @{
+private:
+ bool isSet(DriverFlags flag) {
+ return 0 != ((flag & DRIVER_FLAGS_MASK) & Flags);
+ }
+
+ void cleanup() {
+ if (!isSet(KEEP_TEMPS_FLAG)) {
+ const sys::FileStatus *Status = TempDir.getFileStatus();
+ if (Status && Status->isDir)
+ TempDir.eraseFromDisk(/*remove_contents=*/true);
+ } else {
+ std::cout << "Temporary files are in " << TempDir << "\n";
+ }
+ }
+
+ sys::Path MakeTempFile(const std::string& basename,
+ const std::string& suffix,
+ std::string* ErrMsg) {
+ if (TempDir.isEmpty()) {
+ TempDir = sys::Path::GetTemporaryDirectory(ErrMsg);
+ if (TempDir.isEmpty())
+ return sys::Path();
+ sys::RemoveDirectoryOnSignal(TempDir);
+ }
+ sys::Path result(TempDir);
+ if (!result.appendComponent(basename)) {
+ if (ErrMsg)
+ *ErrMsg = basename + ": can't use this file name";
+ return sys::Path();
+ }
+ if (!result.appendSuffix(suffix)) {
+ if (ErrMsg)
+ *ErrMsg = suffix + ": can't use this file suffix";
+ return sys::Path();
+ }
+ return result;
+ }
+
+ Action* GetAction(ConfigData* cd,
+ const sys::Path& input,
+ const sys::Path& output,
+ Phases phase)
+ {
+ Action* pat = 0; ///< The pattern/template for the action
+ Action* action = new Action; ///< The actual action to execute
+
+ // Get the action pattern
+ switch (phase) {
+ case PREPROCESSING: pat = &cd->PreProcessor; break;
+ case TRANSLATION: pat = &cd->Translator; break;
+ case OPTIMIZATION: pat = &cd->Optimizer; break;
+ case ASSEMBLY: pat = &cd->Assembler; break;
+ case LINKING: pat = &cd->Linker; break;
+ default:
+ assert(!"Invalid driver phase!");
+ break;
+ }
+ assert(pat != 0 && "Invalid command pattern");
+
+ // Copy over some pattern things that don't need to change
+ action->flags = pat->flags;
+
+ // See if program starts with wildcard...
+ std::string programName=pat->program.toString();
+ if (programName[0] == '%' && programName.length() >2) {
+ switch(programName[1]){
+ case 'b':
+ if (programName.substr(0,8) == "%bindir%") {
+ std::string tmp(LLVM_BINDIR);
+ tmp.append(programName.substr(8));
+ pat->program.set(tmp);
+ }
+ break;
+ case 'l':
+ if (programName.substr(0,12) == "%llvmgccdir%"){
+ std::string tmp(LLVMGCCDIR);
+ tmp.append(programName.substr(12));
+ pat->program.set(tmp);
+ }else if (programName.substr(0,13) == "%llvmgccarch%"){
+ std::string tmp(LLVMGCCARCH);
+ tmp.append(programName.substr(13));
+ pat->program.set(tmp);
+ }else if (programName.substr(0,9) == "%llvmgcc%"){
+ std::string tmp(LLVMGCC);
+ tmp.append(programName.substr(9));
+ pat->program.set(tmp);
+ }else if (programName.substr(0,9) == "%llvmgxx%"){
+ std::string tmp(LLVMGXX);
+ tmp.append(programName.substr(9));
+ pat->program.set(tmp);
+ }else if (programName.substr(0,9) == "%llvmcc1%"){
+ std::string tmp(LLVMCC1);
+ tmp.append(programName.substr(9));
+ pat->program.set(tmp);
+ }else if (programName.substr(0,13) == "%llvmcc1plus%"){
+ std::string tmp(LLVMCC1PLUS);
+ tmp.append(programName.substr(13));
+ pat->program.set(tmp);
+ }else if (programName.substr(0,8) == "%libdir%") {
+ std::string tmp(LLVM_LIBDIR);
+ tmp.append(programName.substr(8));
+ pat->program.set(tmp);
+ }
+ break;
+ }
+ }
+ action->program = pat->program;
+
+ // Do the substitutions from the pattern to the actual
+ StringVector::iterator PI = pat->args.begin();
+ StringVector::iterator PE = pat->args.end();
+ while (PI != PE) {
+ if ((*PI)[0] == '%' && PI->length() >2) {
+ bool found = true;
+ switch ((*PI)[1]) {
+ case 'a':
+ if (*PI == "%args%") {
+ if (AdditionalArgs.size() > unsigned(phase))
+ if (!AdditionalArgs[phase].empty()) {
+ // Get specific options for each kind of action type
+ StringVector& addargs = AdditionalArgs[phase];
+ // Add specific options for each kind of action type
+ action->args.insert(action->args.end(), addargs.begin(),
+ addargs.end());
+ }
+ } else
+ found = false;
+ break;
+ case 'b':
+ if (*PI == "%bindir%") {
+ std::string tmp(*PI);
+ tmp.replace(0,8,LLVM_BINDIR);
+ action->args.push_back(tmp);
+ } else
+ found = false;
+ break;
+ case 'd':
+ if (*PI == "%defs%") {
+ StringVector::iterator I = Defines.begin();
+ StringVector::iterator E = Defines.end();
+ while (I != E) {
+ action->args.push_back( std::string("-D") + *I);
+ ++I;
+ }
+ } else
+ found = false;
+ break;
+ case 'f':
+ if (*PI == "%fOpts%") {
+ if (!fOptions.empty())
+ action->args.insert(action->args.end(), fOptions.begin(),
+ fOptions.end());
+ } else
+ found = false;
+ break;
+ case 'i':
+ if (*PI == "%in%") {
+ action->args.push_back(input.toString());
+ } else if (*PI == "%incls%") {
+ PathVector::iterator I = IncludePaths.begin();
+ PathVector::iterator E = IncludePaths.end();
+ while (I != E) {
+ action->args.push_back( std::string("-I") + I->toString() );
+ ++I;
+ }
+ } else
+ found = false;
+ break;
+ case 'l':
+ if ((*PI)[1] == 'l') {
+ std::string tmp(*PI);
+ if (*PI == "%llvmgccdir%")
+ tmp.replace(0,12,LLVMGCCDIR);
+ else if (*PI == "%llvmgccarch%")
+ tmp.replace(0,13,LLVMGCCARCH);
+ else if (*PI == "%llvmgcc%")
+ tmp.replace(0,9,LLVMGCC);
+ else if (*PI == "%llvmgxx%")
+ tmp.replace(0,9,LLVMGXX);
+ else if (*PI == "%llvmcc1%")
+ tmp.replace(0,9,LLVMCC1);
+ else if (*PI == "%llvmcc1plus%")
+ tmp.replace(0,9,LLVMCC1);
+ else
+ found = false;
+ if (found)
+ action->args.push_back(tmp);
+ } else if (*PI == "%libs%") {
+ PathVector::iterator I = LibraryPaths.begin();
+ PathVector::iterator E = LibraryPaths.end();
+ while (I != E) {
+ action->args.push_back( std::string("-L") + I->toString() );
+ ++I;
+ }
+ } else if (*PI == "%libdir%") {
+ std::string tmp(*PI);
+ tmp.replace(0,8,LLVM_LIBDIR);
+ action->args.push_back(tmp);
+ } else
+ found = false;
+ break;
+ case 'o':
+ if (*PI == "%out%") {
+ action->args.push_back(output.toString());
+ } else if (*PI == "%opt%") {
+ if (!isSet(EMIT_RAW_FLAG)) {
+ if (cd->opts.size() > static_cast<unsigned>(optLevel) &&
+ !cd->opts[optLevel].empty())
+ action->args.insert(action->args.end(),
+ cd->opts[optLevel].begin(),
+ cd->opts[optLevel].end());
+ else
+ throw std::string("Optimization options for level ") +
+ utostr(unsigned(optLevel)) + " were not specified";
+ }
+ } else
+ found = false;
+ break;
+ case 's':
+ if (*PI == "%stats%") {
+ if (isSet(SHOW_STATS_FLAG))
+ action->args.push_back("-stats");
+ } else
+ found = false;
+ break;
+ case 't':
+ if (*PI == "%target%") {
+ action->args.push_back(std::string("-march=") + machine);
+ } else if (*PI == "%time%") {
+ if (isSet(TIME_PASSES_FLAG))
+ action->args.push_back("-time-passes");
+ } else
+ found = false;
+ break;
+ case 'v':
+ if (*PI == "%verbose%") {
+ if (isSet(VERBOSE_FLAG))
+ action->args.push_back("-v");
+ } else
+ found = false;
+ break;
+ case 'M':
+ if (*PI == "%Mopts%") {
+ if (!MOptions.empty())
+ action->args.insert(action->args.end(), MOptions.begin(),
+ MOptions.end());
+ } else
+ found = false;
+ break;
+ case 'W':
+ if (*PI == "%Wopts%") {
+ for (StringVector::iterator I = WOptions.begin(),
+ E = WOptions.end(); I != E ; ++I ) {
+ action->args.push_back(std::string("-W") + *I);
+ }
+ } else
+ found = false;
+ break;
+ default:
+ found = false;
+ break;
+ }
+ if (!found) {
+ // Did it even look like a substitution?
+ if (PI->length()>1 && (*PI)[0] == '%' &&
+ (*PI)[PI->length()-1] == '%') {
+ throw std::string("Invalid substitution token: '") + *PI +
+ "' for command '" + pat->program.toString() + "'";
+ } else if (!PI->empty()) {
+ // It's not a legal substitution, just pass it through
+ action->args.push_back(*PI);
+ }
+ }
+ } else if (!PI->empty()) {
+ // Its not a substitution, just put it in the action
+ action->args.push_back(*PI);
+ }
+ PI++;
+ }
+
+ // Finally, we're done
+ return action;
+ }
+
+ int DoAction(Action*action, std::string& ErrMsg) {
+ assert(action != 0 && "Invalid Action!");
+ if (isSet(VERBOSE_FLAG))
+ WriteAction(action);
+ if (!isSet(DRY_RUN_FLAG)) {
+ sys::Path progpath = sys::Program::FindProgramByName(
+ action->program.toString());
+ if (progpath.isEmpty())
+ throw std::string("Can't find program '" +
+ action->program.toString()+"'");
+ else if (progpath.canExecute())
+ action->program = progpath;
+ else
+ throw std::string("Program '"+action->program.toString()+
+ "' is not executable.");
+
+ // Invoke the program
+ const char** Args = (const char**)
+ alloca(sizeof(const char*)*(action->args.size()+2));
+ Args[0] = action->program.toString().c_str();
+ for (unsigned i = 1; i <= action->args.size(); ++i)
+ Args[i] = action->args[i-1].c_str();
+ Args[action->args.size()+1] = 0; // null terminate list.
+ if (isSet(TIME_ACTIONS_FLAG)) {
+ Timer timer(action->program.toString());
+ timer.startTimer();
+ int resultCode =
+ sys::Program::ExecuteAndWait(action->program, Args,0,0,0,0, &ErrMsg);
+ timer.stopTimer();
+ timer.print(timer,std::cerr);
+ return resultCode;
+ }
+ else
+ return
+ sys::Program::ExecuteAndWait(action->program, Args, 0,0,0,0, &ErrMsg);
+ }
+ return 0;
+ }
+
+ /// This method tries various variants of a linkage item's file
+ /// name to see if it can find an appropriate file to link with
+ /// in the directories of the LibraryPaths.
+ llvm::sys::Path GetPathForLinkageItem(const std::string& link_item,
+ bool native = false) {
+ sys::Path fullpath;
+ fullpath.set(link_item);
+ if (fullpath.canRead())
+ return fullpath;
+ for (PathVector::iterator PI = LibraryPaths.begin(),
+ PE = LibraryPaths.end(); PI != PE; ++PI) {
+ fullpath.set(PI->toString());
+ fullpath.appendComponent(link_item);
+ if (fullpath.canRead())
+ return fullpath;
+ if (native) {
+ fullpath.appendSuffix("a");
+ } else {
+ fullpath.appendSuffix("bc");
+ if (fullpath.canRead())
+ return fullpath;
+ fullpath.eraseSuffix();
+ fullpath.appendSuffix("o");
+ if (fullpath.canRead())
+ return fullpath;
+ fullpath = *PI;
+ fullpath.appendComponent(std::string("lib") + link_item);
+ fullpath.appendSuffix("a");
+ if (fullpath.canRead())
+ return fullpath;
+ fullpath.eraseSuffix();
+ fullpath.appendSuffix("so");
+ if (fullpath.canRead())
+ return fullpath;
+ }
+ }
+
+ // Didn't find one.
+ fullpath.clear();
+ return fullpath;
+ }
+
+ /// This method processes a linkage item. The item could be a
+ /// Bitcode file needing translation to native code and that is
+ /// dependent on other bitcode libraries, or a native code
+ /// library that should just be linked into the program.
+ bool ProcessLinkageItem(const llvm::sys::Path& link_item,
+ SetVector<sys::Path>& set,
+ std::string& err) {
+ // First, see if the unadorned file name is not readable. If so,
+ // we must track down the file in the lib search path.
+ sys::Path fullpath;
+ if (!link_item.canRead()) {
+ // look for the library using the -L arguments specified
+ // on the command line.
+ fullpath = GetPathForLinkageItem(link_item.toString());
+
+ // If we didn't find the file in any of the library search paths
+ // we have to bail. No where else to look.
+ if (fullpath.isEmpty()) {
+ err =
+ std::string("Can't find linkage item '") + link_item.toString() + "'";
+ return false;
+ }
+ } else {
+ fullpath = link_item;
+ }
+
+ // If we got here fullpath is the path to the file, and its readable.
+ set.insert(fullpath);
+
+ // If its an LLVM bitcode file ...
+ if (fullpath.isBitcodeFile()) {
+ // Process the dependent libraries recursively
+ Module::LibraryListType modlibs;
+ if (GetBitcodeDependentLibraries(fullpath.toString(),modlibs, &err)) {
+ // Traverse the dependent libraries list
+ Module::lib_iterator LI = modlibs.begin();
+ Module::lib_iterator LE = modlibs.end();
+ while ( LI != LE ) {
+ if (!ProcessLinkageItem(sys::Path(*LI),set,err)) {
+ if (err.empty()) {
+ err = std::string("Library '") + *LI +
+ "' is not valid for linking but is required by file '" +
+ fullpath.toString() + "'";
+ } else {
+ err += " which is required by file '" + fullpath.toString() + "'";
+ }
+ return false;
+ }
+ ++LI;
+ }
+ } else if (err.empty()) {
+ err = std::string(
+ "The dependent libraries could not be extracted from '") +
+ fullpath.toString();
+ return false;
+ } else
+ return false;
+ }
+ return true;
+ }
+
+/// @}
+/// @name Methods
+/// @{
+public:
+ virtual int execute(const InputList& InpList, const sys::Path& Output, std::string& ErrMsg ) {
+ try {
+ // Echo the configuration of options if we're running verbose
+ if (isSet(DEBUG_FLAG)) {
+ std::cerr << "Compiler Driver Options:\n";
+ std::cerr << "DryRun = " << isSet(DRY_RUN_FLAG) << "\n";
+ std::cerr << "Verbose = " << isSet(VERBOSE_FLAG) << " \n";
+ std::cerr << "TimeActions = " << isSet(TIME_ACTIONS_FLAG) << "\n";
+ std::cerr << "TimePasses = " << isSet(TIME_PASSES_FLAG) << "\n";
+ std::cerr << "ShowStats = " << isSet(SHOW_STATS_FLAG) << "\n";
+ std::cerr << "EmitRawCode = " << isSet(EMIT_RAW_FLAG) << "\n";
+ std::cerr << "EmitNativeCode = " << isSet(EMIT_NATIVE_FLAG) << "\n";
+ std::cerr << "KeepTemps = " << isSet(KEEP_TEMPS_FLAG) << "\n";
+ std::cerr << "OutputMachine = " << machine << "\n";
+ InputList::const_iterator I = InpList.begin();
+ while ( I != InpList.end() ) {
+ std::cerr << "Input: " << I->first << "(" << I->second
+ << ")\n";
+ ++I;
+ }
+ std::cerr << "Output: " << Output << "\n";
+ }
+
+ // If there's no input, we're done.
+ if (InpList.empty())
+ throw std::string("Nothing to compile.");
+
+ // If they are asking for linking and didn't provide an output
+ // file then its an error (no way for us to "make up" a meaningful
+ // file name based on the various linker input files).
+ if (finalPhase == LINKING && Output.isEmpty())
+ throw std::string(
+ "An output file name must be specified for linker output");
+
+ // If they are not asking for linking, provided an output file and
+ // there is more than one input file, its an error
+ if (finalPhase != LINKING && !Output.isEmpty() && InpList.size() > 1)
+ throw std::string("An output file name cannot be specified ") +
+ "with more than one input file name when not linking";
+
+ // This vector holds all the resulting actions of the following loop.
+ std::vector<Action*> actions;
+
+ /// PRE-PROCESSING / TRANSLATION / OPTIMIZATION / ASSEMBLY phases
+ // for each input item
+ SetVector<sys::Path> LinkageItems;
+ StringVector LibFiles;
+ InputList::const_iterator I = InpList.begin();
+ for (InputList::const_iterator I = InpList.begin(), E = InpList.end();
+ I != E; ++I ) {
+ // Get the suffix of the file name
+ const std::string& ftype = I->second;
+
+ // If its a library, bitcode file, or object file, save
+ // it for linking below and short circuit the
+ // pre-processing/translation/assembly phases
+ if (ftype.empty() || ftype == "o" || ftype == "bc" || ftype=="a") {
+ // We shouldn't get any of these types of files unless we're
+ // later going to link. Enforce this limit now.
+ if (finalPhase != LINKING) {
+ throw std::string(
+ "Pre-compiled objects found but linking not requested");
+ }
+ if (ftype.empty())
+ LibFiles.push_back(I->first.toString());
+ else
+ LinkageItems.insert(I->first);
+ continue; // short circuit remainder of loop
+ }
+
+ // At this point, we know its something we need to translate
+ // and/or optimize. See if we can get the configuration data
+ // for this kind of file.
+ ConfigData* cd = cdp->ProvideConfigData(I->second);
+ if (cd == 0)
+ throw std::string("Files of type '") + I->second +
+ "' are not recognized.";
+ if (isSet(DEBUG_FLAG))
+ DumpConfigData(cd,I->second);
+
+ // Add the config data's library paths to the end of the list
+ for (StringVector::iterator LPI = cd->libpaths.begin(),
+ LPE = cd->libpaths.end(); LPI != LPE; ++LPI){
+ LibraryPaths.push_back(sys::Path(*LPI));
+ }
+
+ // Initialize the input and output files
+ sys::Path InFile(I->first);
+ sys::Path OutFile(I->first.getBasename());
+
+ // PRE-PROCESSING PHASE
+ Action& action = cd->PreProcessor;
+
+ // Get the preprocessing action, if needed, or error if appropriate
+ if (!action.program.isEmpty()) {
+ if (action.isSet(REQUIRED_FLAG) || finalPhase == PREPROCESSING) {
+ if (finalPhase == PREPROCESSING) {
+ if (Output.isEmpty()) {
+ OutFile.appendSuffix("E");
+ actions.push_back(GetAction(cd,InFile,OutFile,PREPROCESSING));
+ } else {
+ actions.push_back(GetAction(cd,InFile,Output,PREPROCESSING));
+ }
+ } else {
+ sys::Path TempFile(
+ MakeTempFile(I->first.getBasename(),"E",&ErrMsg));
+ if (TempFile.isEmpty())
+ return 1;
+ actions.push_back(GetAction(cd,InFile,TempFile,
+ PREPROCESSING));
+ InFile = TempFile;
+ }
+ }
+ } else if (finalPhase == PREPROCESSING) {
+ throw cd->langName + " does not support pre-processing";
+ } else if (action.isSet(REQUIRED_FLAG)) {
+ throw std::string("Don't know how to pre-process ") +
+ cd->langName + " files";
+ }
+
+ // Short-circuit remaining actions if all they want is
+ // pre-processing
+ if (finalPhase == PREPROCESSING) { continue; };
+
+ /// TRANSLATION PHASE
+ action = cd->Translator;
+
+ // Get the translation action, if needed, or error if appropriate
+ if (!action.program.isEmpty()) {
+ if (action.isSet(REQUIRED_FLAG) || finalPhase == TRANSLATION) {
+ if (finalPhase == TRANSLATION) {
+ if (Output.isEmpty()) {
+ OutFile.appendSuffix("o");
+ actions.push_back(GetAction(cd,InFile,OutFile,TRANSLATION));
+ } else {
+ actions.push_back(GetAction(cd,InFile,Output,TRANSLATION));
+ }
+ } else {
+ sys::Path TempFile(
+ MakeTempFile(I->first.getBasename(),"trans", &ErrMsg));
+ if (TempFile.isEmpty())
+ return 1;
+ actions.push_back(GetAction(cd,InFile,TempFile,TRANSLATION));
+ InFile = TempFile;
+ }
+
+ // ll -> bc Helper
+ if (action.isSet(OUTPUT_IS_ASM_FLAG)) {
+ /// The output of the translator is an LLVM Assembly program
+ /// We need to translate it to bitcode
+ Action* action = new Action();
+ action->program.set("llvm-as");
+ action->args.push_back(InFile.toString());
+ action->args.push_back("-o");
+ InFile.appendSuffix("bc");
+ action->args.push_back(InFile.toString());
+ actions.push_back(action);
+ }
+ }
+ } else if (finalPhase == TRANSLATION) {
+ throw cd->langName + " does not support translation";
+ } else if (action.isSet(REQUIRED_FLAG)) {
+ throw std::string("Don't know how to translate ") +
+ cd->langName + " files";
+ }
+
+ // Short-circuit remaining actions if all they want is translation
+ if (finalPhase == TRANSLATION) { continue; }
+
+ /// OPTIMIZATION PHASE
+ action = cd->Optimizer;
+
+ // Get the optimization action, if needed, or error if appropriate
+ if (!isSet(EMIT_RAW_FLAG)) {
+ if (!action.program.isEmpty()) {
+ if (action.isSet(REQUIRED_FLAG) || finalPhase == OPTIMIZATION) {
+ if (finalPhase == OPTIMIZATION) {
+ if (Output.isEmpty()) {
+ OutFile.appendSuffix("o");
+ actions.push_back(GetAction(cd,InFile,OutFile,OPTIMIZATION));
+ } else {
+ actions.push_back(GetAction(cd,InFile,Output,OPTIMIZATION));
+ }
+ } else {
+ sys::Path TempFile(
+ MakeTempFile(I->first.getBasename(),"opt", &ErrMsg));
+ if (TempFile.isEmpty())
+ return 1;
+ actions.push_back(GetAction(cd,InFile,TempFile,OPTIMIZATION));
+ InFile = TempFile;
+ }
+ // ll -> bc Helper
+ if (action.isSet(OUTPUT_IS_ASM_FLAG)) {
+ /// The output of the optimizer is an LLVM Assembly program
+ /// We need to translate it to bitcode with llvm-as
+ Action* action = new Action();
+ action->program.set("llvm-as");
+ action->args.push_back(InFile.toString());
+ action->args.push_back("-f");
+ action->args.push_back("-o");
+ InFile.appendSuffix("bc");
+ action->args.push_back(InFile.toString());
+ actions.push_back(action);
+ }
+ }
+ } else if (finalPhase == OPTIMIZATION) {
+ throw cd->langName + " does not support optimization";
+ } else if (action.isSet(REQUIRED_FLAG)) {
+ throw std::string("Don't know how to optimize ") +
+ cd->langName + " files";
+ }
+ }
+
+ // Short-circuit remaining actions if all they want is optimization
+ if (finalPhase == OPTIMIZATION) { continue; }
+
+ /// ASSEMBLY PHASE
+ action = cd->Assembler;
+
+ if (finalPhase == ASSEMBLY) {
+
+ // Build either a native compilation action or a disassembly action
+ Action* action = new Action();
+ if (isSet(EMIT_NATIVE_FLAG)) {
+ // Use llc to get the native assembly file
+ action->program.set("llc");
+ action->args.push_back(InFile.toString());
+ action->args.push_back("-f");
+ action->args.push_back("-o");
+ if (Output.isEmpty()) {
+ OutFile.appendSuffix("o");
+ action->args.push_back(OutFile.toString());
+ } else {
+ action->args.push_back(Output.toString());
+ }
+ actions.push_back(action);
+ } else {
+ // Just convert back to llvm assembly with llvm-dis
+ action->program.set("llvm-dis");
+ action->args.push_back(InFile.toString());
+ action->args.push_back("-f");
+ action->args.push_back("-o");
+ if (Output.isEmpty()) {
+ OutFile.appendSuffix("ll");
+ action->args.push_back(OutFile.toString());
+ } else {
+ action->args.push_back(Output.toString());
+ }
+ }
+
+ // Put the action on the list
+ actions.push_back(action);
+
+ // Short circuit the rest of the loop, we don't want to link
+ continue;
+ }
+
+ // Register the result of the actions as a link candidate
+ LinkageItems.insert(InFile);
+
+ } // end while loop over each input file
+
+ /// RUN THE COMPILATION ACTIONS
+ std::vector<Action*>::iterator AI = actions.begin();
+ std::vector<Action*>::iterator AE = actions.end();
+ while (AI != AE) {
+ int ActionResult = DoAction(*AI, ErrMsg);
+ if (ActionResult != 0)
+ return ActionResult;
+ AI++;
+ }
+
+ /// LINKING PHASE
+ if (finalPhase == LINKING) {
+
+ // Insert the platform-specific system libraries to the path list
+ std::vector<sys::Path> SysLibs;
+ sys::Path::GetSystemLibraryPaths(SysLibs);
+ LibraryPaths.insert(LibraryPaths.end(), SysLibs.begin(), SysLibs.end());
+
+ // Set up the linking action with llvm-ld
+ Action* link = new Action();
+ link->program.set("llvm-ld");
+
+ // Add in the optimization level requested
+ switch (optLevel) {
+ case OPT_FAST_COMPILE:
+ link->args.push_back("-O1");
+ break;
+ case OPT_SIMPLE:
+ link->args.push_back("-O2");
+ break;
+ case OPT_AGGRESSIVE:
+ link->args.push_back("-O3");
+ break;
+ case OPT_LINK_TIME:
+ link->args.push_back("-O4");
+ break;
+ case OPT_AGGRESSIVE_LINK_TIME:
+ link->args.push_back("-O5");
+ break;
+ case OPT_NONE:
+ break;
+ }
+
+ // Add in all the linkage items we generated. This includes the
+ // output from the translation/optimization phases as well as any
+ // -l arguments specified.
+ for (PathVector::const_iterator I=LinkageItems.begin(),
+ E=LinkageItems.end(); I != E; ++I )
+ link->args.push_back(I->toString());
+
+ // Add in all the libraries we found.
+ for (StringVector::const_iterator I=LibFiles.begin(),
+ E=LibFiles.end(); I != E; ++I )
+ link->args.push_back(std::string("-l")+*I);
+
+ // Add in all the library paths to the command line
+ for (PathVector::const_iterator I=LibraryPaths.begin(),
+ E=LibraryPaths.end(); I != E; ++I)
+ link->args.push_back( std::string("-L") + I->toString());
+
+ // Add in the additional linker arguments requested
+ for (StringVector::const_iterator I=AdditionalArgs[LINKING].begin(),
+ E=AdditionalArgs[LINKING].end(); I != E; ++I)
+ link->args.push_back( *I );
+
+ // Add in other optional flags
+ if (isSet(EMIT_NATIVE_FLAG))
+ link->args.push_back("-native");
+ if (isSet(VERBOSE_FLAG))
+ link->args.push_back("-v");
+ if (isSet(TIME_PASSES_FLAG))
+ link->args.push_back("-time-passes");
+ if (isSet(SHOW_STATS_FLAG))
+ link->args.push_back("-stats");
+ if (isSet(STRIP_OUTPUT_FLAG))
+ link->args.push_back("-s");
+ if (isSet(DEBUG_FLAG)) {
+ link->args.push_back("-debug");
+ link->args.push_back("-debug-pass=Details");
+ }
+
+ // Add in mandatory flags
+ link->args.push_back("-o");
+ link->args.push_back(Output.toString());
+
+ // Execute the link
+ int ActionResult = DoAction(link, ErrMsg);
+ if (ActionResult != 0)
+ return ActionResult;
+ }
+ } catch (std::string& msg) {
+ cleanup();
+ throw;
+ } catch (...) {
+ cleanup();
+ throw std::string("Unspecified error");
+ }
+ cleanup();
+ return 0;
+ }
+
+/// @}
+/// @name Data
+/// @{
+private:
+ ConfigDataProvider* cdp; ///< Where we get configuration data from
+ Phases finalPhase; ///< The final phase of compilation
+ OptimizationLevels optLevel; ///< The optimization level to apply
+ unsigned Flags; ///< The driver flags
+ std::string machine; ///< Target machine name
+ PathVector LibraryPaths; ///< -L options
+ PathVector IncludePaths; ///< -I options
+ PathVector ToolPaths; ///< -B options
+ StringVector Defines; ///< -D options
+ sys::PathWithStatus TempDir; ///< Name of the temporary directory.
+ StringTable AdditionalArgs; ///< The -Txyz options
+ StringVector fOptions; ///< -f options
+ StringVector MOptions; ///< -M options
+ StringVector WOptions; ///< -W options
+
+/// @}
+};
+}
+
+CompilerDriver::~CompilerDriver() {
+}
+
+CompilerDriver::ConfigDataProvider::~ConfigDataProvider() {}
+
+CompilerDriver*
+CompilerDriver::Get(ConfigDataProvider& CDP) {
+ return new CompilerDriverImpl(CDP);
+}
+
+CompilerDriver::ConfigData::ConfigData()
+ : langName()
+ , PreProcessor()
+ , Translator()
+ , Optimizer()
+ , Assembler()
+ , Linker()
+{
+ StringVector emptyVec;
+ for (unsigned i = 0; i < NUM_PHASES; ++i)
+ opts.push_back(emptyVec);
+}
diff --git a/tools/llvmc/CompilerDriver.h b/tools/llvmc/CompilerDriver.h
new file mode 100644
index 0000000..f2be5cc
--- /dev/null
+++ b/tools/llvmc/CompilerDriver.h
@@ -0,0 +1,206 @@
+//===- CompilerDriver.h - Compiler Driver -----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and 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
diff --git a/tools/llvmc/ConfigLexer.cpp.cvs b/tools/llvmc/ConfigLexer.cpp.cvs
new file mode 100644
index 0000000..9cf8809
--- /dev/null
+++ b/tools/llvmc/ConfigLexer.cpp.cvs
@@ -0,0 +1,2724 @@
+#define yy_create_buffer Config_create_buffer
+#define yy_delete_buffer Config_delete_buffer
+#define yy_scan_buffer Config_scan_buffer
+#define yy_scan_string Config_scan_string
+#define yy_scan_bytes Config_scan_bytes
+#define yy_flex_debug Config_flex_debug
+#define yy_init_buffer Config_init_buffer
+#define yy_flush_buffer Config_flush_buffer
+#define yy_load_buffer_state Config_load_buffer_state
+#define yy_switch_to_buffer Config_switch_to_buffer
+#define yyin Configin
+#define yyleng Configleng
+#define yylex Configlex
+#define yyout Configout
+#define yyrestart Configrestart
+#define yytext Configtext
+
+#line 19 "ConfigLexer.cpp"
+/* A lexical scanner generated by flex */
+
+/* Scanner skeleton version:
+ * $Header: /cvs/root/flex/flex/skel.c,v 1.2 2004/05/07 00:28:17 jkh Exp $
+ */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+
+#include <stdio.h>
+
+
+/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
+#endif
+#endif
+
+
+#ifdef __cplusplus
+
+#include <stdlib.h>
+#include <unistd.h>
+
+/* Use prototypes in function declarations. */
+#define YY_USE_PROTOS
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_PROTOS
+#define YY_USE_CONST
+
+#endif /* __STDC__ */
+#endif /* ! __cplusplus */
+
+#ifdef __TURBOC__
+ #pragma warn -rch
+ #pragma warn -use
+#include <io.h>
+#include <stdlib.h>
+#define YY_USE_CONST
+#define YY_USE_PROTOS
+#endif
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+
+#ifdef YY_USE_PROTOS
+#define YY_PROTO(proto) proto
+#else
+#define YY_PROTO(proto) ()
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart( yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#define YY_BUF_SIZE (16384*64)
+
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+
+extern int yyleng;
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+/* The funky do-while in the following #define is used to turn the definition
+ * int a single C statement (which needs a semi-colon terminator). This
+ * avoids problems with code like:
+ *
+ * if ( condition_holds )
+ * yyless( 5 );
+ * else
+ * do_something_else();
+ *
+ * Prior to using the do-while the compiler would get upset at the
+ * "else" because it interpreted the "if" statement as being all
+ * done when it reached the ';' after the yyless() call.
+ */
+
+/* Return all but the first 'n' matched characters back to the input stream. */
+
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ *yy_cp = yy_hold_char; \
+ YY_RESTORE_YY_MORE_OFFSET \
+ yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, yytext_ptr )
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+typedef unsigned int yy_size_t;
+
+
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via yyrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+ };
+
+static YY_BUFFER_STATE yy_current_buffer = 0;
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ */
+#define YY_CURRENT_BUFFER yy_current_buffer
+
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+
+static int yy_n_chars; /* number of characters read into yy_ch_buf */
+
+
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 1; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart YY_PROTO(( FILE *input_file ));
+
+void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
+void yy_load_buffer_state YY_PROTO(( void ));
+YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
+void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
+void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
+
+YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
+YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));
+YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
+
+static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
+static inline void *yy_flex_realloc YY_PROTO(( void *, yy_size_t ));
+static void yy_flex_free YY_PROTO(( void * ));
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! yy_current_buffer ) \
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ yy_current_buffer->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! yy_current_buffer ) \
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ yy_current_buffer->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
+
+
+#define yywrap() 1
+#define YY_SKIP_YYWRAP
+typedef unsigned char YY_CHAR;
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+typedef int yy_state_type;
+extern char *yytext;
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state YY_PROTO(( void ));
+static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
+static int yy_get_next_buffer YY_PROTO(( void ));
+static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ yytext_ptr = yy_bp; \
+ yyleng = (int) (yy_cp - yy_bp); \
+ yy_hold_char = *yy_cp; \
+ *yy_cp = '\0'; \
+ yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 55
+#define YY_END_OF_BUFFER 56
+static yyconst short int yy_accept[408] =
+ { 0,
+ 1, 1, 56, 55, 1, 4, 55, 55, 55, 52,
+ 52, 6, 5, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 1, 4,
+ 0, 53, 0, 2, 0, 54, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 49, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 51, 52, 52, 50, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 3, 0, 52, 52, 52, 52, 52,
+
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 48, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 29, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 8, 9, 52, 52, 10,
+
+ 11, 12, 13, 14, 15, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 39, 40,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 26, 52, 28, 52,
+ 52, 52, 32, 52, 52, 52, 52, 43, 52, 52,
+ 52, 52, 52, 52, 52, 25, 52, 21, 52, 52,
+
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 46, 47, 52, 45, 30,
+ 52, 52, 52, 52, 41, 52, 52, 52, 52, 17,
+ 52, 52, 52, 52, 52, 52, 52, 52, 7, 52,
+ 52, 52, 52, 52, 27, 31, 52, 52, 52, 42,
+ 52, 52, 52, 52, 52, 52, 52, 18, 52, 52,
+ 52, 52, 52, 52, 37, 52, 35, 52, 52, 36,
+ 44, 24, 22, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 23, 19, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+
+ 52, 33, 20, 16, 38, 34, 0
+ } ;
+
+static yyconst int yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 1, 4, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 1, 5, 6, 1, 7, 1, 1, 1,
+ 1, 1, 8, 8, 8, 9, 8, 8, 10, 11,
+ 12, 13, 14, 8, 8, 8, 8, 8, 1, 1,
+ 15, 1, 1, 16, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, 24, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 24, 39, 40,
+ 1, 41, 1, 1, 8, 1, 42, 43, 44, 45,
+
+ 46, 47, 48, 49, 50, 24, 51, 52, 53, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62, 24, 63,
+ 64, 65, 1, 8, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static yyconst int yy_meta[66] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 2, 3, 1, 3,
+ 3, 3, 3, 3, 1, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3
+ } ;
+
+static yyconst short int yy_base[412] =
+ { 0,
+ 0, 0, 716, 3252, 713, 3252, 711, 708, 63, 61,
+ 0, 3252, 3252, 36, 57, 50, 67, 68, 70, 93,
+ 59, 73, 68, 93, 106, 75, 652, 46, 655, 667,
+ 41, 86, 89, 650, 661, 648, 659, 658, 701, 3252,
+ 697, 3252, 94, 3252, 698, 3252, 0, 148, 183, 218,
+ 253, 305, 349, 389, 424, 472, 518, 573, 627, 671,
+ 103, 641, 0, 664, 638, 669, 643, 668, 642, 664,
+ 115, 638, 92, 663, 0, 637, 667, 0, 653, 651,
+ 633, 616, 615, 653, 627, 640, 614, 115, 92, 637,
+ 609, 632, 606, 3252, 661, 89, 603, 609, 609, 606,
+
+ 114, 606, 611, 597, 596, 609, 597, 121, 595, 593,
+ 711, 761, 811, 853, 901, 942, 992, 1030, 1067, 1123,
+ 1177, 1231, 1267, 1319, 1366, 0, 630, 604, 630, 604,
+ 619, 593, 611, 585, 619, 602, 606, 583, 571, 578,
+ 607, 581, 159, 595, 164, 569, 593, 592, 586, 560,
+ 591, 598, 564, 571, 582, 556, 567, 568, 558, 551,
+ 561, 549, 556, 560, 190, 549, 548, 542, 548, 555,
+ 541, 1418, 1472, 1526, 1579, 1618, 1671, 3252, 1725, 1771,
+ 1824, 231, 242, 1871, 1925, 1967, 2007, 571, 545, 567,
+ 541, 577, 551, 571, 545, 0, 0, 569, 542, 0,
+
+ 0, 0, 0, 0, 0, 550, 541, 523, 514, 540,
+ 514, 546, 513, 526, 499, 531, 500, 494, 491, 501,
+ 491, 481, 468, 458, 452, 459, 448, 451, 2044, 2097,
+ 263, 2150, 279, 2194, 2247, 2300, 289, 2344, 3252, 3252,
+ 2386, 2439, 325, 2479, 473, 438, 457, 431, 445, 419,
+ 438, 403, 430, 417, 399, 383, 409, 378, 396, 370,
+ 400, 373, 386, 360, 370, 367, 357, 352, 359, 348,
+ 352, 348, 346, 339, 337, 363, 3252, 2528, 3252, 373,
+ 410, 2580, 3252, 2632, 2670, 434, 2727, 3252, 2781, 366,
+ 340, 370, 342, 362, 327, 0, 329, 0, 303, 348,
+
+ 320, 337, 308, 335, 301, 313, 286, 282, 285, 284,
+ 263, 283, 280, 283, 270, 3252, 3252, 446, 3252, 3252,
+ 456, 482, 2834, 2872, 3252, 492, 2929, 144, 121, 0,
+ 302, 276, 293, 264, 289, 263, 272, 246, 0, 134,
+ 252, 242, 240, 224, 3252, 3252, 74, 2969, 504, 3252,
+ 528, 249, 223, 247, 220, 234, 203, 0, 158, 160,
+ 199, 193, 187, 161, 3252, 185, 3252, 3008, 3060, 3252,
+ 3252, 0, 0, 202, 176, 199, 194, 164, 164, 162,
+ 161, 154, 150, 3104, 3142, 187, 163, 0, 0, 164,
+ 146, 3194, 541, 158, 154, 127, 123, 107, 80, 81,
+
+ 554, 3252, 0, 0, 3252, 3252, 3252, 3243, 3246, 3248,
+ 83
+ } ;
+
+static yyconst short int yy_def[412] =
+ { 0,
+ 407, 1, 407, 407, 407, 407, 407, 408, 409, 410,
+ 411, 407, 407, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 407, 407,
+ 408, 407, 409, 407, 407, 407, 411, 410, 410, 410,
+ 410, 410, 410, 410, 410, 410, 410, 410, 410, 410,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 407, 407, 411, 411, 411, 411, 411,
+
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 410, 410, 410, 410, 410, 410, 410, 410, 410, 410,
+ 410, 410, 410, 410, 410, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 410, 410, 410, 410, 410, 410, 407, 410, 410,
+ 410, 410, 410, 410, 410, 410, 410, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 410, 410,
+ 410, 410, 410, 410, 410, 410, 410, 410, 407, 407,
+ 410, 410, 410, 410, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 410, 410, 407, 410, 407, 410,
+ 410, 410, 407, 410, 410, 410, 410, 407, 410, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 407, 407, 410, 407, 407,
+ 410, 410, 410, 410, 407, 410, 410, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 407, 407, 411, 410, 410, 407,
+ 410, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 407, 411, 407, 410, 410, 407,
+ 407, 411, 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 410, 410, 411, 411, 411, 411, 411,
+ 411, 410, 410, 411, 411, 411, 411, 411, 411, 411,
+
+ 410, 407, 411, 411, 407, 407, 0, 407, 407, 407,
+ 407
+ } ;
+
+static yyconst short int yy_nxt[3318] =
+ { 0,
+ 4, 5, 6, 7, 8, 9, 10, 11, 12, 11,
+ 11, 11, 11, 11, 13, 4, 14, 15, 16, 11,
+ 11, 17, 11, 11, 11, 11, 18, 11, 19, 20,
+ 21, 11, 22, 11, 23, 11, 24, 11, 25, 11,
+ 26, 27, 28, 29, 11, 11, 30, 11, 11, 11,
+ 11, 31, 11, 32, 33, 34, 11, 35, 11, 36,
+ 11, 37, 11, 38, 11, 44, 45, 46, 47, 61,
+ 47, 47, 47, 47, 47, 63, 47, 94, 95, 66,
+ 365, 64, 100, 68, 70, 47, 74, 405, 49, 63,
+ 101, 84, 71, 86, 62, 97, 44, 45, 50, 75,
+
+ 88, 47, 51, 52, 67, 53, 65, 54, 69, 72,
+ 55, 76, 56, 90, 77, 57, 85, 73, 87, 58,
+ 59, 78, 60, 79, 75, 89, 92, 102, 80, 366,
+ 126, 151, 136, 153, 139, 103, 127, 404, 91, 81,
+ 75, 126, 78, 137, 104, 140, 78, 157, 82, 105,
+ 152, 93, 154, 83, 46, 47, 162, 47, 47, 47,
+ 47, 47, 169, 47, 352, 403, 353, 163, 201, 202,
+ 203, 204, 205, 201, 202, 203, 204, 205, 376, 361,
+ 404, 170, 126, 206, 126, 403, 404, 377, 47, 46,
+ 47, 403, 47, 47, 47, 47, 47, 126, 47, 201,
+
+ 202, 203, 204, 205, 400, 378, 381, 394, 396, 398,
+ 391, 389, 111, 208, 379, 382, 395, 397, 399, 388,
+ 390, 389, 388, 47, 46, 47, 389, 47, 47, 47,
+ 47, 47, 388, 47, 387, 386, 383, 239, 47, 223,
+ 47, 47, 47, 47, 47, 380, 47, 112, 240, 47,
+ 373, 47, 47, 47, 47, 47, 372, 47, 47, 46,
+ 47, 375, 47, 47, 47, 47, 47, 374, 47, 277,
+ 47, 47, 47, 47, 47, 47, 47, 373, 47, 373,
+ 372, 372, 47, 364, 358, 279, 47, 363, 47, 47,
+ 47, 47, 47, 47, 47, 283, 47, 362, 47, 47,
+
+ 47, 47, 47, 47, 47, 360, 359, 358, 358, 357,
+ 113, 46, 47, 356, 47, 47, 47, 47, 47, 47,
+ 47, 355, 354, 339, 344, 343, 342, 341, 330, 47,
+ 63, 288, 47, 340, 47, 47, 47, 47, 47, 339,
+ 47, 339, 338, 316, 47, 47, 47, 47, 47, 47,
+ 47, 337, 47, 336, 114, 46, 47, 335, 47, 47,
+ 47, 47, 47, 334, 47, 47, 333, 332, 331, 317,
+ 47, 330, 47, 47, 47, 47, 47, 47, 47, 319,
+ 47, 330, 47, 47, 47, 47, 47, 63, 47, 47,
+ 63, 329, 328, 315, 115, 46, 47, 314, 47, 47,
+
+ 47, 47, 47, 47, 47, 313, 312, 298, 311, 296,
+ 310, 309, 308, 47, 307, 306, 320, 47, 116, 47,
+ 47, 47, 47, 47, 305, 47, 304, 303, 302, 47,
+ 46, 47, 301, 47, 47, 47, 47, 47, 300, 47,
+ 325, 47, 298, 47, 47, 47, 47, 47, 299, 47,
+ 47, 298, 345, 47, 297, 47, 47, 47, 47, 47,
+ 296, 47, 346, 47, 47, 47, 47, 47, 47, 47,
+ 296, 47, 295, 294, 47, 293, 292, 117, 46, 47,
+ 291, 47, 47, 47, 47, 47, 47, 47, 46, 47,
+ 290, 347, 47, 47, 47, 47, 47, 47, 350, 47,
+
+ 274, 47, 47, 47, 47, 47, 273, 47, 272, 271,
+ 370, 47, 47, 47, 47, 47, 47, 47, 270, 47,
+ 269, 118, 47, 119, 46, 47, 268, 47, 47, 47,
+ 47, 47, 47, 47, 371, 47, 75, 47, 47, 47,
+ 47, 47, 267, 47, 47, 266, 265, 402, 47, 264,
+ 47, 47, 47, 47, 47, 263, 47, 262, 47, 261,
+ 406, 47, 260, 47, 47, 47, 47, 47, 47, 47,
+ 259, 258, 257, 120, 256, 255, 254, 253, 121, 46,
+ 47, 47, 47, 47, 47, 47, 47, 252, 47, 251,
+ 75, 75, 250, 249, 47, 248, 247, 246, 245, 228,
+
+ 78, 227, 226, 225, 224, 200, 222, 197, 196, 221,
+ 220, 219, 218, 47, 217, 216, 78, 215, 78, 214,
+ 213, 212, 211, 210, 209, 207, 200, 200, 199, 197,
+ 196, 198, 122, 46, 47, 197, 47, 47, 47, 47,
+ 47, 196, 47, 195, 194, 193, 192, 191, 190, 189,
+ 188, 78, 171, 168, 167, 166, 165, 75, 164, 161,
+ 160, 159, 158, 94, 78, 78, 156, 47, 123, 155,
+ 150, 149, 148, 147, 146, 145, 124, 46, 47, 75,
+ 47, 47, 47, 47, 47, 144, 47, 143, 75, 142,
+ 141, 138, 135, 134, 133, 132, 131, 130, 129, 128,
+
+ 44, 42, 39, 110, 109, 108, 107, 106, 99, 98,
+ 96, 47, 42, 40, 39, 407, 125, 46, 47, 407,
+ 47, 47, 47, 47, 47, 407, 47, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 47, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 172, 46, 47, 407,
+ 47, 47, 47, 47, 47, 407, 47, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+
+ 407, 47, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 173, 46, 47, 407,
+ 47, 47, 47, 47, 47, 407, 47, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 47, 407, 407, 407, 407, 407, 407, 174, 46,
+ 47, 407, 47, 47, 47, 47, 47, 407, 47, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 47, 407, 407, 407, 407, 407, 407,
+
+ 407, 407, 407, 407, 407, 407, 175, 46, 47, 407,
+ 47, 47, 47, 47, 47, 407, 47, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 47, 407, 407, 407, 407, 407, 176, 46, 47,
+ 407, 47, 47, 47, 47, 47, 407, 47, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 47, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 177, 178, 47,
+
+ 407, 47, 47, 47, 47, 47, 407, 47, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 47, 407, 407, 179, 46, 47, 407, 47,
+ 47, 47, 47, 47, 407, 47, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 47, 407, 180, 46, 47, 407, 47, 47, 47, 47,
+ 47, 407, 47, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+
+ 407, 407, 407, 407, 407, 407, 407, 47, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 181, 46,
+ 47, 407, 47, 47, 47, 47, 47, 407, 47, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 47, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 182, 46, 47, 407, 47, 47, 47, 47,
+ 47, 407, 47, 407, 407, 407, 407, 407, 407, 407,
+
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 47, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 183, 46, 47, 407,
+ 47, 47, 47, 47, 47, 407, 47, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 47, 184, 46, 47, 407, 47, 47, 47, 47,
+ 47, 407, 47, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+
+ 407, 407, 407, 407, 407, 407, 407, 47, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 185, 46, 47, 407, 47, 47,
+ 47, 47, 47, 407, 47, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 47,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 186, 46, 47, 407, 47, 47, 47, 47, 47,
+ 407, 47, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+
+ 407, 407, 407, 407, 407, 407, 47, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 187, 46, 47, 407, 47, 47, 47,
+ 47, 47, 407, 47, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 47, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 229, 46, 47,
+ 407, 47, 47, 47, 47, 47, 407, 47, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 47, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 230, 46, 47, 407, 47, 47, 47, 47, 47,
+ 407, 47, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 47, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 231, 46, 47, 407, 47, 47,
+ 47, 47, 47, 407, 47, 407, 407, 407, 407, 407,
+
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 47,
+ 407, 407, 407, 232, 46, 47, 407, 47, 47, 47,
+ 47, 47, 407, 47, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 47, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 233, 46, 47, 407,
+ 47, 47, 47, 47, 47, 407, 47, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 47, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 234, 46, 47, 407, 47, 47, 47, 47, 47, 407,
+ 47, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 47, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 235, 46, 47, 407,
+ 47, 47, 47, 47, 47, 407, 47, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 47, 407, 407, 407, 236, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 237,
+ 46, 47, 407, 47, 47, 47, 47, 47, 407, 47,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 47, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 238, 46, 47, 407,
+ 47, 47, 47, 47, 47, 407, 47, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 47, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 241, 46, 47, 407, 47, 47, 47, 47, 47, 407,
+ 47, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 47, 407, 407, 407, 407,
+ 407, 407, 242, 46, 47, 407, 47, 47, 47, 47,
+ 47, 407, 47, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+
+ 407, 407, 407, 407, 407, 407, 407, 47, 407, 407,
+ 407, 407, 243, 46, 47, 407, 47, 47, 47, 47,
+ 47, 407, 47, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 47, 407, 244,
+ 46, 47, 407, 47, 47, 47, 47, 47, 407, 47,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 47, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+
+ 407, 407, 275, 46, 47, 407, 47, 47, 47, 47,
+ 47, 407, 47, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 47, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 276, 46, 47, 407, 47,
+ 47, 47, 47, 47, 407, 47, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 47, 407, 407, 407, 407, 407, 407, 407, 407, 278,
+
+ 46, 47, 407, 47, 47, 47, 47, 47, 407, 47,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 47, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 280, 46, 47, 407, 47, 47, 47, 47,
+ 47, 407, 47, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 47, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+
+ 407, 407, 407, 407, 407, 281, 46, 47, 407, 47,
+ 47, 47, 47, 47, 407, 47, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 47, 407, 407, 407, 407, 407, 407, 407, 407, 282,
+ 46, 47, 407, 47, 47, 47, 47, 47, 407, 47,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 47, 407, 407, 284, 407, 407,
+ 407, 285, 46, 47, 407, 47, 47, 47, 47, 47,
+
+ 407, 47, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 47, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 286, 46, 47, 407, 47, 47,
+ 47, 47, 47, 407, 47, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 47,
+ 407, 407, 407, 407, 287, 46, 47, 407, 47, 47,
+ 47, 47, 47, 407, 47, 407, 407, 407, 407, 407,
+
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 47,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 289, 46, 47, 407, 47, 47, 47,
+ 47, 47, 407, 47, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 47, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 318, 46, 47, 407, 47,
+ 47, 47, 47, 47, 407, 47, 407, 407, 407, 407,
+
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 47, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 321, 46, 47,
+ 407, 47, 47, 47, 47, 47, 407, 47, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 47, 407, 407, 322, 46, 47, 407, 47,
+ 47, 47, 47, 47, 407, 47, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 47, 407, 407, 323, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 324, 46, 47, 407, 47, 47, 47, 47,
+ 47, 407, 47, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 47, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 326, 46, 47, 407,
+ 47, 47, 47, 47, 47, 407, 47, 407, 407, 407,
+
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 47, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 327,
+ 46, 47, 407, 47, 47, 47, 47, 47, 407, 47,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 47, 407, 407, 348, 46, 47,
+ 407, 47, 47, 47, 47, 47, 407, 47, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 47, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 349, 46, 47, 407, 47, 47,
+ 47, 47, 47, 407, 47, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 47,
+ 407, 407, 407, 407, 351, 367, 47, 407, 47, 47,
+ 47, 47, 47, 407, 47, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 47,
+ 368, 407, 407, 369, 46, 47, 407, 47, 47, 47,
+ 47, 47, 407, 47, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 47, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 384, 46, 47, 407, 47,
+ 47, 47, 47, 47, 407, 47, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+
+ 47, 407, 407, 407, 407, 407, 407, 407, 407, 385,
+ 46, 47, 407, 47, 47, 47, 47, 47, 407, 47,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 47, 407, 407, 392, 46, 47,
+ 407, 47, 47, 47, 47, 47, 407, 47, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 47, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 393,
+
+ 46, 47, 407, 47, 47, 47, 47, 47, 407, 47,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 47, 407, 407, 407, 407, 407,
+ 407, 407, 401, 41, 41, 41, 43, 43, 43, 48,
+ 48, 3, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407
+ } ;
+
+static yyconst short int yy_chk[3318] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 9, 9, 10, 10, 14,
+ 10, 10, 10, 10, 10, 15, 10, 26, 26, 16,
+ 347, 15, 31, 17, 18, 411, 19, 400, 10, 28,
+ 31, 21, 18, 22, 14, 28, 43, 43, 10, 19,
+
+ 23, 10, 10, 10, 16, 10, 15, 10, 17, 18,
+ 10, 19, 10, 24, 20, 10, 21, 18, 22, 10,
+ 10, 20, 10, 20, 19, 23, 25, 32, 20, 347,
+ 61, 88, 71, 89, 73, 33, 61, 399, 24, 20,
+ 32, 96, 33, 71, 33, 73, 20, 96, 20, 33,
+ 88, 25, 89, 20, 48, 48, 101, 48, 48, 48,
+ 48, 48, 108, 48, 328, 398, 329, 101, 143, 143,
+ 143, 143, 143, 145, 145, 145, 145, 145, 359, 340,
+ 397, 108, 328, 143, 329, 396, 395, 359, 48, 49,
+ 49, 394, 49, 49, 49, 49, 49, 340, 49, 165,
+
+ 165, 165, 165, 165, 391, 360, 364, 386, 387, 390,
+ 383, 382, 49, 145, 360, 364, 386, 387, 390, 381,
+ 380, 379, 378, 49, 50, 50, 377, 50, 50, 50,
+ 50, 50, 376, 50, 375, 374, 366, 182, 182, 165,
+ 182, 182, 182, 182, 182, 363, 182, 50, 183, 183,
+ 362, 183, 183, 183, 183, 183, 361, 183, 50, 51,
+ 51, 357, 51, 51, 51, 51, 51, 356, 51, 231,
+ 231, 182, 231, 231, 231, 231, 231, 355, 231, 354,
+ 353, 352, 183, 344, 343, 233, 233, 342, 233, 233,
+ 233, 233, 233, 51, 233, 237, 237, 341, 237, 237,
+
+ 237, 237, 237, 231, 237, 338, 337, 336, 335, 334,
+ 51, 52, 52, 333, 52, 52, 52, 52, 52, 233,
+ 52, 332, 331, 315, 314, 313, 312, 311, 310, 237,
+ 309, 243, 243, 308, 243, 243, 243, 243, 243, 307,
+ 243, 306, 305, 275, 275, 52, 275, 275, 275, 275,
+ 275, 304, 275, 303, 52, 53, 53, 302, 53, 53,
+ 53, 53, 53, 301, 53, 243, 300, 299, 297, 276,
+ 276, 295, 276, 276, 276, 276, 276, 275, 276, 280,
+ 280, 294, 280, 280, 280, 280, 280, 293, 280, 53,
+ 292, 291, 290, 274, 53, 54, 54, 273, 54, 54,
+
+ 54, 54, 54, 276, 54, 272, 271, 270, 269, 268,
+ 267, 266, 265, 280, 264, 263, 281, 281, 54, 281,
+ 281, 281, 281, 281, 262, 281, 261, 260, 259, 54,
+ 55, 55, 258, 55, 55, 55, 55, 55, 257, 55,
+ 286, 286, 256, 286, 286, 286, 286, 286, 255, 286,
+ 281, 254, 318, 318, 253, 318, 318, 318, 318, 318,
+ 252, 318, 321, 321, 55, 321, 321, 321, 321, 321,
+ 251, 321, 250, 249, 286, 248, 247, 55, 56, 56,
+ 246, 56, 56, 56, 56, 56, 318, 56, 322, 322,
+ 245, 322, 322, 322, 322, 322, 321, 322, 326, 326,
+
+ 228, 326, 326, 326, 326, 326, 227, 326, 226, 225,
+ 349, 349, 56, 349, 349, 349, 349, 349, 224, 349,
+ 223, 56, 322, 56, 57, 57, 222, 57, 57, 57,
+ 57, 57, 326, 57, 351, 351, 221, 351, 351, 351,
+ 351, 351, 220, 351, 349, 219, 218, 393, 393, 217,
+ 393, 393, 393, 393, 393, 216, 393, 215, 57, 214,
+ 401, 401, 213, 401, 401, 401, 401, 401, 351, 401,
+ 212, 211, 210, 57, 209, 208, 207, 206, 57, 58,
+ 58, 393, 58, 58, 58, 58, 58, 199, 58, 198,
+ 195, 194, 193, 192, 401, 191, 190, 189, 188, 171,
+
+ 170, 169, 168, 167, 166, 164, 163, 162, 161, 160,
+ 159, 158, 157, 58, 156, 155, 154, 153, 152, 151,
+ 150, 149, 148, 147, 146, 144, 142, 141, 140, 139,
+ 138, 137, 58, 59, 59, 136, 59, 59, 59, 59,
+ 59, 135, 59, 134, 133, 132, 131, 130, 129, 128,
+ 127, 110, 109, 107, 106, 105, 104, 103, 102, 100,
+ 99, 98, 97, 95, 93, 92, 91, 59, 59, 90,
+ 87, 86, 85, 84, 83, 82, 59, 60, 60, 81,
+ 60, 60, 60, 60, 60, 80, 60, 79, 77, 76,
+ 74, 72, 70, 69, 68, 67, 66, 65, 64, 62,
+
+ 45, 41, 39, 38, 37, 36, 35, 34, 30, 29,
+ 27, 60, 8, 7, 5, 3, 60, 111, 111, 0,
+ 111, 111, 111, 111, 111, 0, 111, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 111, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 111, 112, 112, 0,
+ 112, 112, 112, 112, 112, 0, 112, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 112, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 112, 113, 113, 0,
+ 113, 113, 113, 113, 113, 0, 113, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 113, 0, 0, 0, 0, 0, 0, 113, 114,
+ 114, 0, 114, 114, 114, 114, 114, 0, 114, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 114, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 114, 115, 115, 0,
+ 115, 115, 115, 115, 115, 0, 115, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 115, 0, 0, 0, 0, 0, 115, 116, 116,
+ 0, 116, 116, 116, 116, 116, 0, 116, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 116, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 116, 117, 117,
+
+ 0, 117, 117, 117, 117, 117, 0, 117, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 117, 0, 0, 117, 118, 118, 0, 118,
+ 118, 118, 118, 118, 0, 118, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 118, 0, 118, 119, 119, 0, 119, 119, 119, 119,
+ 119, 0, 119, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 119, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 119, 120,
+ 120, 0, 120, 120, 120, 120, 120, 0, 120, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 120, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 120, 121, 121, 0, 121, 121, 121, 121,
+ 121, 0, 121, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 121, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 121, 122, 122, 0,
+ 122, 122, 122, 122, 122, 0, 122, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 122, 122, 123, 123, 0, 123, 123, 123, 123,
+ 123, 0, 123, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 123, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 123, 124, 124, 0, 124, 124,
+ 124, 124, 124, 0, 124, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 124,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 124, 125, 125, 0, 125, 125, 125, 125, 125,
+ 0, 125, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 125, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 125, 172, 172, 0, 172, 172, 172,
+ 172, 172, 0, 172, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 172, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 172, 173, 173,
+ 0, 173, 173, 173, 173, 173, 0, 173, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 173, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 173, 174, 174, 0, 174, 174, 174, 174, 174,
+ 0, 174, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 174, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 174, 175, 175, 0, 175, 175,
+ 175, 175, 175, 0, 175, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 175,
+ 0, 0, 0, 175, 176, 176, 0, 176, 176, 176,
+ 176, 176, 0, 176, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 176, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 176, 177, 177, 0,
+ 177, 177, 177, 177, 177, 0, 177, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 177, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 177, 179, 179, 0, 179, 179, 179, 179, 179, 0,
+ 179, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 179, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 179, 180, 180, 0,
+ 180, 180, 180, 180, 180, 0, 180, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 180, 0, 0, 0, 180, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 180,
+ 181, 181, 0, 181, 181, 181, 181, 181, 0, 181,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 181, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 181, 184, 184, 0,
+ 184, 184, 184, 184, 184, 0, 184, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 184, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 184, 185, 185, 0, 185, 185, 185, 185, 185, 0,
+ 185, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 185, 0, 0, 0, 0,
+ 0, 0, 185, 186, 186, 0, 186, 186, 186, 186,
+ 186, 0, 186, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 186, 0, 0,
+ 0, 0, 186, 187, 187, 0, 187, 187, 187, 187,
+ 187, 0, 187, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 187, 0, 187,
+ 229, 229, 0, 229, 229, 229, 229, 229, 0, 229,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 229, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 229, 230, 230, 0, 230, 230, 230, 230,
+ 230, 0, 230, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 230, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 230, 232, 232, 0, 232,
+ 232, 232, 232, 232, 0, 232, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 232, 0, 0, 0, 0, 0, 0, 0, 0, 232,
+
+ 234, 234, 0, 234, 234, 234, 234, 234, 0, 234,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 234, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 234, 235, 235, 0, 235, 235, 235, 235,
+ 235, 0, 235, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 235, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 235, 236, 236, 0, 236,
+ 236, 236, 236, 236, 0, 236, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 236, 0, 0, 0, 0, 0, 0, 0, 0, 236,
+ 238, 238, 0, 238, 238, 238, 238, 238, 0, 238,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 238, 0, 0, 238, 0, 0,
+ 0, 238, 241, 241, 0, 241, 241, 241, 241, 241,
+
+ 0, 241, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 241, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 241, 242, 242, 0, 242, 242,
+ 242, 242, 242, 0, 242, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 242,
+ 0, 0, 0, 0, 242, 244, 244, 0, 244, 244,
+ 244, 244, 244, 0, 244, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 244,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 244, 278, 278, 0, 278, 278, 278,
+ 278, 278, 0, 278, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 278, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 278, 282, 282, 0, 282,
+ 282, 282, 282, 282, 0, 282, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 282, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 282, 284, 284,
+ 0, 284, 284, 284, 284, 284, 0, 284, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 284, 0, 0, 284, 285, 285, 0, 285,
+ 285, 285, 285, 285, 0, 285, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 285, 0, 0, 285, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 285, 287, 287, 0, 287, 287, 287, 287,
+ 287, 0, 287, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 287, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 287, 289, 289, 0,
+ 289, 289, 289, 289, 289, 0, 289, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 289, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 289,
+ 323, 323, 0, 323, 323, 323, 323, 323, 0, 323,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 323, 0, 0, 323, 324, 324,
+ 0, 324, 324, 324, 324, 324, 0, 324, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 324, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 324, 327, 327, 0, 327, 327,
+ 327, 327, 327, 0, 327, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 327,
+ 0, 0, 0, 0, 327, 348, 348, 0, 348, 348,
+ 348, 348, 348, 0, 348, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 348,
+ 348, 0, 0, 348, 368, 368, 0, 368, 368, 368,
+ 368, 368, 0, 368, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 368, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 368, 369, 369, 0, 369,
+ 369, 369, 369, 369, 0, 369, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 369, 0, 0, 0, 0, 0, 0, 0, 0, 369,
+ 384, 384, 0, 384, 384, 384, 384, 384, 0, 384,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 384, 0, 0, 384, 385, 385,
+ 0, 385, 385, 385, 385, 385, 0, 385, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 385, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 385,
+
+ 392, 392, 0, 392, 392, 392, 392, 392, 0, 392,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 392, 0, 0, 0, 0, 0,
+ 0, 0, 392, 408, 408, 408, 409, 409, 409, 410,
+ 410, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+
+ 407, 407, 407, 407, 407, 407, 407, 407, 407, 407,
+ 407, 407, 407, 407, 407, 407, 407
+ } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+#define INITIAL 0
+/*===- ConfigLexer.l - Scanner for CompilerDriver Config Files -*- C++ -*--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and 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.
+//
+//===----------------------------------------------------------------------===*/
+#define YY_NEVER_INTERACTIVE 1
+#line 29 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+
+#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;
+}
+
+#line 1314 "ConfigLexer.cpp"
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap YY_PROTO(( void ));
+#else
+extern int yywrap YY_PROTO(( void ));
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+static inline void yyunput YY_PROTO(( int c, char *buf_ptr ));
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen YY_PROTO(( yyconst char * ));
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput YY_PROTO(( void ));
+#else
+static int input YY_PROTO(( void ));
+#endif
+#endif
+
+#if YY_STACK_USED
+static int yy_start_stack_ptr = 0;
+static int yy_start_stack_depth = 0;
+static int *yy_start_stack = 0;
+#ifndef YY_NO_PUSH_STATE
+static void yy_push_state YY_PROTO(( int new_state ));
+#endif
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state YY_PROTO(( void ));
+#endif
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state YY_PROTO(( void ));
+#endif
+
+#else
+#define YY_NO_PUSH_STATE 1
+#define YY_NO_POP_STATE 1
+#define YY_NO_TOP_STATE 1
+#endif
+
+#ifdef YY_MALLOC_DECL
+YY_MALLOC_DECL
+#else
+#if __STDC__
+#ifndef __cplusplus
+#include <stdlib.h>
+#endif
+#else
+/* Just try to get by without declaring the routines. This will fail
+ * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
+ * or sizeof(void*) != sizeof(int).
+ */
+#endif
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( yy_current_buffer->yy_is_interactive ) \
+ { \
+ int c = '*', n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \
+ && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" );
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL int yylex YY_PROTO(( void ))
+#endif
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ YY_USER_ACTION
+
+YY_DECL
+ {
+ register yy_state_type yy_current_state;
+ register char *yy_cp, *yy_bp;
+ register int yy_act;
+
+#line 114 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+
+
+#line 1468 "ConfigLexer.cpp"
+
+ if ( yy_init )
+ {
+ yy_init = 0;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! yy_start )
+ yy_start = 1; /* first start state */
+
+ if ( ! yyin )
+ yyin = stdin;
+
+ if ( ! yyout )
+ yyout = stdout;
+
+ if ( ! yy_current_buffer )
+ yy_current_buffer =
+ yy_create_buffer( yyin, YY_BUF_SIZE );
+
+ yy_load_buffer_state();
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = yy_c_buf_p;
+
+ /* Support of yytext. */
+ *yy_cp = yy_hold_char;
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = yy_start;
+yy_match:
+ do
+ {
+ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+ if ( yy_accept[yy_current_state] )
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 408 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ ++yy_cp;
+ }
+ while ( yy_current_state != 407 );
+ yy_cp = yy_last_accepting_cpos;
+ yy_current_state = yy_last_accepting_state;
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+
+ YY_DO_BEFORE_ACTION;
+
+
+do_action: /* This label is used only to access EOF actions. */
+
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = yy_hold_char;
+ yy_cp = yy_last_accepting_cpos;
+ yy_current_state = yy_last_accepting_state;
+ goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 116 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ if (ConfigLexerState.in_value) return SPACE; }
+ YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 118 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ /* Ignore comments */
+ ConfigLexerState.in_value = false;
+ ConfigLexerState.lineNum++;
+ return EOLTOK;
+ }
+ YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 124 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ ConfigLexerState.lineNum++;
+ /* Don't return EOLTOK! */
+ }
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 128 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ ConfigLexerState.in_value = false;
+ ConfigLexerState.lineNum++;
+ return EOLTOK;
+ }
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 133 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ ConfigLexerState.in_value = true;
+ return EQUALS;
+ }
+ YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 137 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return SEPARATOR; }
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 139 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleNameContext(VERSION_TOK); }
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 141 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleNameContext(LANG); }
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 142 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleNameContext(LIBS); }
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 143 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleNameContext(NAME); }
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 144 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleNameContext(OPT1); }
+ YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 145 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleNameContext(OPT2); }
+ YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 146 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleNameContext(OPT3); }
+ YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 147 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleNameContext(OPT4); }
+ YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 148 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleNameContext(OPT5); }
+ YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 150 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleNameContext(PREPROCESSOR); }
+ YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 151 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleNameContext(COMMAND); }
+ YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 152 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleNameContext(REQUIRED); }
+ YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 154 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleNameContext(TRANSLATOR); }
+ YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 155 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleNameContext(PREPROCESSES); }
+ YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 156 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleNameContext(OUTPUT); }
+ YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 158 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleNameContext(OPTIMIZER); }
+ YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 159 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleNameContext(TRANSLATES); }
+ YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 161 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleNameContext(ASSEMBLER); }
+ YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 163 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleNameContext(LINKER); }
+ YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 165 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleSubstitution(ARGS_SUBST); }
+ YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 166 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleSubstitution(BINDIR_SUBST); }
+ YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 167 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleSubstitution(DEFS_SUBST); }
+ YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 168 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleSubstitution(IN_SUBST); }
+ YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 169 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleSubstitution(INCLS_SUBST); }
+ YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 170 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleSubstitution(LIBDIR_SUBST); }
+ YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 171 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleSubstitution(LIBS_SUBST); }
+ YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 172 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleSubstitution(LLVMGCCDIR_SUBST); }
+ YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 173 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleSubstitution(LLVMGCCARCH_SUBST); }
+ YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 174 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleSubstitution(LLVMGCC_SUBST); }
+ YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 175 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleSubstitution(LLVMGXX_SUBST); }
+ YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 176 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleSubstitution(LLVMCC1_SUBST); }
+ YY_BREAK
+case 38:
+YY_RULE_SETUP
+#line 177 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleSubstitution(LLVMCC1PLUS_SUBST); }
+ YY_BREAK
+case 39:
+YY_RULE_SETUP
+#line 178 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleSubstitution(OPT_SUBST); }
+ YY_BREAK
+case 40:
+YY_RULE_SETUP
+#line 179 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleSubstitution(OUT_SUBST); }
+ YY_BREAK
+case 41:
+YY_RULE_SETUP
+#line 180 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleSubstitution(STATS_SUBST); }
+ YY_BREAK
+case 42:
+YY_RULE_SETUP
+#line 181 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleSubstitution(TARGET_SUBST); }
+ YY_BREAK
+case 43:
+YY_RULE_SETUP
+#line 182 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleSubstitution(TIME_SUBST); }
+ YY_BREAK
+case 44:
+YY_RULE_SETUP
+#line 183 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleSubstitution(VERBOSE_SUBST); }
+ YY_BREAK
+case 45:
+YY_RULE_SETUP
+#line 184 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleSubstitution(FOPTS_SUBST); }
+ YY_BREAK
+case 46:
+YY_RULE_SETUP
+#line 185 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleSubstitution(MOPTS_SUBST); }
+ YY_BREAK
+case 47:
+YY_RULE_SETUP
+#line 186 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleSubstitution(WOPTS_SUBST); }
+ YY_BREAK
+case 48:
+YY_RULE_SETUP
+#line 188 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleValueContext(ASSEMBLY); }
+ YY_BREAK
+case 49:
+YY_RULE_SETUP
+#line 189 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleValueContext(BITCODE); }
+ YY_BREAK
+case 50:
+YY_RULE_SETUP
+#line 190 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleValueContext(TRUETOK); }
+ YY_BREAK
+case 51:
+YY_RULE_SETUP
+#line 191 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ return handleValueContext(FALSETOK); }
+ YY_BREAK
+case 52:
+YY_RULE_SETUP
+#line 193 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ ConfigLexerState.StringVal = yytext; return OPTION; }
+ YY_BREAK
+case 53:
+YY_RULE_SETUP
+#line 194 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ ConfigLexerState.StringVal = yytext+1; // Nuke start quote
+ ConfigLexerState.StringVal.erase(
+ --ConfigLexerState.StringVal.end());
+ return STRING;
+ }
+ YY_BREAK
+case 54:
+YY_RULE_SETUP
+#line 199 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+{ YY_FATAL_ERROR("Invalid substitution token"); }
+ YY_BREAK
+case 55:
+YY_RULE_SETUP
+#line 201 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+ECHO;
+ YY_BREAK
+#line 1837 "ConfigLexer.cpp"
+case YY_STATE_EOF(INITIAL):
+ yyterminate();
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = yy_hold_char;
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * yylex(). If so, then we have to assure
+ * consistency between yy_current_buffer and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ yy_n_chars = yy_current_buffer->yy_n_chars;
+ yy_current_buffer->yy_input_file = yyin;
+ yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++yy_c_buf_p;
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = yy_last_accepting_cpos;
+ yy_current_state = yy_last_accepting_state;
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer() )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ yy_did_buffer_switch_on_eof = 0;
+
+ if ( yywrap() )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p =
+ yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ yy_c_buf_p =
+ &yy_current_buffer->yy_ch_buf[yy_n_chars];
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+ } /* end of yylex */
+
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+
+static int yy_get_next_buffer()
+ {
+ register char *dest = yy_current_buffer->yy_ch_buf;
+ register char *source = yytext_ptr;
+ register int number_to_move, i;
+ int ret_val;
+
+ if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( yy_current_buffer->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ yy_current_buffer->yy_n_chars = yy_n_chars = 0;
+
+ else
+ {
+ int num_to_read =
+ yy_current_buffer->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+#ifdef YY_USES_REJECT
+ YY_FATAL_ERROR(
+"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
+#else
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = yy_current_buffer;
+
+ int yy_c_buf_p_offset =
+ (int) (yy_c_buf_p - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ yy_flex_realloc( (void *) b->yy_ch_buf,
+ b->yy_buf_size + 2 );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = 0;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = yy_current_buffer->yy_buf_size -
+ number_to_move - 1;
+#endif
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
+ yy_n_chars, num_to_read );
+
+ yy_current_buffer->yy_n_chars = yy_n_chars;
+ }
+
+ if ( yy_n_chars == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart( yyin );
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ yy_current_buffer->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ yy_n_chars += number_to_move;
+ yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+ yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+ yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
+
+ return ret_val;
+ }
+
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+static yy_state_type yy_get_previous_state()
+ {
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+
+ yy_current_state = yy_start;
+
+ for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
+ {
+ register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if ( yy_accept[yy_current_state] )
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 408 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ }
+
+ return yy_current_state;
+ }
+
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+
+#ifdef YY_USE_PROTOS
+static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
+#else
+static yy_state_type yy_try_NUL_trans( yy_current_state )
+yy_state_type yy_current_state;
+#endif
+ {
+ register int yy_is_jam;
+ register char *yy_cp = yy_c_buf_p;
+
+ register YY_CHAR yy_c = 1;
+ if ( yy_accept[yy_current_state] )
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 408 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_is_jam = (yy_current_state == 407);
+
+ return yy_is_jam ? 0 : yy_current_state;
+ }
+
+
+#ifndef YY_NO_UNPUT
+#ifdef YY_USE_PROTOS
+static inline void yyunput( int c, register char *yy_bp )
+#else
+static inline void yyunput( c, yy_bp )
+int c;
+register char *yy_bp;
+#endif
+ {
+ register char *yy_cp = yy_c_buf_p;
+
+ /* undo effects of setting up yytext */
+ *yy_cp = yy_hold_char;
+
+ if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ register int number_to_move = yy_n_chars + 2;
+ register char *dest = &yy_current_buffer->yy_ch_buf[
+ yy_current_buffer->yy_buf_size + 2];
+ register char *source =
+ &yy_current_buffer->yy_ch_buf[number_to_move];
+
+ while ( source > yy_current_buffer->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ yy_current_buffer->yy_n_chars =
+ yy_n_chars = yy_current_buffer->yy_buf_size;
+
+ if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--yy_cp = (char) c;
+
+
+ yytext_ptr = yy_bp;
+ yy_hold_char = *yy_cp;
+ yy_c_buf_p = yy_cp;
+ }
+#endif /* ifndef YY_NO_UNPUT */
+
+
+#ifdef __cplusplus
+static int yyinput()
+#else
+static int input()
+#endif
+ {
+ int c;
+
+ *yy_c_buf_p = yy_hold_char;
+
+ if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+ /* This was really a NUL. */
+ *yy_c_buf_p = '\0';
+
+ else
+ { /* need more input */
+ int offset = yy_c_buf_p - yytext_ptr;
+ ++yy_c_buf_p;
+
+ switch ( yy_get_next_buffer() )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ yyrestart( yyin );
+
+ /* fall through */
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( yywrap() )
+ return EOF;
+
+ if ( ! yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p = yytext_ptr + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */
+ *yy_c_buf_p = '\0'; /* preserve yytext */
+ yy_hold_char = *++yy_c_buf_p;
+
+
+ return c;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yyrestart( FILE *input_file )
+#else
+void yyrestart( input_file )
+FILE *input_file;
+#endif
+ {
+ if ( ! yy_current_buffer )
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
+
+ yy_init_buffer( yy_current_buffer, input_file );
+ yy_load_buffer_state();
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+#else
+void yy_switch_to_buffer( new_buffer )
+YY_BUFFER_STATE new_buffer;
+#endif
+ {
+ if ( yy_current_buffer == new_buffer )
+ return;
+
+ if ( yy_current_buffer )
+ {
+ /* Flush out information for old buffer. */
+ *yy_c_buf_p = yy_hold_char;
+ yy_current_buffer->yy_buf_pos = yy_c_buf_p;
+ yy_current_buffer->yy_n_chars = yy_n_chars;
+ }
+
+ yy_current_buffer = new_buffer;
+ yy_load_buffer_state();
+
+ /* We don't actually know whether we did this switch during
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ yy_did_buffer_switch_on_eof = 1;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_load_buffer_state( void )
+#else
+void yy_load_buffer_state()
+#endif
+ {
+ yy_n_chars = yy_current_buffer->yy_n_chars;
+ yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
+ yyin = yy_current_buffer->yy_input_file;
+ yy_hold_char = *yy_c_buf_p;
+ }
+
+
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
+#else
+YY_BUFFER_STATE yy_create_buffer( file, size )
+FILE *file;
+int size;
+#endif
+ {
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer( b, file );
+
+ return b;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_delete_buffer( YY_BUFFER_STATE b )
+#else
+void yy_delete_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+ {
+ if ( ! b )
+ return;
+
+ if ( b == yy_current_buffer )
+ yy_current_buffer = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ yy_flex_free( (void *) b->yy_ch_buf );
+
+ yy_flex_free( (void *) b );
+ }
+
+
+#ifndef YY_ALWAYS_INTERACTIVE
+#ifndef YY_NEVER_INTERACTIVE
+extern int isatty YY_PROTO(( int ));
+#endif
+#endif
+
+#ifdef YY_USE_PROTOS
+void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
+#else
+void yy_init_buffer( b, file )
+YY_BUFFER_STATE b;
+FILE *file;
+#endif
+
+
+ {
+ yy_flush_buffer( b );
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+#if YY_ALWAYS_INTERACTIVE
+ b->yy_is_interactive = 1;
+#else
+#if YY_NEVER_INTERACTIVE
+ b->yy_is_interactive = 0;
+#else
+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+#endif
+#endif
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_flush_buffer( YY_BUFFER_STATE b )
+#else
+void yy_flush_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+
+ {
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == yy_current_buffer )
+ yy_load_buffer_state();
+ }
+
+
+#ifndef YY_NO_SCAN_BUFFER
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )
+#else
+YY_BUFFER_STATE yy_scan_buffer( base, size )
+char *base;
+yy_size_t size;
+#endif
+ {
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer( b );
+
+ return b;
+ }
+#endif
+
+
+#ifndef YY_NO_SCAN_STRING
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )
+#else
+YY_BUFFER_STATE yy_scan_string( yy_str )
+yyconst char *yy_str;
+#endif
+ {
+ int len;
+ for ( len = 0; yy_str[len]; ++len )
+ ;
+
+ return yy_scan_bytes( yy_str, len );
+ }
+#endif
+
+
+#ifndef YY_NO_SCAN_BYTES
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )
+#else
+YY_BUFFER_STATE yy_scan_bytes( bytes, len )
+yyconst char *bytes;
+int len;
+#endif
+ {
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = len + 2;
+ buf = (char *) yy_flex_alloc( n );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+ for ( i = 0; i < len; ++i )
+ buf[i] = bytes[i];
+
+ buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer( buf, n );
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+ }
+#endif
+
+
+#ifndef YY_NO_PUSH_STATE
+#ifdef YY_USE_PROTOS
+static void yy_push_state( int new_state )
+#else
+static void yy_push_state( new_state )
+int new_state;
+#endif
+ {
+ if ( yy_start_stack_ptr >= yy_start_stack_depth )
+ {
+ yy_size_t new_size;
+
+ yy_start_stack_depth += YY_START_STACK_INCR;
+ new_size = yy_start_stack_depth * sizeof( int );
+
+ if ( ! yy_start_stack )
+ yy_start_stack = (int *) yy_flex_alloc( new_size );
+
+ else
+ yy_start_stack = (int *) yy_flex_realloc(
+ (void *) yy_start_stack, new_size );
+
+ if ( ! yy_start_stack )
+ YY_FATAL_ERROR(
+ "out of memory expanding start-condition stack" );
+ }
+
+ yy_start_stack[yy_start_stack_ptr++] = YY_START;
+
+ BEGIN(new_state);
+ }
+#endif
+
+
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state()
+ {
+ if ( --yy_start_stack_ptr < 0 )
+ YY_FATAL_ERROR( "start-condition stack underflow" );
+
+ BEGIN(yy_start_stack[yy_start_stack_ptr]);
+ }
+#endif
+
+
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state()
+ {
+ return yy_start_stack[yy_start_stack_ptr - 1];
+ }
+#endif
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+#ifdef YY_USE_PROTOS
+static void yy_fatal_error( yyconst char msg[] )
+#else
+static void yy_fatal_error( msg )
+char msg[];
+#endif
+ {
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+ }
+
+
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ yytext[yyleng] = yy_hold_char; \
+ yy_c_buf_p = yytext + n; \
+ yy_hold_char = *yy_c_buf_p; \
+ *yy_c_buf_p = '\0'; \
+ yyleng = n; \
+ } \
+ while ( 0 )
+
+
+/* Internal utility routines. */
+
+#ifndef yytext_ptr
+#ifdef YY_USE_PROTOS
+static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )
+#else
+static void yy_flex_strncpy( s1, s2, n )
+char *s1;
+yyconst char *s2;
+int n;
+#endif
+ {
+ register int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+ }
+#endif
+
+#ifdef YY_NEED_STRLEN
+#ifdef YY_USE_PROTOS
+static int yy_flex_strlen( yyconst char *s )
+#else
+static int yy_flex_strlen( s )
+yyconst char *s;
+#endif
+ {
+ register int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+ }
+#endif
+
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_alloc( yy_size_t size )
+#else
+static void *yy_flex_alloc( size )
+yy_size_t size;
+#endif
+ {
+ return (void *) malloc( size );
+ }
+
+#ifdef YY_USE_PROTOS
+static inline void *yy_flex_realloc( void *ptr, yy_size_t size )
+#else
+static inline void *yy_flex_realloc( ptr, size )
+void *ptr;
+yy_size_t size;
+#endif
+ {
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+ }
+
+#ifdef YY_USE_PROTOS
+static void yy_flex_free( void *ptr )
+#else
+static void yy_flex_free( ptr )
+void *ptr;
+#endif
+ {
+ free( ptr );
+ }
+
+#if YY_MAIN
+int main()
+ {
+ yylex();
+ return 0;
+ }
+#endif
+#line 201 "/Volumes/ProjectsDisk/cvs/llvm/tools/llvmc/ConfigLexer.l"
+
diff --git a/tools/llvmc/ConfigLexer.h b/tools/llvmc/ConfigLexer.h
new file mode 100644
index 0000000..9693b34
--- /dev/null
+++ b/tools/llvmc/ConfigLexer.h
@@ -0,0 +1,113 @@
+//===- ConfigLexer.h - ConfigLexer Declarations -----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and 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
diff --git a/tools/llvmc/ConfigLexer.l b/tools/llvmc/ConfigLexer.l
new file mode 100644
index 0000000..6bd61c8
--- /dev/null
+++ b/tools/llvmc/ConfigLexer.l
@@ -0,0 +1,201 @@
+/*===- ConfigLexer.l - Scanner for CompilerDriver Config Files -*- C++ -*--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and 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"); }
+
+%%
diff --git a/tools/llvmc/ConfigLexer.l.cvs b/tools/llvmc/ConfigLexer.l.cvs
new file mode 100644
index 0000000..6bd61c8
--- /dev/null
+++ b/tools/llvmc/ConfigLexer.l.cvs
@@ -0,0 +1,201 @@
+/*===- ConfigLexer.l - Scanner for CompilerDriver Config Files -*- C++ -*--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and 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"); }
+
+%%
diff --git a/tools/llvmc/Configuration.cpp b/tools/llvmc/Configuration.cpp
new file mode 100644
index 0000000..aafca79
--- /dev/null
+++ b/tools/llvmc/Configuration.cpp
@@ -0,0 +1,633 @@
+//===- Configuration.cpp - Configuration Data Mgmt --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and 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;
+ }
+ Configurations.clear();
+}
+
+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.insert(std::make_pair(filetype,result));
+ }
+ return result; // Might return 0
+}
diff --git a/tools/llvmc/Configuration.h b/tools/llvmc/Configuration.h
new file mode 100644
index 0000000..bf38275
--- /dev/null
+++ b/tools/llvmc/Configuration.h
@@ -0,0 +1,62 @@
+//===- Configuration.h - Configuration Data Mgmt ----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and 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 "CompilerDriver.h"
+#include <llvm/ADT/hash_map>
+
+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 hash_map<std::string,CompilerDriver::ConfigData*> ConfigDataMap;
+ ConfigDataMap Configurations; ///< The cache of configurations
+ sys::Path configDir;
+ /// @}
+ };
+}
+
+#endif
diff --git a/tools/llvmc/LICENSE.TXT b/tools/llvmc/LICENSE.TXT
new file mode 100644
index 0000000..27869ad
--- /dev/null
+++ b/tools/llvmc/LICENSE.TXT
@@ -0,0 +1,6 @@
+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.
diff --git a/tools/llvmc/Makefile b/tools/llvmc/Makefile
new file mode 100644
index 0000000..fbbc7e8
--- /dev/null
+++ b/tools/llvmc/Makefile
@@ -0,0 +1,34 @@
+##===- tools/llvmc/Makefile --------------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file was developed by the LLVM research group and 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
diff --git a/tools/llvmc/c b/tools/llvmc/c
new file mode 100644
index 0000000..1f7d48e
--- /dev/null
+++ b/tools/llvmc/c
@@ -0,0 +1,60 @@
+# 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%
diff --git a/tools/llvmc/cpp b/tools/llvmc/cpp
new file mode 100644
index 0000000..5f20fd8
--- /dev/null
+++ b/tools/llvmc/cpp
@@ -0,0 +1,61 @@
+# 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%
diff --git a/tools/llvmc/ll b/tools/llvmc/ll
new file mode 100644
index 0000000..8150204
--- /dev/null
+++ b/tools/llvmc/ll
@@ -0,0 +1,11 @@
+# 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%
diff --git a/tools/llvmc/llvmc.cpp b/tools/llvmc/llvmc.cpp
new file mode 100644
index 0000000..c257a3e
--- /dev/null
+++ b/tools/llvmc/llvmc.cpp
@@ -0,0 +1,370 @@
+//===--- llvmc.cpp - The LLVM Compiler Driver -------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and 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>
+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();
+
+ 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;
+}
diff --git a/tools/llvmc/st b/tools/llvmc/st
new file mode 100644
index 0000000..87b4769
--- /dev/null
+++ b/tools/llvmc/st
@@ -0,0 +1,63 @@
+# 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%
diff --git a/tools/lto/Makefile b/tools/lto/Makefile
new file mode 100644
index 0000000..1b349f7
--- /dev/null
+++ b/tools/lto/Makefile
@@ -0,0 +1,30 @@
+##===- tools/lto/Makefile ----------------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file was developed by Devang Patel and is distributed under
+# the University of Illinois Open Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../..
+LIBRARYNAME = LLVMlto
+
+# Include this here so we can get the configuration of the targets
+# that have been configured for construction. We have to do this
+# early so we can set up LINK_COMPONENTS before includeing Makefile.rules
+include $(LEVEL)/Makefile.config
+
+LINK_LIBS_IN_SHARED = 1
+ifeq ($(OS),Darwin)
+ SHARED_LIBRARY = 1
+ LOADABLE_MODULE = 1
+ DONT_BUILD_RELINKED = 1
+else
+ BUILD_ARCHIVE = 1
+endif
+
+LINK_COMPONENTS := $(TARGETS_TO_BUILD) ipo scalaropts linker bitreader bitwriter
+
+include $(LEVEL)/Makefile.common
+
diff --git a/tools/lto/lto-c.cpp b/tools/lto/lto-c.cpp
new file mode 100644
index 0000000..ae939a9
--- /dev/null
+++ b/tools/lto/lto-c.cpp
@@ -0,0 +1,66 @@
+//===- lto-c.cpp - LLVM Link Time Optimizer C Wrappers --------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chandler Carruth and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a C wrapper API for the Link Time Optimization
+// library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm-c/LinkTimeOptimizer.h"
+#include "llvm/LinkTimeOptimizer.h"
+using namespace llvm;
+
+
+/// Create an instance of the LLVM LTO object for performing the link
+/// time optimizations.
+extern "C"
+llvm_lto_t llvm_create_optimizer() {
+ return new llvm::LTO();
+}
+
+/// Destroy an instance of the LLVM LTO object
+extern "C"
+void llvm_destroy_optimizer(llvm_lto_t lto) {
+ delete (llvm::LTO*)lto;
+}
+
+/// Read an LLVM bitcode file using LTO::readLLVMObjectFile.
+extern "C"
+llvm_lto_status
+llvm_read_object_file(llvm_lto_t lto, const char *input_filename) {
+ llvm::LTO *l = (llvm::LTO*)lto;
+
+ if (input_filename == NULL)
+ return LLVM_LTO_READ_FAILURE;
+
+ std::string InputFilename(input_filename);
+ llvm::LTO::NameToSymbolMap symbols;
+ std::set<std::string> references;
+ return (llvm_lto_status)((int)(l->readLLVMObjectFile(InputFilename, symbols,
+ references)));
+}
+
+
+/// Optimize and output object code using LTO::optimizeModules.
+extern "C"
+llvm_lto_status
+llvm_optimize_modules(llvm_lto_t lto, const char *output_filename) {
+ llvm::LTO *l = (llvm::LTO*)lto;
+
+ std::string OutputFilename(output_filename);
+ std::vector<const char *> exportList;
+ std::string targetTriple;
+
+ return (llvm_lto_status)((int)(
+ l->optimizeModules(OutputFilename, exportList,
+ targetTriple, false, "")));
+}
+
+
+
diff --git a/tools/lto/lto.cpp b/tools/lto/lto.cpp
new file mode 100644
index 0000000..cef26f1
--- /dev/null
+++ b/tools/lto/lto.cpp
@@ -0,0 +1,496 @@
+//===-lto.cpp - LLVM Link Time Optimizer ----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Devang Patel and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Link Time Optimization library. This library is
+// intended to be used by linker to optimize code at link time.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Module.h"
+#include "llvm/PassManager.h"
+#include "llvm/Linker.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/ModuleProvider.h"
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FileUtilities.h"
+#include "llvm/Support/SystemUtils.h"
+#include "llvm/Support/Mangler.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/System/Program.h"
+#include "llvm/System/Signals.h"
+#include "llvm/Analysis/Passes.h"
+#include "llvm/Analysis/LoopPass.h"
+#include "llvm/Analysis/Verifier.h"
+#include "llvm/CodeGen/FileWriters.h"
+#include "llvm/Target/SubtargetFeature.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetMachineRegistry.h"
+#include "llvm/Target/TargetAsmInfo.h"
+#include "llvm/Transforms/IPO.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Analysis/LoadValueNumbering.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/LinkTimeOptimizer.h"
+#include <fstream>
+#include <ostream>
+using namespace llvm;
+
+extern "C"
+llvm::LinkTimeOptimizer *createLLVMOptimizer()
+{
+ llvm::LTO *l = new llvm::LTO();
+ return l;
+}
+
+/// If symbol is not used then make it internal and let optimizer takes
+/// care of it.
+void LLVMSymbol::mayBeNotUsed() {
+ gv->setLinkage(GlobalValue::InternalLinkage);
+}
+
+// Map LLVM LinkageType to LTO LinakgeType
+static LTOLinkageTypes
+getLTOLinkageType(GlobalValue *v)
+{
+ LTOLinkageTypes lt;
+ if (v->hasExternalLinkage())
+ lt = LTOExternalLinkage;
+ else if (v->hasLinkOnceLinkage())
+ lt = LTOLinkOnceLinkage;
+ else if (v->hasWeakLinkage())
+ lt = LTOWeakLinkage;
+ else
+ // Otherwise it is internal linkage for link time optimizer
+ lt = LTOInternalLinkage;
+ return lt;
+}
+
+// Find exeternal symbols referenced by VALUE. This is a recursive function.
+static void
+findExternalRefs(Value *value, std::set<std::string> &references,
+ Mangler &mangler) {
+
+ if (GlobalValue *gv = dyn_cast<GlobalValue>(value)) {
+ LTOLinkageTypes lt = getLTOLinkageType(gv);
+ if (lt != LTOInternalLinkage && strncmp (gv->getName().c_str(), "llvm.", 5))
+ references.insert(mangler.getValueName(gv));
+ }
+
+ // GlobalValue, even with InternalLinkage type, may have operands with
+ // ExternalLinkage type. Do not ignore these operands.
+ if (Constant *c = dyn_cast<Constant>(value))
+ // Handle ConstantExpr, ConstantStruct, ConstantArry etc..
+ for (unsigned i = 0, e = c->getNumOperands(); i != e; ++i)
+ findExternalRefs(c->getOperand(i), references, mangler);
+}
+
+/// If Module with InputFilename is available then remove it from allModules
+/// and call delete on it.
+void
+LTO::removeModule (const std::string &InputFilename)
+{
+ NameToModuleMap::iterator pos = allModules.find(InputFilename.c_str());
+ if (pos == allModules.end())
+ return;
+
+ Module *m = pos->second;
+ allModules.erase(pos);
+ delete m;
+}
+
+/// InputFilename is a LLVM bitcode file. If Module with InputFilename is
+/// available then return it. Otherwise parseInputFilename.
+Module *
+LTO::getModule(const std::string &InputFilename)
+{
+ Module *m = NULL;
+
+ NameToModuleMap::iterator pos = allModules.find(InputFilename.c_str());
+ if (pos != allModules.end())
+ m = allModules[InputFilename.c_str()];
+ else {
+ if (MemoryBuffer *Buffer
+ = MemoryBuffer::getFile(&InputFilename[0], InputFilename.size())) {
+ m = ParseBitcodeFile(Buffer);
+ delete Buffer;
+ }
+ allModules[InputFilename.c_str()] = m;
+ }
+ return m;
+}
+
+/// InputFilename is a LLVM bitcode file. Reade this bitcode file and
+/// set corresponding target triplet string.
+void
+LTO::getTargetTriple(const std::string &InputFilename,
+ std::string &targetTriple)
+{
+ Module *m = getModule(InputFilename);
+ if (m)
+ targetTriple = m->getTargetTriple();
+}
+
+/// InputFilename is a LLVM bitcode file. Read it using bitcode reader.
+/// Collect global functions and symbol names in symbols vector.
+/// Collect external references in references vector.
+/// Return LTO_READ_SUCCESS if there is no error.
+enum LTOStatus
+LTO::readLLVMObjectFile(const std::string &InputFilename,
+ NameToSymbolMap &symbols,
+ std::set<std::string> &references)
+{
+ Module *m = getModule(InputFilename);
+ if (!m)
+ return LTO_READ_FAILURE;
+
+ // Collect Target info
+ getTarget(m);
+
+ if (!Target)
+ return LTO_READ_FAILURE;
+
+ // Use mangler to add GlobalPrefix to names to match linker names.
+ // FIXME : Instead of hard coding "-" use GlobalPrefix.
+ Mangler mangler(*m, Target->getTargetAsmInfo()->getGlobalPrefix());
+ modules.push_back(m);
+
+ for (Module::iterator f = m->begin(), e = m->end(); f != e; ++f) {
+
+ LTOLinkageTypes lt = getLTOLinkageType(f);
+
+ if (!f->isDeclaration() && lt != LTOInternalLinkage
+ && strncmp (f->getName().c_str(), "llvm.", 5)) {
+ int alignment = ( 16 > f->getAlignment() ? 16 : f->getAlignment());
+ LLVMSymbol *newSymbol = new LLVMSymbol(lt, f, f->getName(),
+ mangler.getValueName(f),
+ Log2_32(alignment));
+ symbols[newSymbol->getMangledName()] = newSymbol;
+ allSymbols[newSymbol->getMangledName()] = newSymbol;
+ }
+
+ // Collect external symbols referenced by this function.
+ for (Function::iterator b = f->begin(), fe = f->end(); b != fe; ++b)
+ for (BasicBlock::iterator i = b->begin(), be = b->end();
+ i != be; ++i)
+ for (unsigned count = 0, total = i->getNumOperands();
+ count != total; ++count)
+ findExternalRefs(i->getOperand(count), references, mangler);
+ }
+
+ for (Module::global_iterator v = m->global_begin(), e = m->global_end();
+ v != e; ++v) {
+ LTOLinkageTypes lt = getLTOLinkageType(v);
+ if (!v->isDeclaration() && lt != LTOInternalLinkage
+ && strncmp (v->getName().c_str(), "llvm.", 5)) {
+ const TargetData *TD = Target->getTargetData();
+ LLVMSymbol *newSymbol = new LLVMSymbol(lt, v, v->getName(),
+ mangler.getValueName(v),
+ TD->getPreferredAlignmentLog(v));
+ symbols[newSymbol->getMangledName()] = newSymbol;
+ allSymbols[newSymbol->getMangledName()] = newSymbol;
+
+ for (unsigned count = 0, total = v->getNumOperands();
+ count != total; ++count)
+ findExternalRefs(v->getOperand(count), references, mangler);
+
+ }
+ }
+
+ return LTO_READ_SUCCESS;
+}
+
+/// Get TargetMachine.
+/// Use module M to find appropriate Target.
+void
+LTO::getTarget (Module *M) {
+
+ if (Target)
+ return;
+
+ std::string Err;
+ const TargetMachineRegistry::Entry* March =
+ TargetMachineRegistry::getClosestStaticTargetForModule(*M, Err);
+
+ if (March == 0)
+ return;
+
+ // Create target
+ std::string Features;
+ Target = March->CtorFn(*M, Features);
+}
+
+/// Optimize module M using various IPO passes. Use exportList to
+/// internalize selected symbols. Target platform is selected
+/// based on information available to module M. No new target
+/// features are selected.
+enum LTOStatus
+LTO::optimize(Module *M, std::ostream &Out,
+ std::vector<const char *> &exportList)
+{
+ // Instantiate the pass manager to organize the passes.
+ PassManager Passes;
+
+ // Collect Target info
+ getTarget(M);
+
+ if (!Target)
+ return LTO_NO_TARGET;
+
+ // Start off with a verification pass.
+ Passes.add(createVerifierPass());
+
+ // Add an appropriate TargetData instance for this module...
+ Passes.add(new TargetData(*Target->getTargetData()));
+
+ // Internalize symbols if export list is nonemty
+ if (!exportList.empty())
+ Passes.add(createInternalizePass(exportList));
+
+ // Now that we internalized some globals, see if we can hack on them!
+ Passes.add(createGlobalOptimizerPass());
+
+ // Linking modules together can lead to duplicated global constants, only
+ // keep one copy of each constant...
+ Passes.add(createConstantMergePass());
+
+ // If the -s command line option was specified, strip the symbols out of the
+ // resulting program to make it smaller. -s is a GLD option that we are
+ // supporting.
+ Passes.add(createStripSymbolsPass());
+
+ // Propagate constants at call sites into the functions they call.
+ Passes.add(createIPConstantPropagationPass());
+
+ // Remove unused arguments from functions...
+ Passes.add(createDeadArgEliminationPass());
+
+ Passes.add(createFunctionInliningPass()); // Inline small functions
+
+ Passes.add(createPruneEHPass()); // Remove dead EH info
+
+ Passes.add(createGlobalDCEPass()); // Remove dead functions
+
+ // If we didn't decide to inline a function, check to see if we can
+ // transform it to pass arguments by value instead of by reference.
+ Passes.add(createArgumentPromotionPass());
+
+ // The IPO passes may leave cruft around. Clean up after them.
+ Passes.add(createInstructionCombiningPass());
+
+ Passes.add(createScalarReplAggregatesPass()); // Break up allocas
+
+ // Run a few AA driven optimizations here and now, to cleanup the code.
+ Passes.add(createGlobalsModRefPass()); // IP alias analysis
+
+ Passes.add(createLICMPass()); // Hoist loop invariants
+ Passes.add(createLoadValueNumberingPass()); // GVN for load instrs
+ Passes.add(createGCSEPass()); // Remove common subexprs
+ Passes.add(createDeadStoreEliminationPass()); // Nuke dead stores
+
+ // Cleanup and simplify the code after the scalar optimizations.
+ Passes.add(createInstructionCombiningPass());
+
+ // Delete basic blocks, which optimization passes may have killed...
+ Passes.add(createCFGSimplificationPass());
+
+ // Now that we have optimized the program, discard unreachable functions...
+ Passes.add(createGlobalDCEPass());
+
+ // Make sure everything is still good.
+ Passes.add(createVerifierPass());
+
+ FunctionPassManager *CodeGenPasses =
+ new FunctionPassManager(new ExistingModuleProvider(M));
+
+ CodeGenPasses->add(new TargetData(*Target->getTargetData()));
+
+ MachineCodeEmitter *MCE = 0;
+
+ switch (Target->addPassesToEmitFile(*CodeGenPasses, Out,
+ TargetMachine::AssemblyFile, true)) {
+ default:
+ case FileModel::Error:
+ return LTO_WRITE_FAILURE;
+ case FileModel::AsmFile:
+ break;
+ case FileModel::MachOFile:
+ MCE = AddMachOWriter(*CodeGenPasses, Out, *Target);
+ break;
+ case FileModel::ElfFile:
+ MCE = AddELFWriter(*CodeGenPasses, Out, *Target);
+ break;
+ }
+
+ if (Target->addPassesToEmitFileFinish(*CodeGenPasses, MCE, true))
+ return LTO_WRITE_FAILURE;
+
+ // Run our queue of passes all at once now, efficiently.
+ Passes.run(*M);
+
+ // Run the code generator, if present.
+ CodeGenPasses->doInitialization();
+ for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) {
+ if (!I->isDeclaration())
+ CodeGenPasses->run(*I);
+ }
+ CodeGenPasses->doFinalization();
+
+ return LTO_OPT_SUCCESS;
+}
+
+///Link all modules together and optimize them using IPO. Generate
+/// native object file using OutputFilename
+/// Return appropriate LTOStatus.
+enum LTOStatus
+LTO::optimizeModules(const std::string &OutputFilename,
+ std::vector<const char *> &exportList,
+ std::string &targetTriple,
+ bool saveTemps,
+ const char *FinalOutputFilename)
+{
+ if (modules.empty())
+ return LTO_NO_WORK;
+
+ std::ios::openmode io_mode =
+ std::ios::out | std::ios::trunc | std::ios::binary;
+ std::string *errMsg = NULL;
+ Module *bigOne = modules[0];
+ Linker theLinker("LinkTimeOptimizer", bigOne, false);
+ for (unsigned i = 1, e = modules.size(); i != e; ++i)
+ if (theLinker.LinkModules(bigOne, modules[i], errMsg))
+ return LTO_MODULE_MERGE_FAILURE;
+ // all modules have been handed off to the linker.
+ modules.clear();
+
+ sys::Path FinalOutputPath(FinalOutputFilename);
+ FinalOutputPath.eraseSuffix();
+
+ if (saveTemps) {
+ std::string tempFileName(FinalOutputPath.c_str());
+ tempFileName += "0.bc";
+ std::ofstream Out(tempFileName.c_str(), io_mode);
+ WriteBitcodeToFile(bigOne, Out);
+ }
+
+ // Strip leading underscore because it was added to match names
+ // seen by linker.
+ for (unsigned i = 0, e = exportList.size(); i != e; ++i) {
+ const char *name = exportList[i];
+ NameToSymbolMap::iterator itr = allSymbols.find(name);
+ if (itr != allSymbols.end())
+ exportList[i] = allSymbols[name]->getName();
+ }
+
+
+ std::string ErrMsg;
+ sys::Path TempDir = sys::Path::GetTemporaryDirectory(&ErrMsg);
+ if (TempDir.isEmpty()) {
+ cerr << "lto: " << ErrMsg << "\n";
+ return LTO_WRITE_FAILURE;
+ }
+ sys::Path tmpAsmFilePath(TempDir);
+ if (!tmpAsmFilePath.appendComponent("lto")) {
+ cerr << "lto: " << ErrMsg << "\n";
+ TempDir.eraseFromDisk(true);
+ return LTO_WRITE_FAILURE;
+ }
+ if (tmpAsmFilePath.createTemporaryFileOnDisk(true, &ErrMsg)) {
+ cerr << "lto: " << ErrMsg << "\n";
+ TempDir.eraseFromDisk(true);
+ return LTO_WRITE_FAILURE;
+ }
+ sys::RemoveFileOnSignal(tmpAsmFilePath);
+
+ std::ofstream asmFile(tmpAsmFilePath.c_str(), io_mode);
+ if (!asmFile.is_open() || asmFile.bad()) {
+ if (tmpAsmFilePath.exists()) {
+ tmpAsmFilePath.eraseFromDisk();
+ TempDir.eraseFromDisk(true);
+ }
+ return LTO_WRITE_FAILURE;
+ }
+
+ enum LTOStatus status = optimize(bigOne, asmFile, exportList);
+ asmFile.close();
+ if (status != LTO_OPT_SUCCESS) {
+ tmpAsmFilePath.eraseFromDisk();
+ TempDir.eraseFromDisk(true);
+ return status;
+ }
+
+ if (saveTemps) {
+ std::string tempFileName(FinalOutputPath.c_str());
+ tempFileName += "1.bc";
+ std::ofstream Out(tempFileName.c_str(), io_mode);
+ WriteBitcodeToFile(bigOne, Out);
+ }
+
+ targetTriple = bigOne->getTargetTriple();
+
+ // Run GCC to assemble and link the program into native code.
+ //
+ // Note:
+ // We can't just assemble and link the file with the system assembler
+ // and linker because we don't know where to put the _start symbol.
+ // GCC mysteriously knows how to do it.
+ const sys::Path gcc = sys::Program::FindProgramByName("gcc");
+ if (gcc.isEmpty()) {
+ tmpAsmFilePath.eraseFromDisk();
+ TempDir.eraseFromDisk(true);
+ return LTO_ASM_FAILURE;
+ }
+
+ std::vector<const char*> args;
+ args.push_back(gcc.c_str());
+ args.push_back("-c");
+ args.push_back("-x");
+ args.push_back("assembler");
+ args.push_back("-o");
+ args.push_back(OutputFilename.c_str());
+ args.push_back(tmpAsmFilePath.c_str());
+ args.push_back(0);
+
+ if (sys::Program::ExecuteAndWait(gcc, &args[0], 0, 0, 1, 0, &ErrMsg)) {
+ cerr << "lto: " << ErrMsg << "\n";
+ return LTO_ASM_FAILURE;
+ }
+
+ tmpAsmFilePath.eraseFromDisk();
+ TempDir.eraseFromDisk(true);
+
+ return LTO_OPT_SUCCESS;
+}
+
+void LTO::printVersion() {
+ cl::PrintVersionMessage();
+}
+
+/// Unused pure-virtual destructor. Must remain empty.
+LinkTimeOptimizer::~LinkTimeOptimizer() {}
+
+/// Destruct LTO. Delete all modules, symbols and target.
+LTO::~LTO() {
+
+ for (std::vector<Module *>::iterator itr = modules.begin(), e = modules.end();
+ itr != e; ++itr)
+ delete *itr;
+
+ modules.clear();
+
+ for (NameToSymbolMap::iterator itr = allSymbols.begin(), e = allSymbols.end();
+ itr != e; ++itr)
+ delete itr->second;
+
+ allSymbols.clear();
+
+ delete Target;
+}
diff --git a/tools/opt/AnalysisWrappers.cpp b/tools/opt/AnalysisWrappers.cpp
new file mode 100644
index 0000000..ce2c34d
--- /dev/null
+++ b/tools/opt/AnalysisWrappers.cpp
@@ -0,0 +1,88 @@
+//===- AnalysisWrappers.cpp - Wrappers around non-pass analyses -----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines pass wrappers around LLVM analyses that don't make sense to
+// be passes. It provides a nice standard pass interface to these classes so
+// that they can be printed out by analyze.
+//
+// These classes are separated out of analyze.cpp so that it is more clear which
+// code is the integral part of the analyze tool, and which part of the code is
+// just making it so more passes are available.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/CallSite.h"
+#include "llvm/Analysis/CallGraph.h"
+#include <iostream>
+using namespace llvm;
+
+namespace {
+ /// ExternalFunctionsPassedConstants - This pass prints out call sites to
+ /// external functions that are called with constant arguments. This can be
+ /// useful when looking for standard library functions we should constant fold
+ /// or handle in alias analyses.
+ struct ExternalFunctionsPassedConstants : public ModulePass {
+ static char ID; // Pass ID, replacement for typeid
+ ExternalFunctionsPassedConstants() : ModulePass((intptr_t)&ID) {}
+ virtual bool runOnModule(Module &M) {
+ for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
+ if (I->isDeclaration()) {
+ bool PrintedFn = false;
+ for (Value::use_iterator UI = I->use_begin(), E = I->use_end();
+ UI != E; ++UI)
+ if (Instruction *User = dyn_cast<Instruction>(*UI)) {
+ CallSite CS = CallSite::get(User);
+ if (CS.getInstruction()) {
+ for (CallSite::arg_iterator AI = CS.arg_begin(),
+ E = CS.arg_end(); AI != E; ++AI)
+ if (isa<Constant>(*AI)) {
+ if (!PrintedFn) {
+ std::cerr << "Function '" << I->getName() << "':\n";
+ PrintedFn = true;
+ }
+ std::cerr << *User;
+ break;
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ }
+ };
+
+ char ExternalFunctionsPassedConstants::ID = 0;
+ RegisterPass<ExternalFunctionsPassedConstants>
+ P1("externalfnconstants", "Print external fn callsites passed constants");
+
+ struct CallGraphPrinter : public ModulePass {
+ static char ID; // Pass ID, replacement for typeid
+ CallGraphPrinter() : ModulePass((intptr_t)&ID) {}
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ AU.addRequiredTransitive<CallGraph>();
+ }
+ virtual bool runOnModule(Module &M) { return false; }
+
+ virtual void print(std::ostream &OS, const Module *M) const {
+ getAnalysis<CallGraph>().print(OS, M);
+ }
+ };
+
+ char CallGraphPrinter::ID = 0;
+ RegisterPass<CallGraphPrinter>
+ P2("callgraph", "Print a call graph");
+}
diff --git a/tools/opt/GraphPrinters.cpp b/tools/opt/GraphPrinters.cpp
new file mode 100644
index 0000000..5bf9088
--- /dev/null
+++ b/tools/opt/GraphPrinters.cpp
@@ -0,0 +1,83 @@
+//===- GraphPrinters.cpp - DOT printers for various graph types -----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines several printers for various different types of graphs used
+// by the LLVM infrastructure. It uses the generic graph interface to convert
+// the graph into a .dot graph. These graphs can then be processed with the
+// "dot" tool to convert them to postscript or some other suitable format.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/GraphWriter.h"
+#include "llvm/Pass.h"
+#include "llvm/Value.h"
+#include "llvm/Analysis/CallGraph.h"
+#include <iostream>
+#include <fstream>
+using namespace llvm;
+
+template<typename GraphType>
+static void WriteGraphToFile(std::ostream &O, const std::string &GraphName,
+ const GraphType &GT) {
+ std::string Filename = GraphName + ".dot";
+ O << "Writing '" << Filename << "'...";
+ std::ofstream F(Filename.c_str());
+
+ if (F.good())
+ WriteGraph(F, GT);
+ else
+ O << " error opening file for writing!";
+ O << "\n";
+}
+
+
+//===----------------------------------------------------------------------===//
+// Call Graph Printer
+//===----------------------------------------------------------------------===//
+
+namespace llvm {
+ template<>
+ struct DOTGraphTraits<CallGraph*> : public DefaultDOTGraphTraits {
+ static std::string getGraphName(CallGraph *F) {
+ return "Call Graph";
+ }
+
+ static std::string getNodeLabel(CallGraphNode *Node, CallGraph *Graph) {
+ if (Node->getFunction())
+ return ((Value*)Node->getFunction())->getName();
+ else
+ return "Indirect call node";
+ }
+ };
+}
+
+
+namespace {
+ struct CallGraphPrinter : public ModulePass {
+ static char ID; // Pass ID, replacement for typeid
+ CallGraphPrinter() : ModulePass((intptr_t)&ID) {}
+
+ virtual bool runOnModule(Module &M) {
+ WriteGraphToFile(std::cerr, "callgraph", &getAnalysis<CallGraph>());
+ return false;
+ }
+
+ void print(std::ostream &OS) const {}
+ void print(std::ostream &OS, const llvm::Module*) const {}
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<CallGraph>();
+ AU.setPreservesAll();
+ }
+ };
+
+ char CallGraphPrinter::ID = 0;
+ RegisterPass<CallGraphPrinter> P2("print-callgraph",
+ "Print Call Graph to 'dot' file");
+}
diff --git a/tools/opt/Makefile b/tools/opt/Makefile
new file mode 100644
index 0000000..f444fe3
--- /dev/null
+++ b/tools/opt/Makefile
@@ -0,0 +1,15 @@
+##===- tools/opt/Makefile ------------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file was developed by the LLVM research group and is distributed under
+# the University of Illinois Open Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+LEVEL = ../..
+TOOLNAME = opt
+REQUIRES_EH := 1
+
+LINK_COMPONENTS := bitreader bitwriter instrumentation scalaropts ipo
+
+include $(LEVEL)/Makefile.common
diff --git a/tools/opt/PrintSCC.cpp b/tools/opt/PrintSCC.cpp
new file mode 100644
index 0000000..c2e4f5b
--- /dev/null
+++ b/tools/opt/PrintSCC.cpp
@@ -0,0 +1,112 @@
+//===- PrintSCC.cpp - Enumerate SCCs in some key graphs -------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides passes to print out SCCs in a CFG or a CallGraph.
+// Normally, you would not use these passes; instead, you would use the
+// scc_iterator directly to enumerate SCCs and process them in some way. These
+// passes serve three purposes:
+//
+// (1) As a reference for how to use the scc_iterator.
+// (2) To print out the SCCs for a CFG or a CallGraph:
+// analyze -cfgscc to print the SCCs in each CFG of a module.
+// analyze -cfgscc -stats to print the #SCCs and the maximum SCC size.
+// analyze -cfgscc -debug > /dev/null to watch the algorithm in action.
+//
+// and similarly:
+// analyze -callscc [-stats] [-debug] to print SCCs in the CallGraph
+//
+// (3) To test the scc_iterator.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Pass.h"
+#include "llvm/Module.h"
+#include "llvm/Analysis/CallGraph.h"
+#include "llvm/Support/CFG.h"
+#include "llvm/ADT/SCCIterator.h"
+#include <iostream>
+using namespace llvm;
+
+namespace {
+ struct CFGSCC : public FunctionPass {
+ static char ID; // Pass identification, replacement for typeid
+ CFGSCC() : FunctionPass((intptr_t)&ID) {}
+ bool runOnFunction(Function& func);
+
+ void print(std::ostream &O, const Module* = 0) const { }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ }
+ };
+
+ struct CallGraphSCC : public ModulePass {
+ static char ID; // Pass identification, replacement for typeid
+ CallGraphSCC() : ModulePass((intptr_t)&ID) {}
+
+ // run - Print out SCCs in the call graph for the specified module.
+ bool runOnModule(Module &M);
+
+ void print(std::ostream &O, const Module* = 0) const { }
+
+ // getAnalysisUsage - This pass requires the CallGraph.
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ AU.addRequired<CallGraph>();
+ }
+ };
+
+ char CFGSCC::ID = 0;
+ RegisterPass<CFGSCC>
+ Y("cfgscc", "Print SCCs of each function CFG");
+
+ char CallGraphSCC::ID = 0;
+ RegisterPass<CallGraphSCC>
+ Z("callscc", "Print SCCs of the Call Graph");
+}
+
+bool CFGSCC::runOnFunction(Function &F) {
+ unsigned sccNum = 0;
+ std::cout << "SCCs for Function " << F.getName() << " in PostOrder:";
+ for (scc_iterator<Function*> SCCI = scc_begin(&F),
+ E = scc_end(&F); SCCI != E; ++SCCI) {
+ std::vector<BasicBlock*> &nextSCC = *SCCI;
+ std::cout << "\nSCC #" << ++sccNum << " : ";
+ for (std::vector<BasicBlock*>::const_iterator I = nextSCC.begin(),
+ E = nextSCC.end(); I != E; ++I)
+ std::cout << (*I)->getName() << ", ";
+ if (nextSCC.size() == 1 && SCCI.hasLoop())
+ std::cout << " (Has self-loop).";
+ }
+ std::cout << "\n";
+
+ return true;
+}
+
+
+// run - Print out SCCs in the call graph for the specified module.
+bool CallGraphSCC::runOnModule(Module &M) {
+ CallGraphNode* rootNode = getAnalysis<CallGraph>().getRoot();
+ unsigned sccNum = 0;
+ std::cout << "SCCs for the program in PostOrder:";
+ for (scc_iterator<CallGraphNode*> SCCI = scc_begin(rootNode),
+ E = scc_end(rootNode); SCCI != E; ++SCCI) {
+ const std::vector<CallGraphNode*> &nextSCC = *SCCI;
+ std::cout << "\nSCC #" << ++sccNum << " : ";
+ for (std::vector<CallGraphNode*>::const_iterator I = nextSCC.begin(),
+ E = nextSCC.end(); I != E; ++I)
+ std::cout << ((*I)->getFunction() ? (*I)->getFunction()->getName()
+ : std::string("Indirect CallGraph node")) << ", ";
+ if (nextSCC.size() == 1 && SCCI.hasLoop())
+ std::cout << " (Has self-loop).";
+ }
+ std::cout << "\n";
+
+ return true;
+}
diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp
new file mode 100644
index 0000000..24f6b79
--- /dev/null
+++ b/tools/opt/opt.cpp
@@ -0,0 +1,441 @@
+//===- opt.cpp - The LLVM Modular Optimizer -------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Optimizations may be specified an arbitrary number of times on the command
+// line, They are run in the order specified.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Module.h"
+#include "llvm/PassManager.h"
+#include "llvm/CallGraphSCCPass.h"
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/Assembly/PrintModulePass.h"
+#include "llvm/Analysis/Verifier.h"
+#include "llvm/Analysis/LoopPass.h"
+#include "llvm/Analysis/CallGraph.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Support/PassNameParser.h"
+#include "llvm/System/Signals.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/PluginLoader.h"
+#include "llvm/Support/Streams.h"
+#include "llvm/Support/SystemUtils.h"
+#include "llvm/LinkAllPasses.h"
+#include "llvm/LinkAllVMCore.h"
+#include <iostream>
+#include <fstream>
+#include <memory>
+#include <algorithm>
+using namespace llvm;
+
+// The OptimizationList is automatically populated with registered Passes by the
+// PassNameParser.
+//
+static cl::list<const PassInfo*, bool, PassNameParser>
+PassList(cl::desc("Optimizations available:"));
+
+// Other command line options...
+//
+static cl::opt<std::string>
+InputFilename(cl::Positional, cl::desc("<input bitcode file>"),
+ cl::init("-"), cl::value_desc("filename"));
+
+static cl::opt<std::string>
+OutputFilename("o", cl::desc("Override output filename"),
+ cl::value_desc("filename"), cl::init("-"));
+
+static cl::opt<bool>
+Force("f", cl::desc("Overwrite output files"));
+
+static cl::opt<bool>
+PrintEachXForm("p", cl::desc("Print module after each transformation"));
+
+static cl::opt<bool>
+NoOutput("disable-output",
+ cl::desc("Do not write result bitcode file"), cl::Hidden);
+
+static cl::opt<bool>
+NoVerify("disable-verify", cl::desc("Do not verify result module"), cl::Hidden);
+
+static cl::opt<bool>
+VerifyEach("verify-each", cl::desc("Verify after each transform"));
+
+static cl::opt<bool>
+StripDebug("strip-debug",
+ cl::desc("Strip debugger symbol info from translation unit"));
+
+static cl::opt<bool>
+DisableInline("disable-inlining", cl::desc("Do not run the inliner pass"));
+
+static cl::opt<bool>
+DisableOptimizations("disable-opt",
+ cl::desc("Do not run any optimization passes"));
+
+static cl::opt<bool>
+StandardCompileOpts("std-compile-opts",
+ cl::desc("Include the standard compile time optimizations"));
+
+static cl::opt<bool>
+Quiet("q", cl::desc("Obsolete option"), cl::Hidden);
+
+static cl::alias
+QuietA("quiet", cl::desc("Alias for -q"), cl::aliasopt(Quiet));
+
+static cl::opt<bool>
+AnalyzeOnly("analyze", cl::desc("Only perform analysis, no optimization"));
+
+// ---------- Define Printers for module and function passes ------------
+namespace {
+
+struct CallGraphSCCPassPrinter : public CallGraphSCCPass {
+ static char ID;
+ const PassInfo *PassToPrint;
+ CallGraphSCCPassPrinter(const PassInfo *PI) :
+ CallGraphSCCPass((intptr_t)&ID), PassToPrint(PI) {}
+
+ virtual bool runOnSCC(const std::vector<CallGraphNode *>&SCC) {
+ if (!Quiet) {
+ cout << "Printing analysis '" << PassToPrint->getPassName() << "':\n";
+
+ for (unsigned i = 0, e = SCC.size(); i != e; ++i) {
+ Function *F = SCC[i]->getFunction();
+ if (F)
+ getAnalysisID<Pass>(PassToPrint).print(cout, F->getParent());
+ }
+ }
+ // Get and print pass...
+ return false;
+ }
+
+ virtual const char *getPassName() const { return "'Pass' Printer"; }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequiredID(PassToPrint);
+ AU.setPreservesAll();
+ }
+};
+
+char CallGraphSCCPassPrinter::ID = 0;
+
+struct ModulePassPrinter : public ModulePass {
+ static char ID;
+ const PassInfo *PassToPrint;
+ ModulePassPrinter(const PassInfo *PI) : ModulePass((intptr_t)&ID),
+ PassToPrint(PI) {}
+
+ virtual bool runOnModule(Module &M) {
+ if (!Quiet) {
+ cout << "Printing analysis '" << PassToPrint->getPassName() << "':\n";
+ getAnalysisID<Pass>(PassToPrint).print(cout, &M);
+ }
+
+ // Get and print pass...
+ return false;
+ }
+
+ virtual const char *getPassName() const { return "'Pass' Printer"; }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequiredID(PassToPrint);
+ AU.setPreservesAll();
+ }
+};
+
+char ModulePassPrinter::ID = 0;
+struct FunctionPassPrinter : public FunctionPass {
+ const PassInfo *PassToPrint;
+ static char ID;
+ FunctionPassPrinter(const PassInfo *PI) : FunctionPass((intptr_t)&ID),
+ PassToPrint(PI) {}
+
+ virtual bool runOnFunction(Function &F) {
+ if (!Quiet) {
+ cout << "Printing analysis '" << PassToPrint->getPassName()
+ << "' for function '" << F.getName() << "':\n";
+ }
+ // Get and print pass...
+ getAnalysisID<Pass>(PassToPrint).print(cout, F.getParent());
+ return false;
+ }
+
+ virtual const char *getPassName() const { return "FunctionPass Printer"; }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequiredID(PassToPrint);
+ AU.setPreservesAll();
+ }
+};
+
+char FunctionPassPrinter::ID = 0;
+
+struct LoopPassPrinter : public LoopPass {
+ static char ID;
+ const PassInfo *PassToPrint;
+ LoopPassPrinter(const PassInfo *PI) :
+ LoopPass((intptr_t)&ID), PassToPrint(PI) {}
+
+ virtual bool runOnLoop(Loop *L, LPPassManager &LPM) {
+ if (!Quiet) {
+ cout << "Printing analysis '" << PassToPrint->getPassName() << "':\n";
+ getAnalysisID<Pass>(PassToPrint).print(cout,
+ L->getHeader()->getParent()->getParent());
+ }
+ // Get and print pass...
+ return false;
+ }
+
+ virtual const char *getPassName() const { return "'Pass' Printer"; }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequiredID(PassToPrint);
+ AU.setPreservesAll();
+ }
+};
+
+char LoopPassPrinter::ID = 0;
+
+struct BasicBlockPassPrinter : public BasicBlockPass {
+ const PassInfo *PassToPrint;
+ static char ID;
+ BasicBlockPassPrinter(const PassInfo *PI)
+ : BasicBlockPass((intptr_t)&ID), PassToPrint(PI) {}
+
+ virtual bool runOnBasicBlock(BasicBlock &BB) {
+ if (!Quiet) {
+ cout << "Printing Analysis info for BasicBlock '" << BB.getName()
+ << "': Pass " << PassToPrint->getPassName() << ":\n";
+ }
+
+ // Get and print pass...
+ getAnalysisID<Pass>(PassToPrint).print(cout, BB.getParent()->getParent());
+ return false;
+ }
+
+ virtual const char *getPassName() const { return "BasicBlockPass Printer"; }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequiredID(PassToPrint);
+ AU.setPreservesAll();
+ }
+};
+
+char BasicBlockPassPrinter::ID = 0;
+inline void addPass(PassManager &PM, Pass *P) {
+ // Add the pass to the pass manager...
+ PM.add(P);
+
+ // If we are verifying all of the intermediate steps, add the verifier...
+ if (VerifyEach) PM.add(createVerifierPass());
+}
+
+void AddStandardCompilePasses(PassManager &PM) {
+ PM.add(createVerifierPass()); // Verify that input is correct
+
+ addPass(PM, createLowerSetJmpPass()); // Lower llvm.setjmp/.longjmp
+
+ // If the -strip-debug command line option was specified, do it.
+ if (StripDebug)
+ addPass(PM, createStripSymbolsPass(true));
+
+ if (DisableOptimizations) return;
+
+ addPass(PM, createRaiseAllocationsPass()); // call %malloc -> malloc inst
+ addPass(PM, createCFGSimplificationPass()); // Clean up disgusting code
+ addPass(PM, createPromoteMemoryToRegisterPass());// Kill useless allocas
+ addPass(PM, createGlobalOptimizerPass()); // Optimize out global vars
+ addPass(PM, createGlobalDCEPass()); // Remove unused fns and globs
+ addPass(PM, createIPConstantPropagationPass());// IP Constant Propagation
+ addPass(PM, createDeadArgEliminationPass()); // Dead argument elimination
+ addPass(PM, createInstructionCombiningPass()); // Clean up after IPCP & DAE
+ addPass(PM, createCFGSimplificationPass()); // Clean up after IPCP & DAE
+
+ addPass(PM, createPruneEHPass()); // Remove dead EH info
+
+ if (!DisableInline)
+ addPass(PM, createFunctionInliningPass()); // Inline small functions
+ addPass(PM, createArgumentPromotionPass()); // Scalarize uninlined fn args
+
+ addPass(PM, createTailDuplicationPass()); // Simplify cfg by copying code
+ addPass(PM, createInstructionCombiningPass()); // Cleanup for scalarrepl.
+ addPass(PM, createCFGSimplificationPass()); // Merge & remove BBs
+ // FIXME: Temporary!
+ addPass(PM, createScalarReplAggregatesPass()); // Break up aggregate allocas
+ addPass(PM, createInstructionCombiningPass()); // Combine silly seq's
+ addPass(PM, createCondPropagationPass()); // Propagate conditionals
+
+ addPass(PM, createTailCallEliminationPass()); // Eliminate tail calls
+ addPass(PM, createCFGSimplificationPass()); // Merge & remove BBs
+ addPass(PM, createReassociatePass()); // Reassociate expressions
+ addPass(PM, createLoopRotatePass());
+ addPass(PM, createLICMPass()); // Hoist loop invariants
+ addPass(PM, createLoopUnswitchPass()); // Unswitch loops.
+ addPass(PM, createInstructionCombiningPass()); // Clean up after LICM/reassoc
+ addPass(PM, createIndVarSimplifyPass()); // Canonicalize indvars
+ addPass(PM, createLoopUnrollPass()); // Unroll small loops
+ addPass(PM, createInstructionCombiningPass()); // Clean up after the unroller
+ addPass(PM, createLoadValueNumberingPass()); // GVN for load instructions
+ addPass(PM, createGCSEPass()); // Remove common subexprs
+ addPass(PM, createSCCPPass()); // Constant prop with SCCP
+
+ // Run instcombine after redundancy elimination to exploit opportunities
+ // opened up by them.
+ addPass(PM, createInstructionCombiningPass());
+ addPass(PM, createCondPropagationPass()); // Propagate conditionals
+
+ addPass(PM, createFastDeadStoreEliminationPass()); // Delete dead stores
+ addPass(PM, createAggressiveDCEPass()); // SSA based 'Aggressive DCE'
+ addPass(PM, createCFGSimplificationPass()); // Merge & remove BBs
+ addPass(PM, createSimplifyLibCallsPass()); // Library Call Optimizations
+ addPass(PM, createDeadTypeEliminationPass()); // Eliminate dead types
+ addPass(PM, createConstantMergePass()); // Merge dup global constants
+}
+
+} // anonymous namespace
+
+
+//===----------------------------------------------------------------------===//
+// main for opt
+//
+int main(int argc, char **argv) {
+ llvm_shutdown_obj X; // Call llvm_shutdown() on exit.
+ try {
+ cl::ParseCommandLineOptions(argc, argv,
+ " llvm .bc -> .bc modular optimizer and analysis printer \n");
+ sys::PrintStackTraceOnErrorSignal();
+
+ // Allocate a full target machine description only if necessary.
+ // FIXME: The choice of target should be controllable on the command line.
+ std::auto_ptr<TargetMachine> target;
+
+ std::string ErrorMessage;
+
+ // Load the input module...
+ std::auto_ptr<Module> M;
+ if (MemoryBuffer *Buffer
+ = MemoryBuffer::getFileOrSTDIN(InputFilename, &ErrorMessage)) {
+ M.reset(ParseBitcodeFile(Buffer, &ErrorMessage));
+ delete Buffer;
+ }
+
+ if (M.get() == 0) {
+ cerr << argv[0] << ": ";
+ if (ErrorMessage.size())
+ cerr << ErrorMessage << "\n";
+ else
+ cerr << "bitcode didn't read correctly.\n";
+ return 1;
+ }
+
+ // Figure out what stream we are supposed to write to...
+ // FIXME: cout is not binary!
+ std::ostream *Out = &std::cout; // Default to printing to stdout...
+ if (OutputFilename != "-") {
+ if (!Force && std::ifstream(OutputFilename.c_str())) {
+ // If force is not specified, make sure not to overwrite a file!
+ cerr << argv[0] << ": error opening '" << OutputFilename
+ << "': file exists!\n"
+ << "Use -f command line argument to force output\n";
+ return 1;
+ }
+ std::ios::openmode io_mode = std::ios::out | std::ios::trunc |
+ std::ios::binary;
+ Out = new std::ofstream(OutputFilename.c_str(), io_mode);
+
+ if (!Out->good()) {
+ cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
+ return 1;
+ }
+
+ // Make sure that the Output file gets unlinked from the disk if we get a
+ // SIGINT
+ sys::RemoveFileOnSignal(sys::Path(OutputFilename));
+ }
+
+ // If the output is set to be emitted to standard out, and standard out is a
+ // console, print out a warning message and refuse to do it. We don't
+ // impress anyone by spewing tons of binary goo to a terminal.
+ if (!Force && !NoOutput && CheckBitcodeOutputToConsole(Out,!Quiet)) {
+ NoOutput = true;
+ }
+
+ // Create a PassManager to hold and optimize the collection of passes we are
+ // about to build...
+ //
+ PassManager Passes;
+
+ // Add an appropriate TargetData instance for this module...
+ Passes.add(new TargetData(M.get()));
+
+ // If -std-compile-opts is given, add in all the standard compilation
+ // optimizations first. This will handle -strip-debug, -disable-inline,
+ // and -disable-opt as well.
+ if (StandardCompileOpts)
+ AddStandardCompilePasses(Passes);
+
+ // otherwise if the -strip-debug command line option was specified, add it.
+ else if (StripDebug)
+ addPass(Passes, createStripSymbolsPass(true));
+
+ // Create a new optimization pass for each one specified on the command line
+ for (unsigned i = 0; i < PassList.size(); ++i) {
+ const PassInfo *PassInf = PassList[i];
+ Pass *P = 0;
+ if (PassInf->getNormalCtor())
+ P = PassInf->getNormalCtor()();
+ else
+ cerr << argv[0] << ": cannot create pass: "
+ << PassInf->getPassName() << "\n";
+ if (P) {
+ addPass(Passes, P);
+
+ if (AnalyzeOnly) {
+ if (dynamic_cast<BasicBlockPass*>(P))
+ Passes.add(new BasicBlockPassPrinter(PassInf));
+ else if (dynamic_cast<LoopPass*>(P))
+ Passes.add(new LoopPassPrinter(PassInf));
+ else if (dynamic_cast<FunctionPass*>(P))
+ Passes.add(new FunctionPassPrinter(PassInf));
+ else if (dynamic_cast<CallGraphSCCPass*>(P))
+ Passes.add(new CallGraphSCCPassPrinter(PassInf));
+ else
+ Passes.add(new ModulePassPrinter(PassInf));
+ }
+ }
+
+ if (PrintEachXForm)
+ Passes.add(new PrintModulePass(&cerr));
+ }
+
+ // Check that the module is well formed on completion of optimization
+ if (!NoVerify && !VerifyEach)
+ Passes.add(createVerifierPass());
+
+ // Write bitcode out to disk or cout as the last step...
+ if (!NoOutput && !AnalyzeOnly)
+ Passes.add(CreateBitcodeWriterPass(*Out));
+
+ // Now that we have all of the passes ready, run them.
+ Passes.run(*M.get());
+
+ // Delete the ofstream.
+ if (Out != &std::cout)
+ delete Out;
+ return 0;
+
+ } catch (const std::string& msg) {
+ cerr << argv[0] << ": " << msg << "\n";
+ } catch (...) {
+ cerr << argv[0] << ": Unexpected unknown exception occurred.\n";
+ }
+ llvm_shutdown();
+ return 1;
+}