diff options
Diffstat (limited to 'contrib/llvm/tools')
267 files changed, 0 insertions, 39490 deletions
diff --git a/contrib/llvm/tools/CMakeLists.txt b/contrib/llvm/tools/CMakeLists.txt deleted file mode 100644 index 7ed10e9..0000000 --- a/contrib/llvm/tools/CMakeLists.txt +++ /dev/null @@ -1,43 +0,0 @@ -# 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. - -if( NOT WIN32 OR MSYS OR CYGWIN ) - # It is useful to build llvm-config before the other tools, so we - # have a fresh LibDeps.txt for regenerating the hard-coded library - # dependencies. llvm-config/CMakeLists.txt takes care of this but we - # must keep llvm-config as the first entry on the list of tools to - # be built. - add_subdirectory(llvm-config) -endif() - -add_subdirectory(opt) -add_subdirectory(llvm-as) -add_subdirectory(llvm-dis) -add_subdirectory(llvm-mc) - -add_subdirectory(llc) -add_subdirectory(llvm-ranlib) -add_subdirectory(llvm-ar) -add_subdirectory(llvm-nm) - -add_subdirectory(llvm-ld) -add_subdirectory(llvm-prof) -add_subdirectory(llvm-link) -add_subdirectory(lli) - -add_subdirectory(llvm-extract) -add_subdirectory(llvm-diff) - -add_subdirectory(bugpoint) -add_subdirectory(bugpoint-passes) -add_subdirectory(llvm-bcanalyzer) -add_subdirectory(llvm-stub) -add_subdirectory(edis) -add_subdirectory(llvmc) - -if( EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/clang/CMakeLists.txt ) - add_subdirectory( ${CMAKE_CURRENT_SOURCE_DIR}/clang ) -endif( EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/clang/CMakeLists.txt ) - -set(LLVM_COMMON_DEPENDS ${LLVM_COMMON_DEPENDS} PARENT_SCOPE) diff --git a/contrib/llvm/tools/Makefile b/contrib/llvm/tools/Makefile deleted file mode 100644 index aa07a2b..0000000 --- a/contrib/llvm/tools/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -##===- tools/Makefile --------------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL := .. - -# Build clang if present. -OPTIONAL_PARALLEL_DIRS := clang - -# 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. -DIRS := llvm-config -PARALLEL_DIRS := opt llvm-as llvm-dis \ - llc llvm-ranlib llvm-ar llvm-nm \ - llvm-ld llvm-prof llvm-link \ - lli llvm-extract llvm-mc \ - bugpoint llvm-bcanalyzer llvm-stub \ - llvmc llvm-diff - -# Let users override the set of tools to build from the command line. -ifdef ONLY_TOOLS - OPTIONAL_PARALLEL_DIRS := - PARALLEL_DIRS := $(ONLY_TOOLS) -endif - -include $(LEVEL)/Makefile.config - - -# These libraries build as dynamic libraries (.dylib /.so), they can only be -# built if ENABLE_PIC is set. -ifeq ($(ENABLE_PIC),1) - # No support for dynamic libraries on windows targets. - ifneq ($(TARGET_OS), $(filter $(TARGET_OS), Cygwin MingW)) - # gold only builds if binutils is around. It requires "lto" to build before - # it so it is added to DIRS. - ifdef BINUTILS_INCDIR - DIRS += lto gold - else - PARALLEL_DIRS += lto - endif - - PARALLEL_DIRS += bugpoint-passes - - # The edis library is only supported if ARM and/or X86 are enabled, and if - # LLVM is being built PIC on platforms that support dylibs. - ifneq ($(DISABLE_EDIS),1) - ifneq ($(filter $(TARGETS_TO_BUILD), X86 ARM),) - PARALLEL_DIRS += edis - endif - endif - endif -endif - -include $(LEVEL)/Makefile.common diff --git a/contrib/llvm/tools/bugpoint-passes/CMakeLists.txt b/contrib/llvm/tools/bugpoint-passes/CMakeLists.txt deleted file mode 100644 index 50109a5..0000000 --- a/contrib/llvm/tools/bugpoint-passes/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -add_llvm_loadable_module( BugpointPasses - TestPasses.cpp - ) diff --git a/contrib/llvm/tools/bugpoint-passes/Makefile b/contrib/llvm/tools/bugpoint-passes/Makefile deleted file mode 100644 index b4ad3e4..0000000 --- a/contrib/llvm/tools/bugpoint-passes/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -##===- tools/bugpoint-passes/Makefile -- -------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL = ../.. -LIBRARYNAME = BugpointPasses -LOADABLE_MODULE = 1 -USEDLIBS = - -# If we don't need RTTI or EH, there's no reason to export anything -# from this plugin. -ifneq ($(REQUIRES_RTTI), 1) -ifneq ($(REQUIRES_EH), 1) -EXPORTED_SYMBOL_FILE = $(PROJ_SRC_DIR)/bugpoint.exports -endif -endif - -include $(LEVEL)/Makefile.common diff --git a/contrib/llvm/tools/bugpoint-passes/TestPasses.cpp b/contrib/llvm/tools/bugpoint-passes/TestPasses.cpp deleted file mode 100644 index 1535b03..0000000 --- a/contrib/llvm/tools/bugpoint-passes/TestPasses.cpp +++ /dev/null @@ -1,75 +0,0 @@ -//===- TestPasses.cpp - "buggy" passes used to test bugpoint --------------===// -// -// The LLVM Compiler Infrastructure -// -// This file 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(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; -static 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(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; -static RegisterPass<DeleteCalls> - Y("bugpoint-deletecalls", - "BugPoint Test Pass - Intentionally 'misoptimize' CallInsts"); diff --git a/contrib/llvm/tools/bugpoint-passes/bugpoint.exports b/contrib/llvm/tools/bugpoint-passes/bugpoint.exports deleted file mode 100644 index e69de29..0000000 --- a/contrib/llvm/tools/bugpoint-passes/bugpoint.exports +++ /dev/null diff --git a/contrib/llvm/tools/bugpoint/BugDriver.cpp b/contrib/llvm/tools/bugpoint/BugDriver.cpp deleted file mode 100644 index 6966671..0000000 --- a/contrib/llvm/tools/bugpoint/BugDriver.cpp +++ /dev/null @@ -1,246 +0,0 @@ -//===- BugDriver.cpp - Top-Level BugPoint class implementation ------------===// -// -// The LLVM Compiler Infrastructure -// -// This file 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/Support/IRReader.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/FileUtilities.h" -#include "llvm/Support/SourceMgr.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/System/Host.h" -#include <memory> -using namespace llvm; - -namespace llvm { - Triple TargetTriple; -} - -// 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<std::string> &Passes) { - std::string Result; - for (unsigned i = 0, e = Passes.size(); i != e; ++i) { - if (i) Result += " "; - Result += "-"; - Result += Passes[i]; - } - return Result; -} - -BugDriver::BugDriver(const char *toolname, bool find_bugs, - unsigned timeout, unsigned memlimit, bool use_valgrind, - LLVMContext& ctxt) - : Context(ctxt), ToolName(toolname), ReferenceOutputFile(OutputFile), - Program(0), Interpreter(0), SafeInterpreter(0), gcc(0), - run_find_bugs(find_bugs), Timeout(timeout), - MemoryLimit(memlimit), UseValgrind(use_valgrind) {} - -BugDriver::~BugDriver() { - delete Program; -} - - -/// 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, - LLVMContext& Ctxt) { - SMDiagnostic Err; - Module *Result = ParseIRFile(Filename, Err, Ctxt); - if (!Result) - Err.Print("bugpoint", errs()); - - // If we don't have an override triple, use the first one to configure - // bugpoint, or use the host triple if none provided. - if (Result) { - if (TargetTriple.getTriple().empty()) { - Triple TheTriple(Result->getTargetTriple()); - - if (TheTriple.getTriple().empty()) - TheTriple.setTriple(sys::getHostTriple()); - - TargetTriple.setTriple(TheTriple.getTriple()); - } - - Result->setTargetTriple(TargetTriple.getTriple()); // override the triple - } - 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!"); - - // Load the first input file. - Program = ParseInputFile(Filenames[0], Context); - if (Program == 0) return true; - - outs() << "Read input file : '" << Filenames[0] << "'\n"; - - for (unsigned i = 1, e = Filenames.size(); i != e; ++i) { - std::auto_ptr<Module> M(ParseInputFile(Filenames[i], Context)); - if (M.get() == 0) return true; - - outs() << "Linking in input file: '" << Filenames[i] << "'\n"; - std::string ErrorMessage; - if (Linker::LinkModules(Program, M.get(), &ErrorMessage)) { - errs() << ToolName << ": error linking in '" << Filenames[i] << "': " - << ErrorMessage << '\n'; - return true; - } - } - - outs() << "*** 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(std::string &ErrMsg) { - 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, ErrMsg); - } - - // 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()) { - outs() << "Running selected passes on program to test for crash: "; - if (runPasses(Program, 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. - outs() << "Running the code generator to test for a crash: "; - std::string Error; - compileProgram(Program, &Error); - if (!Error.empty()) { - outs() << Error; - return debugCodeGeneratorCrash(ErrMsg); - } - outs() << '\n'; - - // 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()) { - outs() << "Generating reference output from raw program: "; - if (!createReferenceFile(Program)) { - return debugCodeGeneratorCrash(ErrMsg); - } - 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 && !SaveTemps); - - // 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. - outs() << "*** Checking the code generator...\n"; - bool Diff = diffProgram(Program, "", "", false, &Error); - if (!Error.empty()) { - errs() << Error; - return debugCodeGeneratorCrash(ErrMsg); - } - if (!Diff) { - outs() << "\n*** Output matches: Debugging miscompilation!\n"; - debugMiscompilation(&Error); - if (!Error.empty()) { - errs() << Error; - return debugCodeGeneratorCrash(ErrMsg); - } - return false; - } - - outs() << "\n*** Input program does not match reference diff!\n"; - outs() << "Debugging code generator problem!\n"; - bool Failure = debugCodeGenerator(&Error); - if (!Error.empty()) { - errs() << Error; - return debugCodeGeneratorCrash(ErrMsg); - } - return Failure; -} - -void llvm::PrintFunctionList(const std::vector<Function*> &Funcs) { - unsigned NumPrint = Funcs.size(); - if (NumPrint > 10) NumPrint = 10; - for (unsigned i = 0; i != NumPrint; ++i) - outs() << " " << Funcs[i]->getName(); - if (NumPrint < Funcs.size()) - outs() << "... <" << Funcs.size() << " total>"; - outs().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) - outs() << " " << GVs[i]->getName(); - if (NumPrint < GVs.size()) - outs() << "... <" << GVs.size() << " total>"; - outs().flush(); -} diff --git a/contrib/llvm/tools/bugpoint/BugDriver.h b/contrib/llvm/tools/bugpoint/BugDriver.h deleted file mode 100644 index e48806a..0000000 --- a/contrib/llvm/tools/bugpoint/BugDriver.h +++ /dev/null @@ -1,329 +0,0 @@ -//===- BugDriver.h - Top-Level BugPoint class -------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file 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 "llvm/ADT/ValueMap.h" -#include <vector> -#include <string> - -namespace llvm { - -class Value; -class PassInfo; -class Module; -class GlobalVariable; -class Function; -class BasicBlock; -class AbstractInterpreter; -class Instruction; -class LLVMContext; - -class DebugCrashes; - -class GCC; - -extern bool DisableSimplifyCFG; - -/// BugpointIsInterrupted - Set to true when the user presses ctrl-c. -/// -extern bool BugpointIsInterrupted; - -class BugDriver { - LLVMContext& Context; - const char *ToolName; // argv[0] of bugpoint - std::string ReferenceOutputFile; // Name of `good' output file - Module *Program; // The raw program, linked together - std::vector<std::string> PassesToRun; - AbstractInterpreter *Interpreter; // How to run the program - AbstractInterpreter *SafeInterpreter; // To generate reference output, etc. - GCC *gcc; - bool run_find_bugs; - unsigned Timeout; - unsigned MemoryLimit; - bool UseValgrind; - - // FIXME: sort out public/private distinctions... - friend class ReducePassList; - friend class ReduceMisCodegenFunctions; - -public: - BugDriver(const char *toolname, bool find_bugs, - unsigned timeout, unsigned memlimit, bool use_valgrind, - LLVMContext& ctxt); - ~BugDriver(); - - const char *getToolName() const { return ToolName; } - - LLVMContext& getContext() const { return Context; } - - // 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); - void addPass(std::string p) { PassesToRun.push_back(p); } - void setPassesToRun(const std::vector<std::string> &PTR) { - PassesToRun = PTR; - } - const std::vector<std::string> &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(std::string &ErrMsg); - - /// 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(std::string &Error); - - /// debugMiscompilation - This method is used when the passes selected are not - /// crashing, but the generated output is semantically different from the - /// input. - void debugMiscompilation(std::string *Error); - - /// 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, - std::string &Error); - - /// 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(std::string *Error); - - /// 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) const { - return runPasses(M, PassesToRun); - } - - 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 *switchToSafeInterpreter() { - AbstractInterpreter *Old = Interpreter; - Interpreter = (AbstractInterpreter*)SafeInterpreter; - 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, returning false and - /// setting Error if an error occurs. This is used for code generation - /// crash testing. - /// - void compileProgram(Module *M, std::string *Error) const; - - /// executeProgram - This method runs "Program", capturing the output of the - /// program to a file. A recommended filename may be optionally specified. - /// - std::string executeProgram(const Module *Program, - std::string OutputFilename, - std::string Bitcode, - const std::string &SharedObjects, - AbstractInterpreter *AI, - std::string *Error) const; - - /// executeProgramSafely - Used to create reference output with the "safe" - /// backend, if reference output is not provided. If there is a problem with - /// the code generator (e.g., llc crashes), this will return false and set - /// Error. - /// - std::string executeProgramSafely(const Module *Program, - std::string OutputFile, - std::string *Error) const; - - /// 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, 1 is returned. If there is a problem with the code - /// generator (e.g., llc crashes), this will return -1 and set Error. - /// - bool diffProgram(const Module *Program, - const std::string &BitcodeFile = "", - const std::string &SharedObj = "", - bool RemoveBitcode = false, - std::string *Error = 0) const; - - /// EmitProgressBitcode - This function is used to output M to a file named - /// "bugpoint-ID.bc". - /// - void EmitProgressBitcode(const Module *M, const std::string &ID, - bool NoFlyer = false) const; - - /// 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); - - /// 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<std::string> &Passes, - bool AutoDebugCrashes = false, unsigned NumExtraArgs = 0, - const char * const *ExtraArgs = NULL); - - /// 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 - /// outs() a single line message indicating whether compilation was successful - /// or failed, unless Quiet is set. ExtraArgs specifies additional arguments - /// to pass to the child bugpoint instance. - /// - bool runPasses(Module *Program, - const std::vector<std::string> &PassesToRun, - std::string &OutputFilename, bool DeleteOutput = false, - bool Quiet = false, unsigned NumExtraArgs = 0, - const char * const *ExtraArgs = NULL) 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<std::string> &AllPasses, - std::string &ErrMsg); - - /// writeProgramToFile - This writes the current "Program" to the named - /// bitcode file. If an error occurs, true is returned. - /// - bool writeProgramToFile(const std::string &Filename, const Module *M) 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(Module *M, - const std::vector<std::string> &PassesToRun, - bool DeleteOutput = true) const { - std::string Filename; - return runPasses(M, PassesToRun, Filename, DeleteOutput); - } - - /// 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, - LLVMContext& ctxt); - - -/// 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<std::string> &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, - ValueMap<const Value*, Value*> &VMap); - -} // End llvm namespace - -#endif diff --git a/contrib/llvm/tools/bugpoint/CMakeLists.txt b/contrib/llvm/tools/bugpoint/CMakeLists.txt deleted file mode 100644 index e06feb1..0000000 --- a/contrib/llvm/tools/bugpoint/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -set(LLVM_LINK_COMPONENTS asmparser instrumentation scalaropts ipo - linker bitreader bitwriter) - -add_llvm_tool(bugpoint - BugDriver.cpp - CrashDebugger.cpp - ExecutionDriver.cpp - ExtractFunction.cpp - FindBugs.cpp - Miscompilation.cpp - OptimizerDriver.cpp - ToolRunner.cpp - bugpoint.cpp - ) diff --git a/contrib/llvm/tools/bugpoint/CrashDebugger.cpp b/contrib/llvm/tools/bugpoint/CrashDebugger.cpp deleted file mode 100644 index 57dc1c8..0000000 --- a/contrib/llvm/tools/bugpoint/CrashDebugger.cpp +++ /dev/null @@ -1,667 +0,0 @@ -//===- CrashDebugger.cpp - Debug compilation crashes ----------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file 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/Constants.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/ADT/SmallPtrSet.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 <set> -using namespace llvm; - -namespace { - cl::opt<bool> - KeepMain("keep-main", - cl::desc("Force function reduction to keep main"), - cl::init(false)); - cl::opt<bool> - NoGlobalRM ("disable-global-remove", - cl::desc("Do not remove global variables"), - cl::init(false)); -} - -namespace llvm { - class ReducePassList : public ListReducer<std::string> { - 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<std::string> &Removed, - std::vector<std::string> &Kept, - std::string &Error); - }; -} - -ReducePassList::TestResult -ReducePassList::doTest(std::vector<std::string> &Prefix, - std::vector<std::string> &Suffix, - std::string &Error) { - sys::Path PrefixOutput; - Module *OrigProgram = 0; - if (!Prefix.empty()) { - outs() << "Checking to see if these passes crash: " - << getPassesString(Prefix) << ": "; - std::string PfxOutput; - if (BD.runPasses(BD.getProgram(), Prefix, PfxOutput)) - return KeepPrefix; - - PrefixOutput.set(PfxOutput); - OrigProgram = BD.Program; - - BD.Program = ParseInputFile(PrefixOutput.str(), BD.getContext()); - if (BD.Program == 0) { - errs() << BD.getToolName() << ": Error reading bitcode file '" - << PrefixOutput.str() << "'!\n"; - exit(1); - } - PrefixOutput.eraseFromDisk(); - } - - outs() << "Checking to see if these passes crash: " - << getPassesString(Suffix) << ": "; - - if (BD.runPasses(BD.getProgram(), 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)(const BugDriver &, Module *); - public: - ReduceCrashingGlobalVariables(BugDriver &bd, - bool (*testFn)(const BugDriver &, Module *)) - : BD(bd), TestFn(testFn) {} - - virtual TestResult doTest(std::vector<GlobalVariable*> &Prefix, - std::vector<GlobalVariable*> &Kept, - std::string &Error) { - 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... - ValueMap<const Value*, Value*> VMap; - Module *M = CloneModule(BD.getProgram(), VMap); - - // Convert list to set for fast lookup... - std::set<GlobalVariable*> GVSet; - - for (unsigned i = 0, e = GVs.size(); i != e; ++i) { - GlobalVariable* CMGV = cast<GlobalVariable>(VMap[GVs[i]]); - assert(CMGV && "Global Variable not in module?!"); - GVSet.insert(CMGV); - } - - outs() << "Checking for crash with only these global variables: "; - PrintGlobalVariableList(GVs); - outs() << ": "; - - // 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() && !GVSet.count(I)) { - 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)(const BugDriver &, Module *); - public: - ReduceCrashingFunctions(BugDriver &bd, - bool (*testFn)(const BugDriver &, Module *)) - : BD(bd), TestFn(testFn) {} - - virtual TestResult doTest(std::vector<Function*> &Prefix, - std::vector<Function*> &Kept, - std::string &Error) { - 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... - ValueMap<const Value*, Value*> VMap; - Module *M = CloneModule(BD.getProgram(), VMap); - - // Convert list to set for fast lookup... - std::set<Function*> Functions; - for (unsigned i = 0, e = Funcs.size(); i != e; ++i) { - Function *CMF = cast<Function>(VMap[Funcs[i]]); - assert(CMF && "Function not in module?!"); - assert(CMF->getFunctionType() == Funcs[i]->getFunctionType() && "wrong ty"); - assert(CMF->getName() == Funcs[i]->getName() && "wrong name"); - Functions.insert(CMF); - } - - outs() << "Checking for crash with only these functions: "; - PrintFunctionList(Funcs); - outs() << ": "; - - // 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)(const BugDriver &, Module *); - public: - ReduceCrashingBlocks(BugDriver &bd, - bool (*testFn)(const BugDriver &, Module *)) - : BD(bd), TestFn(testFn) {} - - virtual TestResult doTest(std::vector<const BasicBlock*> &Prefix, - std::vector<const BasicBlock*> &Kept, - std::string &Error) { - 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... - ValueMap<const Value*, Value*> VMap; - Module *M = CloneModule(BD.getProgram(), VMap); - - // Convert list to set for fast lookup... - SmallPtrSet<BasicBlock*, 8> Blocks; - for (unsigned i = 0, e = BBs.size(); i != e; ++i) - Blocks.insert(cast<BasicBlock>(VMap[BBs[i]])); - - outs() << "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) - outs() << " " << BBs[i]->getName(); - if (NumPrint < Blocks.size()) - outs() << "... <" << Blocks.size() << " total>"; - outs() << ": "; - - // 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); - - TerminatorInst *BBTerm = BB->getTerminator(); - - if (!BB->getTerminator()->getType()->isVoidTy()) - BBTerm->replaceAllUsesWith(Constant::getNullValue(BBTerm->getType())); - - // Replace the old terminator instruction. - BB->getInstList().pop_back(); - new UnreachableInst(BB->getContext(), 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<std::string, std::string> > BlockInfo; - - for (SmallPtrSet<BasicBlock*, 8>::iterator I = Blocks.begin(), - E = Blocks.end(); I != E; ++I) - BlockInfo.push_back(std::make_pair((*I)->getParent()->getName(), - (*I)->getName())); - - // Now run the CFG simplify pass on the function... - std::vector<std::string> Passes; - Passes.push_back("simplifycfg"); - Passes.push_back("verify"); - Module *New = BD.runPassesOn(M, Passes); - delete M; - if (!New) { - errs() << "simplifycfg failed!\n"; - exit(1); - } - M = New; - - // 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(); - const ValueSymbolTable &GST = M->getValueSymbolTable(); - for (unsigned i = 0, e = BlockInfo.size(); i != e; ++i) { - Function *F = cast<Function>(GST.lookup(BlockInfo[i].first)); - ValueSymbolTable &ST = F->getValueSymbolTable(); - Value* V = ST.lookup(BlockInfo[i].second); - if (V && V->getType() == Type::getLabelTy(V->getContext())) - BBs.push_back(cast<BasicBlock>(V)); - } - return true; - } - delete M; // It didn't crash, try something else. - return false; -} - -namespace { - /// ReduceCrashingInstructions reducer - This works by removing the specified - /// non-terminator instructions and replacing them with undef. - /// - class ReduceCrashingInstructions : public ListReducer<const Instruction*> { - BugDriver &BD; - bool (*TestFn)(const BugDriver &, Module *); - public: - ReduceCrashingInstructions(BugDriver &bd, - bool (*testFn)(const BugDriver &, Module *)) - : BD(bd), TestFn(testFn) {} - - virtual TestResult doTest(std::vector<const Instruction*> &Prefix, - std::vector<const Instruction*> &Kept, - std::string &Error) { - if (!Kept.empty() && TestInsts(Kept)) - return KeepSuffix; - if (!Prefix.empty() && TestInsts(Prefix)) - return KeepPrefix; - return NoFailure; - } - - bool TestInsts(std::vector<const Instruction*> &Prefix); - }; -} - -bool ReduceCrashingInstructions::TestInsts(std::vector<const Instruction*> - &Insts) { - // Clone the program to try hacking it apart... - ValueMap<const Value*, Value*> VMap; - Module *M = CloneModule(BD.getProgram(), VMap); - - // Convert list to set for fast lookup... - SmallPtrSet<Instruction*, 64> Instructions; - for (unsigned i = 0, e = Insts.size(); i != e; ++i) { - assert(!isa<TerminatorInst>(Insts[i])); - Instructions.insert(cast<Instruction>(VMap[Insts[i]])); - } - - outs() << "Checking for crash with only " << Instructions.size(); - if (Instructions.size() == 1) - outs() << " instruction: "; - else - outs() << " instructions: "; - - for (Module::iterator MI = M->begin(), ME = M->end(); MI != ME; ++MI) - for (Function::iterator FI = MI->begin(), FE = MI->end(); FI != FE; ++FI) - for (BasicBlock::iterator I = FI->begin(), E = FI->end(); I != E;) { - Instruction *Inst = I++; - if (!Instructions.count(Inst) && !isa<TerminatorInst>(Inst)) { - if (!Inst->getType()->isVoidTy()) - Inst->replaceAllUsesWith(UndefValue::get(Inst->getType())); - Inst->eraseFromParent(); - } - } - - // Verify that this is still valid. - PassManager Passes; - 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 instruction pointers that point into the now-current - // module, and that they don't include any deleted blocks. - Insts.clear(); - for (SmallPtrSet<Instruction*, 64>::const_iterator I = Instructions.begin(), - E = Instructions.end(); I != E; ++I) - Insts.push_back(*I); - 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)(const BugDriver &, Module *), - std::string &Error) { - // See if we can get away with nuking some of the global variable initializers - // in the program... - if (!NoGlobalRM && - 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... - outs() << "\nChecking to see if we can delete global inits: "; - - if (TestFn(BD, M)) { // Still crashes? - BD.setNewProgram(M); - outs() << "\n*** Able to remove all global initializers!\n"; - } else { // No longer crashes? - outs() << " - 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) { - outs() << "\n*** Attempting to reduce the number of global " - << "variables in the testcase\n"; - - unsigned OldSize = GVs.size(); - ReduceCrashingGlobalVariables(BD, TestFn).reduceList(GVs, Error); - if (!Error.empty()) - return true; - - if (GVs.size() < OldSize) - BD.EmitProgressBitcode(BD.getProgram(), "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) { - outs() << "\n*** Attempting to reduce the number of functions " - "in the testcase\n"; - - unsigned OldSize = Functions.size(); - ReduceCrashingFunctions(BD, TestFn).reduceList(Functions, Error); - - if (Functions.size() < OldSize) - BD.EmitProgressBitcode(BD.getProgram(), "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); - unsigned OldSize = Blocks.size(); - ReduceCrashingBlocks(BD, TestFn).reduceList(Blocks, Error); - if (Blocks.size() < OldSize) - BD.EmitProgressBitcode(BD.getProgram(), "reduced-blocks"); - } - - // Attempt to delete instructions using bisection. This should help out nasty - // cases with large basic blocks where the problem is at one end. - if (!BugpointIsInterrupted) { - std::vector<const Instruction*> Insts; - for (Module::const_iterator MI = BD.getProgram()->begin(), - ME = BD.getProgram()->end(); MI != ME; ++MI) - for (Function::const_iterator FI = MI->begin(), FE = MI->end(); FI != FE; - ++FI) - for (BasicBlock::const_iterator I = FI->begin(), E = FI->end(); - I != E; ++I) - if (!isa<TerminatorInst>(I)) - Insts.push_back(I); - - ReduceCrashingInstructions(BD, TestFn).reduceList(Insts, Error); - } - - // 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; - outs() << "\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; - - outs() << "Checking instruction: " << *I; - 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) { - outs() << "\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(BD.getProgram(), "reduced-simplified"); - - return false; -} - -static bool TestForOptimizerCrash(const 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) { - outs() << "\n*** Debugging optimizer crash!\n"; - - std::string Error; - // Reduce the list of passes which causes the optimizer to crash... - if (!BugpointIsInterrupted) - ReducePassList(*this).reduceList(PassesToRun, Error); - assert(Error.empty()); - - outs() << "\n*** Found crashing pass" - << (PassesToRun.size() == 1 ? ": " : "es: ") - << getPassesString(PassesToRun) << '\n'; - - EmitProgressBitcode(Program, ID); - - bool Success = DebugACrash(*this, TestForOptimizerCrash, Error); - assert(Error.empty()); - return Success; -} - -static bool TestForCodeGenCrash(const BugDriver &BD, Module *M) { - std::string Error; - BD.compileProgram(M, &Error); - if (!Error.empty()) { - errs() << "<crash>\n"; - return true; // Tool is still crashing. - } - errs() << '\n'; - return false; -} - -/// 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::string &Error) { - errs() << "*** Debugging code generator crash!\n"; - - return DebugACrash(*this, TestForCodeGenCrash, Error); -} diff --git a/contrib/llvm/tools/bugpoint/ExecutionDriver.cpp b/contrib/llvm/tools/bugpoint/ExecutionDriver.cpp deleted file mode 100644 index 7312484..0000000 --- a/contrib/llvm/tools/bugpoint/ExecutionDriver.cpp +++ /dev/null @@ -1,501 +0,0 @@ -//===- ExecutionDriver.cpp - Allow execution of LLVM program --------------===// -// -// The LLVM Compiler Infrastructure -// -// This file 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 "llvm/Support/raw_ostream.h" -#include <fstream> - -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, RunLLCIA, RunCBE, CBE_bug, LLC_Safe,Custom - }; - - 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 the \"test\" i.e. suspect back-end:"), - 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(RunLLCIA, "run-llc-ia", - "Compile with LLC with integrated assembler"), - clEnumValN(RunCBE, "run-cbe", "Compile with CBE"), - clEnumValN(CBE_bug,"cbe-bug", "Find CBE bugs"), - clEnumValN(LLC_Safe, "llc-safe", "Use LLC for all"), - clEnumValN(Custom, "run-custom", - "Use -exec-command to define a command to execute " - "the bitcode. Useful for cross-compilation."), - clEnumValEnd), - cl::init(AutoPick)); - - cl::opt<OutputType> - SafeInterpreterSel(cl::desc("Specify \"safe\" i.e. known-good backend:"), - cl::values(clEnumValN(AutoPick, "safe-auto", "Use best guess"), - clEnumValN(RunLLC, "safe-run-llc", "Compile with LLC"), - clEnumValN(RunCBE, "safe-run-cbe", "Compile with CBE"), - clEnumValN(Custom, "safe-run-custom", - "Use -exec-command to define a command to execute " - "the bitcode. Useful for cross-compilation."), - clEnumValEnd), - cl::init(AutoPick)); - - cl::opt<std::string> - SafeInterpreterPath("safe-path", - cl::desc("Specify the path to the \"safe\" backend program"), - cl::init("")); - - 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")); - - cl::opt<std::string> - CustomExecCommand("exec-command", cl::init("simulate"), - cl::desc("Command to execute the bitcode (use with -run-custom) " - "(default: simulate)")); -} - -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::opt<std::string> - OutputPrefix("output-prefix", cl::init("bugpoint"), - cl::desc("Prefix to use for outputs (default: 'bugpoint')")); -} - -namespace { - cl::list<std::string> - ToolArgv("tool-args", cl::Positional, cl::desc("<tool arguments>..."), - cl::ZeroOrMore, cl::PositionalEatsArgs); - - cl::list<std::string> - SafeToolArgv("safe-tool-args", cl::Positional, - cl::desc("<safe-tool arguments>..."), - cl::ZeroOrMore, cl::PositionalEatsArgs); - - cl::opt<std::string> - GCCBinary("gcc", cl::init("gcc"), - cl::desc("The gcc binary to use. (default 'gcc')")); - - cl::list<std::string> - GCCToolArgv("gcc-tool-args", cl::Positional, - cl::desc("<gcc-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() { - outs() << "Initializing execution environment: "; - - // Create an instance of the AbstractInterpreter interface as specified on - // the command line - SafeInterpreter = 0; - std::string Message; - - switch (InterpreterSel) { - case AutoPick: - InterpreterSel = RunCBE; - Interpreter = - AbstractInterpreter::createCBE(getToolName(), Message, GCCBinary, - &ToolArgv, &GCCToolArgv); - if (!Interpreter) { - InterpreterSel = RunJIT; - Interpreter = AbstractInterpreter::createJIT(getToolName(), Message, - &ToolArgv); - } - if (!Interpreter) { - InterpreterSel = RunLLC; - Interpreter = AbstractInterpreter::createLLC(getToolName(), Message, - GCCBinary, &ToolArgv, - &GCCToolArgv); - } - 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: - case RunLLCIA: - case LLC_Safe: - Interpreter = AbstractInterpreter::createLLC(getToolName(), Message, - GCCBinary, &ToolArgv, - &GCCToolArgv, - InterpreterSel == RunLLCIA); - break; - case RunJIT: - Interpreter = AbstractInterpreter::createJIT(getToolName(), Message, - &ToolArgv); - break; - case RunCBE: - case CBE_bug: - Interpreter = AbstractInterpreter::createCBE(getToolName(), Message, - GCCBinary, &ToolArgv, - &GCCToolArgv); - break; - case Custom: - Interpreter = AbstractInterpreter::createCustom(Message, CustomExecCommand); - break; - default: - Message = "Sorry, this back-end is not supported by bugpoint right now!\n"; - break; - } - if (!Interpreter) - errs() << Message; - else // Display informational messages on stdout instead of stderr - outs() << Message; - - std::string Path = SafeInterpreterPath; - if (Path.empty()) - Path = getToolName(); - std::vector<std::string> SafeToolArgs = SafeToolArgv; - switch (SafeInterpreterSel) { - case AutoPick: - // In "cbe-bug" mode, default to using LLC as the "safe" backend. - if (!SafeInterpreter && - InterpreterSel == CBE_bug) { - SafeInterpreterSel = RunLLC; - SafeToolArgs.push_back("--relocation-model=pic"); - SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message, - GCCBinary, - &SafeToolArgs, - &GCCToolArgv); - } - - // In "llc-safe" mode, default to using LLC as the "safe" backend. - if (!SafeInterpreter && - InterpreterSel == LLC_Safe) { - SafeInterpreterSel = RunLLC; - SafeToolArgs.push_back("--relocation-model=pic"); - SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message, - GCCBinary, - &SafeToolArgs, - &GCCToolArgv); - } - - // Pick a backend that's different from the test backend. The JIT and - // LLC backends share a lot of code, so prefer to use the CBE as the - // safe back-end when testing them. - if (!SafeInterpreter && - InterpreterSel != RunCBE) { - SafeInterpreterSel = RunCBE; - SafeInterpreter = AbstractInterpreter::createCBE(Path.c_str(), Message, - GCCBinary, - &SafeToolArgs, - &GCCToolArgv); - } - if (!SafeInterpreter && - InterpreterSel != RunLLC && - InterpreterSel != RunJIT) { - SafeInterpreterSel = RunLLC; - SafeToolArgs.push_back("--relocation-model=pic"); - SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message, - GCCBinary, - &SafeToolArgs, - &GCCToolArgv); - } - if (!SafeInterpreter) { - SafeInterpreterSel = AutoPick; - Message = "Sorry, I can't automatically select an interpreter!\n"; - } - break; - case RunLLC: - case RunLLCIA: - SafeToolArgs.push_back("--relocation-model=pic"); - SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message, - GCCBinary, &SafeToolArgs, - &GCCToolArgv, - SafeInterpreterSel == RunLLCIA); - break; - case RunCBE: - SafeInterpreter = AbstractInterpreter::createCBE(Path.c_str(), Message, - GCCBinary, &SafeToolArgs, - &GCCToolArgv); - break; - case Custom: - SafeInterpreter = AbstractInterpreter::createCustom(Message, - CustomExecCommand); - break; - default: - Message = "Sorry, this back-end is not supported by bugpoint as the " - "\"safe\" backend right now!\n"; - break; - } - if (!SafeInterpreter) { outs() << Message << "\nExiting.\n"; exit(1); } - - gcc = GCC::create(Message, GCCBinary, &GCCToolArgv); - if (!gcc) { outs() << 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, returning false and -/// setting Error if an error occurs. This is used for code generation -/// crash testing. -/// -void BugDriver::compileProgram(Module *M, std::string *Error) const { - // Emit the program to a bitcode file... - sys::Path BitcodeFile (OutputPrefix + "-test-program.bc"); - std::string ErrMsg; - if (BitcodeFile.makeUnique(true, &ErrMsg)) { - errs() << ToolName << ": Error making unique filename: " << ErrMsg - << "\n"; - exit(1); - } - if (writeProgramToFile(BitcodeFile.str(), M)) { - errs() << ToolName << ": Error emitting bitcode to file '" - << BitcodeFile.str() << "'!\n"; - exit(1); - } - - // Remove the temporary bitcode file when we are done. - FileRemover BitcodeFileRemover(BitcodeFile, !SaveTemps); - - // Actually compile the program! - Interpreter->compileProgram(BitcodeFile.str(), Error, Timeout, MemoryLimit); -} - - -/// 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(const Module *Program, - std::string OutputFile, - std::string BitcodeFile, - const std::string &SharedObj, - AbstractInterpreter *AI, - std::string *Error) const { - 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(OutputPrefix + "-test-program.bc"); - if (uniqueFilename.makeUnique(true, &ErrMsg)) { - errs() << ToolName << ": Error making unique filename: " - << ErrMsg << "!\n"; - exit(1); - } - BitcodeFile = uniqueFilename.str(); - - if (writeProgramToFile(BitcodeFile, Program)) { - errs() << 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 && !SaveTemps); - - if (OutputFile.empty()) OutputFile = OutputPrefix + "-execution-output"; - - // Check to see if this is a valid output filename... - sys::Path uniqueFile(OutputFile); - if (uniqueFile.makeUnique(true, &ErrMsg)) { - errs() << ToolName << ": Error making unique filename: " - << ErrMsg << "\n"; - exit(1); - } - OutputFile = uniqueFile.str(); - - // Figure out which shared objects to run, if any. - std::vector<std::string> SharedObjs(AdditionalSOs); - if (!SharedObj.empty()) - SharedObjs.push_back(SharedObj); - - int RetVal = AI->ExecuteProgram(BitcodeFile, InputArgv, InputFile, OutputFile, - Error, AdditionalLinkerArgs, SharedObjs, - Timeout, MemoryLimit); - if (!Error->empty()) - return OutputFile; - - if (RetVal == -1) { - errs() << "<timeout>"; - static bool FirstTimeout = true; - if (FirstTimeout) { - outs() << "\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(); - } - - // Return the filename we captured the output to. - return OutputFile; -} - -/// executeProgramSafely - Used to create reference output with the "safe" -/// backend, if reference output is not provided. -/// -std::string BugDriver::executeProgramSafely(const Module *Program, - std::string OutputFile, - std::string *Error) const { - return executeProgram(Program, OutputFile, "", "", SafeInterpreter, Error); -} - -std::string BugDriver::compileSharedObject(const std::string &BitcodeFile, - std::string &Error) { - assert(Interpreter && "Interpreter should have been created already!"); - sys::Path OutputFile; - - // Using the known-good backend. - GCC::FileType FT = SafeInterpreter->OutputCode(BitcodeFile, OutputFile, - Error); - if (!Error.empty()) - return ""; - - std::string SharedObjectFile; - bool Failure = gcc->MakeSharedObject(OutputFile.str(), FT, SharedObjectFile, - AdditionalLinkerArgs, Error); - if (!Error.empty()) - return ""; - if (Failure) - 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) { - std::string Error; - compileProgram(Program, &Error); - if (!Error.empty()) - return false; - - ReferenceOutputFile = executeProgramSafely(Program, Filename, &Error); - if (!Error.empty()) { - errs() << Error; - if (Interpreter != SafeInterpreter) { - errs() << "*** There is a bug running the \"safe\" backend. Either" - << " debug it (for example with the -run-cbe bugpoint option," - << " if CBE is being used as the \"safe\" backend), or fix the" - << " error some other way.\n"; - } - return false; - } - outs() << "\nReference output is: " << ReferenceOutputFile << "\n\n"; - return true; -} - -/// diffProgram - This method executes the specified module and diffs the -/// output against the file specified by ReferenceOutputFile. If the output -/// is different, 1 is returned. If there is a problem with the code -/// generator (e.g., llc crashes), this will return -1 and set Error. -/// -bool BugDriver::diffProgram(const Module *Program, - const std::string &BitcodeFile, - const std::string &SharedObject, - bool RemoveBitcode, - std::string *ErrMsg) const { - // Execute the program, generating an output file... - sys::Path Output(executeProgram(Program, "", BitcodeFile, SharedObject, 0, - ErrMsg)); - if (!ErrMsg->empty()) - return false; - - std::string Error; - bool FilesDifferent = false; - if (int Diff = DiffFilesWithTolerance(sys::Path(ReferenceOutputFile), - sys::Path(Output.str()), - AbsTolerance, RelTolerance, &Error)) { - if (Diff == 2) { - errs() << "While diffing output: " << Error << '\n'; - exit(1); - } - FilesDifferent = true; - } - else { - // Remove the generated output if there are no differences. - 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/contrib/llvm/tools/bugpoint/ExtractFunction.cpp b/contrib/llvm/tools/bugpoint/ExtractFunction.cpp deleted file mode 100644 index 524f130..0000000 --- a/contrib/llvm/tools/bugpoint/ExtractFunction.cpp +++ /dev/null @@ -1,369 +0,0 @@ -//===- ExtractFunction.cpp - Extract a function from Program --------------===// -// -// The LLVM Compiler Infrastructure -// -// This file 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/LLVMContext.h" -#include "llvm/Module.h" -#include "llvm/PassManager.h" -#include "llvm/Pass.h" -#include "llvm/Analysis/Verifier.h" -#include "llvm/Assembly/Writer.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 "llvm/Support/raw_ostream.h" -#include "llvm/System/Path.h" -#include "llvm/System/Signals.h" -#include <set> -using namespace llvm; - -namespace llvm { - bool DisableSimplifyCFG = false; - extern cl::opt<std::string> OutputPrefix; -} // 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) { - // FIXME, use vmap? - Module *Clone = CloneModule(Program); - - const BasicBlock *PBB = I->getParent(); - const Function *PF = PBB->getParent(); - - Module::iterator RFI = Clone->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()->isVoidTy()) - TheInst->replaceAllUsesWith(Constant::getNullValue(TheInst->getType())); - - // Remove the instruction from the program. - TheInst->getParent()->getInstList().erase(TheInst); - - // Spiff up the output a little bit. - std::vector<std::string> Passes; - - /// Can we get rid of the -disable-* options? - if (Simplification > 1 && !NoDCE) - Passes.push_back("dce"); - if (Simplification && !DisableSimplifyCFG) - Passes.push_back("simplifycfg"); // Delete dead control flow - - Passes.push_back("verify"); - Module *New = runPassesOn(Clone, Passes); - delete Clone; - if (!New) { - errs() << "Instruction removal failed. Sorry. :( Please report a bug!\n"; - exit(1); - } - return New; -} - -/// 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<std::string> CleanupPasses; - CleanupPasses.push_back("globaldce"); - - if (MayModifySemantics) - CleanupPasses.push_back("deadarghaX0r"); - else - CleanupPasses.push_back("deadargelim"); - - CleanupPasses.push_back("deadtypeelim"); - - Module *New = runPassesOn(M, CleanupPasses); - if (New == 0) { - errs() << "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<std::string> LoopExtractPasses; - LoopExtractPasses.push_back("loop-extract-single"); - - Module *NewM = runPassesOn(M, LoopExtractPasses); - if (NewM == 0) { - outs() << "*** Loop extraction failed: "; - EmitProgressBitcode(M, "loopextraction", true); - outs() << "*** Sorry. :( Please report a bug!\n"; - 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::getInt32Ty(TorList[i].first->getContext()), TorList[i].second)); - Elts.push_back(TorList[i].first); - ArrayElts.push_back(ConstantStruct::get(TorList[i].first->getContext(), - Elts, false)); - } - 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, - ValueMap<const Value*, Value*> &VMap) { - GlobalVariable *GV = M1->getNamedGlobal(GlobalName); - if (!GV || GV->isDeclaration() || GV->hasLocalLinkage() || - !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 = cast<Function>(VMap[F]); - M2Tors.push_back(std::make_pair(F, Priority)); - } - } - } - } - - GV->eraseFromParent(); - if (!M1Tors.empty()) { - Constant *M1Init = GetTorInit(M1Tors); - new GlobalVariable(*M1, M1Init->getType(), false, - GlobalValue::AppendingLinkage, - M1Init, GlobalName); - } - - 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(*M2, M2Init->getType(), false, - GlobalValue::AppendingLinkage, - M2Init, GlobalName); - } -} - - -/// 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, - ValueMap<const Value*, Value*> &VMap) { - // 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) { - if (I->hasName() && I->getName()[0] == '\01') - I->setName(I->getName().substr(1)); - I->setLinkage(GlobalValue::ExternalLinkage); - } - - ValueMap<const Value*, Value*> NewVMap; - Module *New = CloneModule(M, NewVMap); - - // 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<Function *> TestFunctions; - for (unsigned i = 0, e = F.size(); i != e; ++i) { - Function *TNOF = cast<Function>(VMap[F[i]]); - DEBUG(errs() << "Removing function "); - DEBUG(WriteAsOperand(errs(), TNOF, false)); - DEBUG(errs() << "\n"); - TestFunctions.insert(cast<Function>(NewVMap[TNOF])); - 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(I)) - 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, NewVMap); - SplitStaticCtorDtor("llvm.global_dtors", M, New, NewVMap); - - return New; -} - -//===----------------------------------------------------------------------===// -// Basic Block Extraction Code -//===----------------------------------------------------------------------===// - -/// 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) { - sys::Path uniqueFilename(OutputPrefix + "-extractblocks"); - std::string ErrMsg; - if (uniqueFilename.createTemporaryFileOnDisk(true, &ErrMsg)) { - outs() << "*** Basic Block extraction failed!\n"; - errs() << "Error creating temporary file: " << ErrMsg << "\n"; - EmitProgressBitcode(M, "basicblockextractfail", true); - return 0; - } - sys::RemoveFileOnSignal(uniqueFilename); - - std::string ErrorInfo; - tool_output_file BlocksToNotExtractFile(uniqueFilename.c_str(), ErrorInfo); - if (!ErrorInfo.empty()) { - outs() << "*** Basic Block extraction failed!\n"; - errs() << "Error writing list of blocks to not extract: " << ErrorInfo - << "\n"; - EmitProgressBitcode(M, "basicblockextractfail", true); - return 0; - } - for (std::vector<BasicBlock*>::const_iterator I = BBs.begin(), E = BBs.end(); - I != E; ++I) { - BasicBlock *BB = *I; - // If the BB doesn't have a name, give it one so we have something to key - // off of. - if (!BB->hasName()) BB->setName("tmpbb"); - BlocksToNotExtractFile.os() << BB->getParent()->getNameStr() << " " - << BB->getName() << "\n"; - } - BlocksToNotExtractFile.os().close(); - if (BlocksToNotExtractFile.os().has_error()) { - errs() << "Error writing list of blocks to not extract: " << ErrorInfo - << "\n"; - EmitProgressBitcode(M, "basicblockextractfail", true); - BlocksToNotExtractFile.os().clear_error(); - return 0; - } - BlocksToNotExtractFile.keep(); - - std::string uniqueFN = "--extract-blocks-file=" + uniqueFilename.str(); - const char *ExtraArg = uniqueFN.c_str(); - - std::vector<std::string> PI; - PI.push_back("extract-blocks"); - Module *Ret = runPassesOn(M, PI, false, 1, &ExtraArg); - - uniqueFilename.eraseFromDisk(); // Free disk space - - if (Ret == 0) { - outs() << "*** Basic Block extraction failed, please report a bug!\n"; - EmitProgressBitcode(M, "basicblockextractfail", true); - } - return Ret; -} diff --git a/contrib/llvm/tools/bugpoint/FindBugs.cpp b/contrib/llvm/tools/bugpoint/FindBugs.cpp deleted file mode 100644 index a291f9f..0000000 --- a/contrib/llvm/tools/bugpoint/FindBugs.cpp +++ /dev/null @@ -1,113 +0,0 @@ -//===-- FindBugs.cpp - Run Many Different Optimizations -------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file 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 "llvm/Support/raw_ostream.h" -#include <algorithm> -#include <ctime> -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<std::string> &AllPasses, - std::string &ErrMsg) { - setPassesToRun(AllPasses); - outs() << "Starting bug finding procedure...\n\n"; - - // Creating a reference output if necessary - if (initializeExecutionEnvironment()) return false; - - outs() << "\n"; - if (ReferenceOutputFile.empty()) { - outs() << "Generating reference output from raw program: \n"; - if (!createReferenceFile(Program)) - return false; - } - - srand(time(NULL)); - - unsigned num = 1; - while(1) { - // - // Step 1: Randomize the order of the optimizer passes. - // - std::random_shuffle(PassesToRun.begin(), PassesToRun.end()); - - // - // Step 2: Run optimizer passes on the program and check for success. - // - outs() << "Running selected passes on program to test for crash: "; - for(int i = 0, e = PassesToRun.size(); i != e; i++) { - outs() << "-" << PassesToRun[i] << " "; - } - - std::string Filename; - if(runPasses(Program, PassesToRun, Filename, false)) { - outs() << "\n"; - outs() << "Optimizer passes caused failure!\n\n"; - debugOptimizerCrash(); - return true; - } else { - outs() << "Combination " << num << " optimized successfully!\n"; - } - - // - // Step 3: Compile the optimized code. - // - outs() << "Running the code generator to test for a crash: "; - std::string Error; - compileProgram(Program, &Error); - if (!Error.empty()) { - outs() << "\n*** compileProgram threw an exception: "; - outs() << Error; - return debugCodeGeneratorCrash(ErrMsg); - } - outs() << '\n'; - - // - // Step 4: Run the program and compare its output to the reference - // output (created above). - // - outs() << "*** Checking if passes caused miscompliation:\n"; - bool Diff = diffProgram(Program, Filename, "", false, &Error); - if (Error.empty() && Diff) { - outs() << "\n*** diffProgram returned true!\n"; - debugMiscompilation(&Error); - if (Error.empty()) - return true; - } - if (!Error.empty()) { - errs() << Error; - debugCodeGeneratorCrash(ErrMsg); - return true; - } - outs() << "\n*** diff'd output matches!\n"; - - sys::Path(Filename).eraseFromDisk(); - - outs() << "\n\n"; - num++; - } //end while - - // Unreachable. -} diff --git a/contrib/llvm/tools/bugpoint/ListReducer.h b/contrib/llvm/tools/bugpoint/ListReducer.h deleted file mode 100644 index bd1c5da..0000000 --- a/contrib/llvm/tools/bugpoint/ListReducer.h +++ /dev/null @@ -1,201 +0,0 @@ -//===- ListReducer.h - Trim down list while retaining property --*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file 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 "llvm/Support/raw_ostream.h" -#include "llvm/Support/ErrorHandling.h" -#include <vector> -#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 - InternalError // Encountered an error trying to run 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, - std::string &Error) = 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::string &Error) { - std::vector<ElTy> empty; - std::srand(0x6e5ea738); // Seed the random number generator - switch (doTest(TheList, empty, Error)) { - 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! - llvm_unreachable("bugpoint ListReducer internal error: " - "selected empty set."); - - case NoFailure: - return false; // there is no failure with the full set of passes/funcs! - - case InternalError: - assert(!Error.empty()); - return true; - } - - // 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) { - errs() << "\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()); - errs() << "\n\n*** Testing shuffled set...\n\n"; - // Check that random shuffle doesn't loose the bug - if (doTest(ShuffledList, empty, Error) == 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; - errs() << "\n\n*** Shuffling does not hide the bug...\n\n"; - } else { - ShufflingEnabled = false; // Disable shuffling further on - errs() << "\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, Error)) { - 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; - case InternalError: - return true; // Error was set by doTest. - } - assert(Error.empty() && "doTest did not return InternalError for error"); - } - - // 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) { - errs() << "\n\n*** Reduction Interrupted, cleaning up...\n\n"; - return true; - } - - std::vector<ElTy> TestList(TheList); - TestList.erase(TestList.begin()+i); - - if (doTest(EmptyList, TestList, Error) == KeepSuffix) { - // We can trim down the list! - TheList.swap(TestList); - --i; // Don't skip an element of the list - Changed = true; - } - if (!Error.empty()) - return 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/contrib/llvm/tools/bugpoint/Makefile b/contrib/llvm/tools/bugpoint/Makefile deleted file mode 100644 index 5d287ef..0000000 --- a/contrib/llvm/tools/bugpoint/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -##===- tools/bugpoint/Makefile -----------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -LEVEL = ../.. - -TOOLNAME = bugpoint - -LINK_COMPONENTS := asmparser instrumentation scalaropts ipo \ - linker bitreader bitwriter - -include $(LEVEL)/Makefile.common diff --git a/contrib/llvm/tools/bugpoint/Miscompilation.cpp b/contrib/llvm/tools/bugpoint/Miscompilation.cpp deleted file mode 100644 index 3f2b696..0000000 --- a/contrib/llvm/tools/bugpoint/Miscompilation.cpp +++ /dev/null @@ -1,1082 +0,0 @@ -//===- Miscompilation.cpp - Debug program miscompilations -----------------===// -// -// The LLVM Compiler Infrastructure -// -// This file 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 "ToolRunner.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/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::opt<std::string> OutputPrefix; - 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)); - static llvm::cl::opt<bool> - DisableBlockExtraction("disable-block-extraction", - cl::desc("Don't extract blocks when searching for miscompilations"), - cl::init(false)); - - class ReduceMiscompilingPasses : public ListReducer<std::string> { - BugDriver &BD; - public: - ReduceMiscompilingPasses(BugDriver &bd) : BD(bd) {} - - virtual TestResult doTest(std::vector<std::string> &Prefix, - std::vector<std::string> &Suffix, - std::string &Error); - }; -} - -/// 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<std::string> &Prefix, - std::vector<std::string> &Suffix, - std::string &Error) { - // First, run the program with just the Suffix passes. If it is still broken - // with JUST the kept passes, discard the prefix passes. - outs() << "Checking to see if '" << getPassesString(Suffix) - << "' compiles correctly: "; - - std::string BitcodeResult; - if (BD.runPasses(BD.getProgram(), Suffix, BitcodeResult, false/*delete*/, - true/*quiet*/)) { - errs() << " Error running this sequence of passes" - << " on the input program!\n"; - BD.setPassesToRun(Suffix); - BD.EmitProgressBitcode(BD.getProgram(), "pass-error", false); - exit(BD.debugOptimizerCrash()); - } - - // Check to see if the finished program matches the reference output... - bool Diff = BD.diffProgram(BD.getProgram(), BitcodeResult, "", - true /*delete bitcode*/, &Error); - if (!Error.empty()) - return InternalError; - if (Diff) { - outs() << " nope.\n"; - if (Suffix.empty()) { - errs() << BD.getToolName() << ": I'm confused: the test fails when " - << "no passes are run, nondeterministic program?\n"; - exit(1); - } - return KeepSuffix; // Miscompilation detected! - } - outs() << " 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. - outs() << "Checking to see if '" << getPassesString(Prefix) - << "' compiles 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(BD.getProgram(), Prefix, BitcodeResult, false/*delete*/, - true/*quiet*/)) { - errs() << " Error running this sequence of passes" - << " on the input program!\n"; - BD.setPassesToRun(Prefix); - BD.EmitProgressBitcode(BD.getProgram(), "pass-error", false); - exit(BD.debugOptimizerCrash()); - } - - // If the prefix maintains the predicate by itself, only keep the prefix! - Diff = BD.diffProgram(BD.getProgram(), BitcodeResult, "", false, &Error); - if (!Error.empty()) - return InternalError; - if (Diff) { - outs() << " nope.\n"; - sys::Path(BitcodeResult).eraseFromDisk(); - return KeepPrefix; - } - outs() << " 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. - // - OwningPtr<Module> PrefixOutput(ParseInputFile(BitcodeResult, - BD.getContext())); - if (PrefixOutput == 0) { - errs() << 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; - - outs() << "Checking to see if '" << getPassesString(Suffix) - << "' passes compile correctly after the '" - << getPassesString(Prefix) << "' passes: "; - - OwningPtr<Module> OriginalInput(BD.swapProgramIn(PrefixOutput.take())); - if (BD.runPasses(BD.getProgram(), Suffix, BitcodeResult, false/*delete*/, - true/*quiet*/)) { - errs() << " Error running this sequence of passes" - << " on the input program!\n"; - BD.setPassesToRun(Suffix); - BD.EmitProgressBitcode(BD.getProgram(), "pass-error", false); - exit(BD.debugOptimizerCrash()); - } - - // Run the result... - Diff = BD.diffProgram(BD.getProgram(), BitcodeResult, "", - true /*delete bitcode*/, &Error); - if (!Error.empty()) - return InternalError; - if (Diff) { - outs() << " nope.\n"; - return KeepSuffix; - } - - // Otherwise, we must not be running the bad pass anymore. - outs() << " yup.\n"; // No miscompilation! - // Restore orig program & free test. - delete BD.swapProgramIn(OriginalInput.take()); - return NoFailure; -} - -namespace { - class ReduceMiscompilingFunctions : public ListReducer<Function*> { - BugDriver &BD; - bool (*TestFn)(BugDriver &, Module *, Module *, std::string &); - public: - ReduceMiscompilingFunctions(BugDriver &bd, - bool (*F)(BugDriver &, Module *, Module *, - std::string &)) - : BD(bd), TestFn(F) {} - - virtual TestResult doTest(std::vector<Function*> &Prefix, - std::vector<Function*> &Suffix, - std::string &Error) { - if (!Suffix.empty()) { - bool Ret = TestFuncs(Suffix, Error); - if (!Error.empty()) - return InternalError; - if (Ret) - return KeepSuffix; - } - if (!Prefix.empty()) { - bool Ret = TestFuncs(Prefix, Error); - if (!Error.empty()) - return InternalError; - if (Ret) - return KeepPrefix; - } - return NoFailure; - } - - bool TestFuncs(const std::vector<Function*> &Prefix, std::string &Error); - }; -} - -/// TestMergedProgram - Given two modules, link them together and run the -/// program, checking to see if the program matches the diff. If there is -/// an error, return NULL. If not, return the merged module. The Broken argument -/// will be set to true if the output is different. If the DeleteInputs -/// argument is set to true then this function deletes both input -/// modules before it returns. -/// -static Module *TestMergedProgram(const BugDriver &BD, Module *M1, Module *M2, - bool DeleteInputs, std::string &Error, - bool &Broken) { - // 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)) { - errs() << BD.getToolName() << ": Error linking modules together:" - << ErrorMsg << '\n'; - exit(1); - } - delete M2; // We are done with this module. - - // Execute the program. - Broken = BD.diffProgram(M1, "", "", false, &Error); - if (!Error.empty()) { - // Delete the linked module - delete M1; - return NULL; - } - return M1; -} - -/// 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, - std::string &Error) { - // Test to see if the function is misoptimized if we ONLY run it on the - // functions listed in Funcs. - outs() << "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); - outs() << '\n'; - - // Create a clone for two reasons: - // * If the optimization passes delete any function, the deleted function - // will be in the clone and Funcs will still point to valid memory - // * If the optimization passes use interprocedural information to break - // a function, we want to continue with the original function. Otherwise - // we can conclude that a function triggers the bug when in fact one - // needs a larger set of original functions to do so. - ValueMap<const Value*, Value*> VMap; - Module *Clone = CloneModule(BD.getProgram(), VMap); - Module *Orig = BD.swapProgramIn(Clone); - - std::vector<Function*> FuncsOnClone; - for (unsigned i = 0, e = Funcs.size(); i != e; ++i) { - Function *F = cast<Function>(VMap[Funcs[i]]); - FuncsOnClone.push_back(F); - } - - // Split the module into the two halves of the program we want. - VMap.clear(); - Module *ToNotOptimize = CloneModule(BD.getProgram(), VMap); - Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize, FuncsOnClone, - VMap); - - // Run the predicate, note that the predicate will delete both input modules. - bool Broken = TestFn(BD, ToOptimize, ToNotOptimize, Error); - - delete BD.swapProgramIn(Orig); - - return Broken; -} - -/// DisambiguateGlobalSymbols - Give anonymous global values names. -/// -static void DisambiguateGlobalSymbols(Module *M) { - for (Module::global_iterator I = M->global_begin(), E = M->global_end(); - I != E; ++I) - if (!I->hasName()) - I->setName("anon_global"); - for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) - if (!I->hasName()) - I->setName("anon_fn"); -} - -/// 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::string &), - std::vector<Function*> &MiscompiledFunctions, - std::string &Error) { - bool MadeChange = false; - while (1) { - if (BugpointIsInterrupted) return MadeChange; - - ValueMap<const Value*, Value*> VMap; - Module *ToNotOptimize = CloneModule(BD.getProgram(), VMap); - Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize, - MiscompiledFunctions, - VMap); - 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; - } - - errs() << "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.switchToSafeInterpreter(); - bool Failure; - Module *New = TestMergedProgram(BD, ToOptimizeLoopExtracted, ToNotOptimize, - false, Error, Failure); - if (!New) - return false; - // Delete the original and set the new program. - delete BD.swapProgramIn(New); - if (Failure) { - BD.switchToInterpreter(AI); - - // Merged program doesn't work anymore! - errs() << " *** ERROR: Loop extraction broke the program. :(" - << " Please report a bug!\n"; - errs() << " Continuing on with un-loop-extracted version.\n"; - - BD.writeProgramToFile(OutputPrefix + "-loop-extract-fail-tno.bc", - ToNotOptimize); - BD.writeProgramToFile(OutputPrefix + "-loop-extract-fail-to.bc", - ToOptimize); - BD.writeProgramToFile(OutputPrefix + "-loop-extract-fail-to-le.bc", - ToOptimizeLoopExtracted); - - errs() << "Please submit the " - << OutputPrefix << "-loop-extract-fail-*.bc files.\n"; - delete ToOptimize; - delete ToNotOptimize; - delete ToOptimizeLoopExtracted; - return MadeChange; - } - delete ToOptimize; - BD.switchToInterpreter(AI); - - outs() << " Testing after loop extraction:\n"; - // Clone modules, the tester function will free them. - Module *TOLEBackup = CloneModule(ToOptimizeLoopExtracted); - Module *TNOBackup = CloneModule(ToNotOptimize); - Failure = TestFn(BD, ToOptimizeLoopExtracted, ToNotOptimize, Error); - if (!Error.empty()) - return false; - if (!Failure) { - outs() << "*** 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; - - outs() << "*** 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)){ - errs() << 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::string &); - std::vector<Function*> FunctionsBeingTested; - public: - ReduceMiscompiledBlocks(BugDriver &bd, - bool (*F)(BugDriver &, Module *, Module *, - std::string &), - const std::vector<Function*> &Fns) - : BD(bd), TestFn(F), FunctionsBeingTested(Fns) {} - - virtual TestResult doTest(std::vector<BasicBlock*> &Prefix, - std::vector<BasicBlock*> &Suffix, - std::string &Error) { - if (!Suffix.empty()) { - bool Ret = TestFuncs(Suffix, Error); - if (!Error.empty()) - return InternalError; - if (Ret) - return KeepSuffix; - } - if (!Prefix.empty()) { - bool Ret = TestFuncs(Prefix, Error); - if (!Error.empty()) - return InternalError; - if (Ret) - return KeepPrefix; - } - return NoFailure; - } - - bool TestFuncs(const std::vector<BasicBlock*> &BBs, std::string &Error); - }; -} - -/// 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, - std::string &Error) { - // Test to see if the function is misoptimized if we ONLY run it on the - // functions listed in Funcs. - outs() << "Checking to see if the program is misoptimized when all "; - if (!BBs.empty()) { - outs() << "but these " << BBs.size() << " blocks are extracted: "; - for (unsigned i = 0, e = BBs.size() < 10 ? BBs.size() : 10; i != e; ++i) - outs() << BBs[i]->getName() << " "; - if (BBs.size() > 10) outs() << "..."; - } else { - outs() << "blocks are extracted."; - } - outs() << '\n'; - - // Split the module into the two halves of the program we want. - ValueMap<const Value*, Value*> VMap; - Module *Clone = CloneModule(BD.getProgram(), VMap); - Module *Orig = BD.swapProgramIn(Clone); - std::vector<Function*> FuncsOnClone; - std::vector<BasicBlock*> BBsOnClone; - for (unsigned i = 0, e = FunctionsBeingTested.size(); i != e; ++i) { - Function *F = cast<Function>(VMap[FunctionsBeingTested[i]]); - FuncsOnClone.push_back(F); - } - for (unsigned i = 0, e = BBs.size(); i != e; ++i) { - BasicBlock *BB = cast<BasicBlock>(VMap[BBs[i]]); - BBsOnClone.push_back(BB); - } - VMap.clear(); - - Module *ToNotOptimize = CloneModule(BD.getProgram(), VMap); - Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize, - FuncsOnClone, - VMap); - - // 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(BBsOnClone, ToOptimize)) { - delete ToOptimize; - // Run the predicate, - // note that the predicate will delete both input modules. - bool Ret = TestFn(BD, New, ToNotOptimize, Error); - delete BD.swapProgramIn(Orig); - return Ret; - } - delete BD.swapProgramIn(Orig); - 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::string &), - std::vector<Function*> &MiscompiledFunctions, - std::string &Error) { - 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. - bool Ret = ReduceMiscompiledBlocks(BD, TestFn, MiscompiledFunctions) - .TestFuncs(std::vector<BasicBlock*>(), Error); - if (!Error.empty()) - return false; - if (Ret) { - Blocks.clear(); - } else { - ReduceMiscompiledBlocks(BD, TestFn, - MiscompiledFunctions).reduceList(Blocks, Error); - if (!Error.empty()) - return false; - if (Blocks.size() == OldSize) - return false; - } - - ValueMap<const Value*, Value*> VMap; - Module *ProgClone = CloneModule(BD.getProgram(), VMap); - Module *ToExtract = SplitFunctionsOutOfModule(ProgClone, - MiscompiledFunctions, - VMap); - Module *Extracted = BD.ExtractMappedBlocksFromModule(Blocks, ToExtract); - if (Extracted == 0) { - // Weird, extraction should have worked. - errs() << "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)) { - errs() << 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 *, - std::string &), - std::string &Error) { - // 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, - Error); - if (!Error.empty()) - return MiscompiledFunctions; - - outs() << "\n*** The following function" - << (MiscompiledFunctions.size() == 1 ? " is" : "s are") - << " being miscompiled: "; - PrintFunctionList(MiscompiledFunctions); - outs() << '\n'; - - // See if we can rip any loops out of the miscompiled functions and still - // trigger the problem. - - if (!BugpointIsInterrupted && !DisableLoopExtraction) { - bool Ret = ExtractLoops(BD, TestFn, MiscompiledFunctions, Error); - if (!Error.empty()) - return MiscompiledFunctions; - if (Ret) { - // Okay, we extracted some loops and the problem still appears. See if - // we can eliminate some of the created functions from being candidates. - DisambiguateGlobalSymbols(BD.getProgram()); - - // Do the reduction... - if (!BugpointIsInterrupted) - ReduceMiscompilingFunctions(BD, TestFn).reduceList(MiscompiledFunctions, - Error); - if (!Error.empty()) - return MiscompiledFunctions; - - outs() << "\n*** The following function" - << (MiscompiledFunctions.size() == 1 ? " is" : "s are") - << " being miscompiled: "; - PrintFunctionList(MiscompiledFunctions); - outs() << '\n'; - } - } - - if (!BugpointIsInterrupted && !DisableBlockExtraction) { - bool Ret = ExtractBlocks(BD, TestFn, MiscompiledFunctions, Error); - if (!Error.empty()) - return MiscompiledFunctions; - if (Ret) { - // Okay, we extracted some blocks and the problem still appears. See if - // we can eliminate some of the created functions from being candidates. - DisambiguateGlobalSymbols(BD.getProgram()); - - // Do the reduction... - ReduceMiscompilingFunctions(BD, TestFn).reduceList(MiscompiledFunctions, - Error); - if (!Error.empty()) - return MiscompiledFunctions; - - outs() << "\n*** The following function" - << (MiscompiledFunctions.size() == 1 ? " is" : "s are") - << " being miscompiled: "; - PrintFunctionList(MiscompiledFunctions); - outs() << '\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, - std::string &Error) { - // Run the optimization passes on ToOptimize, producing a transformed version - // of the functions being tested. - outs() << " Optimizing functions being tested: "; - Module *Optimized = BD.runPassesOn(Test, BD.getPassesToRun(), - /*AutoDebugCrashes*/true); - outs() << "done.\n"; - delete Test; - - outs() << " Checking to see if the merged program executes correctly: "; - bool Broken; - Module *New = TestMergedProgram(BD, Optimized, Safe, true, Error, Broken); - if (New) { - outs() << (Broken ? " nope.\n" : " yup.\n"); - // Delete the original and set the new program. - delete BD.swapProgramIn(New); - } - return Broken; -} - - -/// debugMiscompilation - This method is used when the passes selected are not -/// crashing, but the generated output is semantically different from the -/// input. -/// -void BugDriver::debugMiscompilation(std::string *Error) { - // Make sure something was miscompiled... - if (!BugpointIsInterrupted) - if (!ReduceMiscompilingPasses(*this).reduceList(PassesToRun, *Error)) { - if (Error->empty()) - errs() << "*** Optimized program matches reference output! No problem" - << " detected...\nbugpoint can't help you with your problem!\n"; - return; - } - - outs() << "\n*** Found miscompiling pass" - << (getPassesToRun().size() == 1 ? "" : "es") << ": " - << getPassesString(getPassesToRun()) << '\n'; - EmitProgressBitcode(Program, "passinput"); - - std::vector<Function *> MiscompiledFunctions = - DebugAMiscompilation(*this, TestOptimizer, *Error); - if (!Error->empty()) - return; - - // Output a bunch of bitcode files for the user... - outs() << "Outputting reduced bitcode files which expose the problem:\n"; - ValueMap<const Value*, Value*> VMap; - Module *ToNotOptimize = CloneModule(getProgram(), VMap); - Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize, - MiscompiledFunctions, - VMap); - - outs() << " Non-optimized portion: "; - EmitProgressBitcode(ToNotOptimize, "tonotoptimize", true); - delete ToNotOptimize; // Delete hacked module. - - outs() << " Portion that is input to optimizer: "; - EmitProgressBitcode(ToOptimize, "tooptimize"); - delete ToOptimize; // Delete hacked module. - - return; -} - -/// 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 = Function::Create(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 = Function::Create(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 = BasicBlock::Create(Safe->getContext(), "entry", newMain); - CallInst *call = CallInst::Create(oldMainProto, args.begin(), args.end(), - "", BB); - - // If the type of old function wasn't void, return value of call - ReturnInst::Create(Safe->getContext(), 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", - Type::getInt8PtrTy(Safe->getContext()), - Type::getInt8PtrTy(Safe->getContext()), - (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->isIntrinsic() /* 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->getContext(), F->getName()); - GlobalVariable *funcName = - new GlobalVariable(*Safe, InitArray->getType(), true /*isConstant*/, - GlobalValue::InternalLinkage, InitArray, - F->getName() + "_name"); - - // 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::getInt32Ty(F->getContext()))); - 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->getParent(), F->getType(), - false, GlobalValue::InternalLinkage, - NullPtr,F->getName()+".fpcache"); - - // Construct a new stub function that will re-route calls to F - const FunctionType *FuncTy = F->getFunctionType(); - Function *FuncWrapper = Function::Create(FuncTy, - GlobalValue::InternalLinkage, - F->getName() + "_wrapper", - F->getParent()); - BasicBlock *EntryBB = BasicBlock::Create(F->getContext(), - "entry", FuncWrapper); - BasicBlock *DoCallBB = BasicBlock::Create(F->getContext(), - "usecache", FuncWrapper); - BasicBlock *LookupBB = BasicBlock::Create(F->getContext(), - "lookupfp", FuncWrapper); - - // Check to see if we already looked up the value. - Value *CachedVal = new LoadInst(Cache, "fpcache", EntryBB); - Value *IsNull = new ICmpInst(*EntryBB, ICmpInst::ICMP_EQ, CachedVal, - NullPtr, "isNull"); - BranchInst::Create(LookupBB, DoCallBB, IsNull, EntryBB); - - // Resolve the call to function F via the JIT API: - // - // call resolver(GetElementPtr...) - CallInst *Resolver = - CallInst::Create(resolverFunc, ResolverArgs.begin(), - ResolverArgs.end(), "resolver", LookupBB); - - // Cast the result from the resolver to correctly-typed function. - CastInst *CastedResolver = - new BitCastInst(Resolver, - PointerType::getUnqual(F->getFunctionType()), - "resolverCast", LookupBB); - - // Save the value in our cache. - new StoreInst(CastedResolver, Cache, LookupBB); - BranchInst::Create(DoCallBB, LookupBB); - - PHINode *FuncPtr = PHINode::Create(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()->isVoidTy()) { - CallInst::Create(FuncPtr, Args.begin(), Args.end(), "", DoCallBB); - ReturnInst::Create(F->getContext(), DoCallBB); - } else { - CallInst *Call = CallInst::Create(FuncPtr, Args.begin(), Args.end(), - "retval", DoCallBB); - ReturnInst::Create(F->getContext(),Call, DoCallBB); - } - - // Use the wrapper function instead of the old function - F->replaceAllUsesWith(FuncWrapper); - } - } - } - } - - if (verifyModule(*Test) || verifyModule(*Safe)) { - errs() << "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, - std::string &Error) { - CleanupAndPrepareModules(BD, Test, Safe); - - sys::Path TestModuleBC("bugpoint.test.bc"); - std::string ErrMsg; - if (TestModuleBC.makeUnique(true, &ErrMsg)) { - errs() << BD.getToolName() << "Error making unique filename: " - << ErrMsg << "\n"; - exit(1); - } - if (BD.writeProgramToFile(TestModuleBC.str(), Test)) { - errs() << "Error writing bitcode to `" << TestModuleBC.str() - << "'\nExiting."; - exit(1); - } - delete Test; - - FileRemover TestModuleBCRemover(TestModuleBC, !SaveTemps); - - // Make the shared library - sys::Path SafeModuleBC("bugpoint.safe.bc"); - if (SafeModuleBC.makeUnique(true, &ErrMsg)) { - errs() << BD.getToolName() << "Error making unique filename: " - << ErrMsg << "\n"; - exit(1); - } - - if (BD.writeProgramToFile(SafeModuleBC.str(), Safe)) { - errs() << "Error writing bitcode to `" << SafeModuleBC.str() - << "'\nExiting."; - exit(1); - } - - FileRemover SafeModuleBCRemover(SafeModuleBC, !SaveTemps); - - std::string SharedObject = BD.compileSharedObject(SafeModuleBC.str(), Error); - if (!Error.empty()) - return false; - delete Safe; - - FileRemover SharedObjectRemover(sys::Path(SharedObject), !SaveTemps); - - // Run the code generator on the `Test' code, loading the shared library. - // The function returns whether or not the new output differs from reference. - bool Result = BD.diffProgram(BD.getProgram(), TestModuleBC.str(), - SharedObject, false, &Error); - if (!Error.empty()) - return false; - - if (Result) - errs() << ": still failing!\n"; - else - errs() << ": didn't fail.\n"; - - return Result; -} - - -/// debugCodeGenerator - debug errors in LLC, LLI, or CBE. -/// -bool BugDriver::debugCodeGenerator(std::string *Error) { - if ((void*)SafeInterpreter == (void*)Interpreter) { - std::string Result = executeProgramSafely(Program, "bugpoint.safe.out", - Error); - if (Error->empty()) { - outs() << "\n*** The \"safe\" i.e. 'known good' backend cannot match " - << "the reference diff. This may be due to a\n front-end " - << "bug or a bug in the original program, but this can also " - << "happen if bugpoint isn't running the program with the " - << "right flags or input.\n I left the result of executing " - << "the program with the \"safe\" backend in this file for " - << "you: '" - << Result << "'.\n"; - } - return true; - } - - DisambiguateGlobalSymbols(Program); - - std::vector<Function*> Funcs = DebugAMiscompilation(*this, TestCodeGenerator, - *Error); - if (!Error->empty()) - return true; - - // Split the module into the two halves of the program we want. - ValueMap<const Value*, Value*> VMap; - Module *ToNotCodeGen = CloneModule(getProgram(), VMap); - Module *ToCodeGen = SplitFunctionsOutOfModule(ToNotCodeGen, Funcs, VMap); - - // Condition the modules - CleanupAndPrepareModules(*this, ToCodeGen, ToNotCodeGen); - - sys::Path TestModuleBC("bugpoint.test.bc"); - std::string ErrMsg; - if (TestModuleBC.makeUnique(true, &ErrMsg)) { - errs() << getToolName() << "Error making unique filename: " - << ErrMsg << "\n"; - exit(1); - } - - if (writeProgramToFile(TestModuleBC.str(), ToCodeGen)) { - errs() << "Error writing bitcode to `" << TestModuleBC.str() - << "'\nExiting."; - exit(1); - } - delete ToCodeGen; - - // Make the shared library - sys::Path SafeModuleBC("bugpoint.safe.bc"); - if (SafeModuleBC.makeUnique(true, &ErrMsg)) { - errs() << getToolName() << "Error making unique filename: " - << ErrMsg << "\n"; - exit(1); - } - - if (writeProgramToFile(SafeModuleBC.str(), ToNotCodeGen)) { - errs() << "Error writing bitcode to `" << SafeModuleBC.str() - << "'\nExiting."; - exit(1); - } - std::string SharedObject = compileSharedObject(SafeModuleBC.str(), *Error); - if (!Error->empty()) - return true; - delete ToNotCodeGen; - - outs() << "You can reproduce the problem with the command line: \n"; - if (isExecutingJIT()) { - outs() << " lli -load " << SharedObject << " " << TestModuleBC.str(); - } else { - outs() << " llc " << TestModuleBC.str() << " -o " << TestModuleBC.str() - << ".s\n"; - outs() << " gcc " << SharedObject << " " << TestModuleBC.str() - << ".s -o " << TestModuleBC.str() << ".exe"; -#if defined (HAVE_LINK_R) - outs() << " -Wl,-R."; -#endif - outs() << "\n"; - outs() << " " << TestModuleBC.str() << ".exe"; - } - for (unsigned i = 0, e = InputArgv.size(); i != e; ++i) - outs() << " " << InputArgv[i]; - outs() << '\n'; - outs() << "The shared object was created with:\n llc -march=c " - << SafeModuleBC.str() << " -o temporary.c\n" - << " gcc -xc temporary.c -O2 -o " << SharedObject; - if (TargetTriple.getArch() == Triple::sparc) - outs() << " -G"; // Compile a shared library, `-G' for Sparc - else - outs() << " -fPIC -shared"; // `-shared' for Linux/X86, maybe others - - outs() << " -fno-strict-aliasing\n"; - - return false; -} diff --git a/contrib/llvm/tools/bugpoint/OptimizerDriver.cpp b/contrib/llvm/tools/bugpoint/OptimizerDriver.cpp deleted file mode 100644 index 3600ca6..0000000 --- a/contrib/llvm/tools/bugpoint/OptimizerDriver.cpp +++ /dev/null @@ -1,260 +0,0 @@ -//===- OptimizerDriver.cpp - Allow BugPoint to run passes safely ----------===// -// -// The LLVM Compiler Infrastructure -// -// This file 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/SystemUtils.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/System/Path.h" -#include "llvm/System/Program.h" - -#define DONT_GET_PLUGIN_LOADER_OPTION -#include "llvm/Support/PluginLoader.h" - -#include <fstream> -using namespace llvm; - -namespace llvm { - extern cl::opt<std::string> OutputPrefix; -} - -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); -} - -/// 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, - const Module *M) const { - std::string ErrInfo; - tool_output_file Out(Filename.c_str(), ErrInfo, - raw_fd_ostream::F_Binary); - if (ErrInfo.empty()) { - WriteBitcodeToFile(M, Out.os()); - Out.os().close(); - if (!Out.os().has_error()) { - Out.keep(); - return false; - } - } - Out.os().clear_error(); - return true; -} - - -/// EmitProgressBitcode - This function is used to output the current Program -/// to a file named "bugpoint-ID.bc". -/// -void BugDriver::EmitProgressBitcode(const Module *M, - const std::string &ID, - bool NoFlyer) const { - // 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 = OutputPrefix + "-" + ID + ".bc"; - if (writeProgramToFile(Filename, M)) { - errs() << "Error opening file '" << Filename << "' for writing!\n"; - return; - } - - outs() << "Emitted bitcode to '" << Filename << "'\n"; - if (NoFlyer || PassesToRun.empty()) return; - outs() << "\n*** You can reproduce the problem with: "; - if (UseValgrind) outs() << "valgrind "; - outs() << "opt " << Filename << " "; - outs() << getPassesString(PassesToRun) << "\n"; -} - -cl::opt<bool> SilencePasses("silence-passes", cl::desc("Suppress output of running passes (both stdout and stderr)")); - -static cl::list<std::string> OptArgs("opt-args", cl::Positional, - cl::desc("<opt arguments>..."), - cl::ZeroOrMore, cl::PositionalEatsArgs); - -/// 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 -/// outs() a single line message indicating whether compilation was successful -/// or failed. -/// -bool BugDriver::runPasses(Module *Program, - const std::vector<std::string> &Passes, - std::string &OutputFilename, bool DeleteOutput, - bool Quiet, unsigned NumExtraArgs, - const char * const *ExtraArgs) const { - // setup the output file name - outs().flush(); - sys::Path uniqueFilename(OutputPrefix + "-output.bc"); - std::string ErrMsg; - if (uniqueFilename.makeUnique(true, &ErrMsg)) { - errs() << getToolName() << ": Error making unique filename: " - << ErrMsg << "\n"; - return(1); - } - OutputFilename = uniqueFilename.str(); - - // set up the input file name - sys::Path inputFilename(OutputPrefix + "-input.bc"); - if (inputFilename.makeUnique(true, &ErrMsg)) { - errs() << getToolName() << ": Error making unique filename: " - << ErrMsg << "\n"; - return(1); - } - - std::string ErrInfo; - tool_output_file InFile(inputFilename.c_str(), ErrInfo, - raw_fd_ostream::F_Binary); - - - if (!ErrInfo.empty()) { - errs() << "Error opening bitcode file: " << inputFilename.str() << "\n"; - return 1; - } - WriteBitcodeToFile(Program, InFile.os()); - InFile.os().close(); - if (InFile.os().has_error()) { - errs() << "Error writing bitcode file: " << inputFilename.str() << "\n"; - InFile.os().clear_error(); - return 1; - } - InFile.keep(); - - // setup the child process' arguments - SmallVector<const char*, 8> Args; - sys::Path tool = FindExecutable("opt", getToolName(), (void*)"opt"); - std::string Opt = tool.str(); - if (UseValgrind) { - Args.push_back("valgrind"); - Args.push_back("--error-exitcode=1"); - Args.push_back("-q"); - Args.push_back(tool.c_str()); - } else - Args.push_back(Opt.c_str()); - - Args.push_back("-o"); - Args.push_back(OutputFilename.c_str()); - for (unsigned i = 0, e = OptArgs.size(); i != e; ++i) - Args.push_back(OptArgs[i].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<std::string>::const_iterator I = Passes.begin(), - E = Passes.end(); I != E; ++I ) - pass_args.push_back( std::string("-") + (*I) ); - for (std::vector<std::string>::const_iterator I = pass_args.begin(), - E = pass_args.end(); I != E; ++I ) - Args.push_back(I->c_str()); - Args.push_back(inputFilename.c_str()); - for (unsigned i = 0; i < NumExtraArgs; ++i) - Args.push_back(*ExtraArgs); - Args.push_back(0); - - DEBUG(errs() << "\nAbout to run:\t"; - for (unsigned i = 0, e = Args.size()-1; i != e; ++i) - errs() << " " << Args[i]; - errs() << "\n"; - ); - - sys::Path prog; - if (UseValgrind) - prog = sys::Program::FindProgramByName("valgrind"); - else - prog = tool; - - // Redirect stdout and stderr to nowhere if SilencePasses is given - sys::Path Nowhere; - const sys::Path *Redirects[3] = {0, &Nowhere, &Nowhere}; - - int result = sys::Program::ExecuteAndWait(prog, Args.data(), 0, - (SilencePasses ? Redirects : 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) - outs() << "Success!\n"; - else if (result > 0) - outs() << "Exited with error code '" << result << "'\n"; - else if (result < 0) { - if (result == -1) - outs() << "Execute failed: " << ErrMsg << "\n"; - else - outs() << "Crashed with signal #" << abs(result) << "\n"; - } - if (result & 0x01000000) - outs() << "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<std::string> &Passes, - bool AutoDebugCrashes, unsigned NumExtraArgs, - const char * const *ExtraArgs) { - std::string BitcodeResult; - if (runPasses(M, Passes, BitcodeResult, false/*delete*/, true/*quiet*/, - NumExtraArgs, ExtraArgs)) { - if (AutoDebugCrashes) { - errs() << " Error running this sequence of passes" - << " on the input program!\n"; - delete swapProgramIn(M); - EmitProgressBitcode(M, "pass-error", false); - exit(debugOptimizerCrash()); - } - return 0; - } - - Module *Ret = ParseInputFile(BitcodeResult, Context); - if (Ret == 0) { - errs() << 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/contrib/llvm/tools/bugpoint/ToolRunner.cpp b/contrib/llvm/tools/bugpoint/ToolRunner.cpp deleted file mode 100644 index 36dbe14..0000000 --- a/contrib/llvm/tools/bugpoint/ToolRunner.cpp +++ /dev/null @@ -1,883 +0,0 @@ -//===-- ToolRunner.cpp ----------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the interfaces described in the ToolRunner.h file. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "toolrunner" -#include "ToolRunner.h" -#include "llvm/System/Program.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/FileUtilities.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Config/config.h" // for HAVE_LINK_R -#include <fstream> -#include <sstream> -using namespace llvm; - -namespace llvm { - cl::opt<bool> - SaveTemps("save-temps", cl::init(false), cl::desc("Save temporary files")); -} - -namespace { - cl::opt<std::string> - RemoteClient("remote-client", - cl::desc("Remote execution client (rsh/ssh)")); - - cl::opt<std::string> - RemoteHost("remote-host", - cl::desc("Remote execution (rsh/ssh) host")); - - cl::opt<std::string> - RemotePort("remote-port", - cl::desc("Remote execution (rsh/ssh) port")); - - cl::opt<std::string> - RemoteUser("remote-user", - cl::desc("Remote execution (rsh/ssh) user id")); - - cl::opt<std::string> - RemoteExtra("remote-extra-options", - cl::desc("Remote execution (rsh/ssh) extra options")); -} - -/// 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 // For debug purposes - { - errs() << "RUN:"; - for (unsigned i = 0; Args[i]; ++i) - errs() << " " << Args[i]; - errs() << "\n"; - } -#endif - - return - sys::Program::ExecuteAndWait(ProgramPath, Args, 0, redirects, - NumSeconds, MemoryLimit); -} - -/// RunProgramRemotelyWithTimeout - This function runs the given program -/// remotely using the given remote client and the sys::Program::ExecuteAndWait. -/// Returns the remote program exit code or reports a remote client error if it -/// fails. Remote client is required to return 255 if it failed or program exit -/// code otherwise. -/// @see sys::Program::ExecuteAndWait -static int RunProgramRemotelyWithTimeout(const sys::Path &RemoteClientPath, - 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 // For debug purposes - { - errs() << "RUN:"; - for (unsigned i = 0; Args[i]; ++i) - errs() << " " << Args[i]; - errs() << "\n"; - } -#endif - - // Run the program remotely with the remote client - int ReturnCode = sys::Program::ExecuteAndWait(RemoteClientPath, Args, - 0, redirects, NumSeconds, MemoryLimit); - - // Has the remote client fail? - if (255 == ReturnCode) { - std::ostringstream OS; - OS << "\nError running remote client:\n "; - for (const char **Arg = Args; *Arg; ++Arg) - OS << " " << *Arg; - OS << "\n"; - - // The error message is in the output file, let's print it out from there. - std::ifstream ErrorFile(StdOutFile.c_str()); - if (ErrorFile) { - std::copy(std::istreambuf_iterator<char>(ErrorFile), - std::istreambuf_iterator<char>(), - std::ostreambuf_iterator<char>(OS)); - ErrorFile.close(); - } - - errs() << OS; - } - - return ReturnCode; -} - -static std::string ProcessFailure(sys::Path ProgPath, const char** Args, - unsigned Timeout = 0, - unsigned MemoryLimit = 0) { - 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("bugpoint.program_error_messages"); - std::string ErrMsg; - if (ErrorFilename.makeUnique(true, &ErrMsg)) { - errs() << "Error making unique filename: " << ErrMsg << "\n"; - exit(1); - } - RunProgramWithTimeout(ProgPath, Args, sys::Path(""), ErrorFilename, - ErrorFilename, Timeout, MemoryLimit); - // 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(); - return 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, - std::string *Error, - 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, - std::string *Error, - const std::vector<std::string> &GCCArgs, - const std::vector<std::string> &SharedLibs, - unsigned Timeout, - unsigned MemoryLimit) { - std::vector<const char*> LLIArgs; - LLIArgs.push_back(LLIPath.c_str()); - LLIArgs.push_back("-force-interpreter=true"); - - for (std::vector<std::string>::const_iterator i = SharedLibs.begin(), e = SharedLibs.end(); i != e; ++i) { - LLIArgs.push_back("-load"); - LLIArgs.push_back((*i).c_str()); - } - - // 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); - - outs() << "<lli>"; outs().flush(); - DEBUG(errs() << "\nAbout to run:\t"; - for (unsigned i=0, e = LLIArgs.size()-1; i != e; ++i) - errs() << " " << LLIArgs[i]; - errs() << "\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 char *Argv0, - std::string &Message, - const std::vector<std::string> *ToolArgs) { - std::string LLIPath = - FindExecutable("lli", Argv0, (void *)(intptr_t)&createLLI).str(); - 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; -} - -//===---------------------------------------------------------------------===// -// Custom execution command implementation of AbstractIntepreter interface -// -// Allows using a custom command for executing the bitcode, thus allows, -// for example, to invoke a cross compiler for code generation followed by -// a simulator that executes the generated binary. -namespace { - class CustomExecutor : public AbstractInterpreter { - std::string ExecutionCommand; - std::vector<std::string> ExecutorArgs; - public: - CustomExecutor( - const std::string &ExecutionCmd, std::vector<std::string> ExecArgs) : - ExecutionCommand(ExecutionCmd), ExecutorArgs(ExecArgs) {} - - virtual int ExecuteProgram(const std::string &Bitcode, - const std::vector<std::string> &Args, - const std::string &InputFile, - const std::string &OutputFile, - std::string *Error, - const std::vector<std::string> &GCCArgs, - const std::vector<std::string> &SharedLibs = - std::vector<std::string>(), - unsigned Timeout = 0, - unsigned MemoryLimit = 0); - }; -} - -int CustomExecutor::ExecuteProgram(const std::string &Bitcode, - const std::vector<std::string> &Args, - const std::string &InputFile, - const std::string &OutputFile, - std::string *Error, - const std::vector<std::string> &GCCArgs, - const std::vector<std::string> &SharedLibs, - unsigned Timeout, - unsigned MemoryLimit) { - - std::vector<const char*> ProgramArgs; - ProgramArgs.push_back(ExecutionCommand.c_str()); - - for (std::size_t i = 0; i < ExecutorArgs.size(); ++i) - ProgramArgs.push_back(ExecutorArgs.at(i).c_str()); - ProgramArgs.push_back(Bitcode.c_str()); - ProgramArgs.push_back(0); - - // 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()); - - return RunProgramWithTimeout( - sys::Path(ExecutionCommand), - &ProgramArgs[0], sys::Path(InputFile), sys::Path(OutputFile), - sys::Path(OutputFile), Timeout, MemoryLimit); -} - -// Custom execution environment create method, takes the execution command -// as arguments -AbstractInterpreter *AbstractInterpreter::createCustom( - std::string &Message, - const std::string &ExecCommandLine) { - - std::string Command = ""; - std::vector<std::string> Args; - std::string delimiters = " "; - - // Tokenize the ExecCommandLine to the command and the args to allow - // defining a full command line as the command instead of just the - // executed program. We cannot just pass the whole string after the command - // as a single argument because then program sees only a single - // command line argument (with spaces in it: "foo bar" instead - // of "foo" and "bar"). - - // code borrowed from: - // http://oopweb.com/CPP/Documents/CPPHOWTO/Volume/C++Programming-HOWTO-7.html - std::string::size_type lastPos = - ExecCommandLine.find_first_not_of(delimiters, 0); - std::string::size_type pos = - ExecCommandLine.find_first_of(delimiters, lastPos); - - while (std::string::npos != pos || std::string::npos != lastPos) { - std::string token = ExecCommandLine.substr(lastPos, pos - lastPos); - if (Command == "") - Command = token; - else - Args.push_back(token); - // Skip delimiters. Note the "not_of" - lastPos = ExecCommandLine.find_first_not_of(delimiters, pos); - // Find next "non-delimiter" - pos = ExecCommandLine.find_first_of(delimiters, lastPos); - } - - std::string CmdPath = sys::Program::FindProgramByName(Command).str(); - if (CmdPath.empty()) { - Message = - std::string("Cannot find '") + Command + - "' in executable directory or PATH!\n"; - return 0; - } - - Message = "Found command in: " + CmdPath + "\n"; - - return new CustomExecutor(CmdPath, Args); -} - -//===----------------------------------------------------------------------===// -// LLC Implementation of AbstractIntepreter interface -// -GCC::FileType LLC::OutputCode(const std::string &Bitcode, - sys::Path &OutputAsmFile, std::string &Error, - unsigned Timeout, unsigned MemoryLimit) { - const char *Suffix = (UseIntegratedAssembler ? ".llc.o" : ".llc.s"); - sys::Path uniqueFile(Bitcode + Suffix); - std::string ErrMsg; - if (uniqueFile.makeUnique(true, &ErrMsg)) { - errs() << "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(Bitcode.c_str()); // This is the input bitcode - - if (UseIntegratedAssembler) - LLCArgs.push_back("-filetype=obj"); - - LLCArgs.push_back (0); - - outs() << (UseIntegratedAssembler ? "<llc-ia>" : "<llc>"); - outs().flush(); - DEBUG(errs() << "\nAbout to run:\t"; - for (unsigned i = 0, e = LLCArgs.size()-1; i != e; ++i) - errs() << " " << LLCArgs[i]; - errs() << "\n"; - ); - if (RunProgramWithTimeout(sys::Path(LLCPath), &LLCArgs[0], - sys::Path(), sys::Path(), sys::Path(), - Timeout, MemoryLimit)) - Error = ProcessFailure(sys::Path(LLCPath), &LLCArgs[0], - Timeout, MemoryLimit); - return UseIntegratedAssembler ? GCC::ObjectFile : GCC::AsmFile; -} - -void LLC::compileProgram(const std::string &Bitcode, std::string *Error, - unsigned Timeout, unsigned MemoryLimit) { - sys::Path OutputAsmFile; - OutputCode(Bitcode, OutputAsmFile, *Error, Timeout, MemoryLimit); - OutputAsmFile.eraseFromDisk(); -} - -int LLC::ExecuteProgram(const std::string &Bitcode, - const std::vector<std::string> &Args, - const std::string &InputFile, - const std::string &OutputFile, - std::string *Error, - const std::vector<std::string> &ArgsForGCC, - const std::vector<std::string> &SharedLibs, - unsigned Timeout, - unsigned MemoryLimit) { - - sys::Path OutputAsmFile; - GCC::FileType FileKind = OutputCode(Bitcode, OutputAsmFile, *Error, Timeout, - MemoryLimit); - FileRemover OutFileRemover(OutputAsmFile, !SaveTemps); - - 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.str(), Args, FileKind, - InputFile, OutputFile, Error, GCCArgs, - Timeout, MemoryLimit); -} - -/// createLLC - Try to find the LLC executable -/// -LLC *AbstractInterpreter::createLLC(const char *Argv0, - std::string &Message, - const std::string &GCCBinary, - const std::vector<std::string> *Args, - const std::vector<std::string> *GCCArgs, - bool UseIntegratedAssembler) { - std::string LLCPath = - FindExecutable("llc", Argv0, (void *)(intptr_t)&createLLC).str(); - if (LLCPath.empty()) { - Message = "Cannot find `llc' in executable directory or PATH!\n"; - return 0; - } - - Message = "Found llc: " + LLCPath + "\n"; - GCC *gcc = GCC::create(Message, GCCBinary, GCCArgs); - if (!gcc) { - errs() << Message << "\n"; - exit(1); - } - return new LLC(LLCPath, gcc, Args, UseIntegratedAssembler); -} - -//===---------------------------------------------------------------------===// -// 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, - std::string *Error, - 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, - std::string *Error, - const std::vector<std::string> &GCCArgs, - const std::vector<std::string> &SharedLibs, - unsigned Timeout, - unsigned MemoryLimit) { - // 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); - - outs() << "<jit>"; outs().flush(); - DEBUG(errs() << "\nAbout to run:\t"; - for (unsigned i=0, e = JITArgs.size()-1; i != e; ++i) - errs() << " " << JITArgs[i]; - errs() << "\n"; - ); - DEBUG(errs() << "\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 char *Argv0, - std::string &Message, const std::vector<std::string> *Args) { - std::string LLIPath = - FindExecutable("lli", Argv0, (void *)(intptr_t)&createJIT).str(); - 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, std::string &Error, - unsigned Timeout, unsigned MemoryLimit) { - sys::Path uniqueFile(Bitcode+".cbe.c"); - std::string ErrMsg; - if (uniqueFile.makeUnique(true, &ErrMsg)) { - errs() << "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(Bitcode.c_str()); // This is the input bitcode - LLCArgs.push_back(0); - - outs() << "<cbe>"; outs().flush(); - DEBUG(errs() << "\nAbout to run:\t"; - for (unsigned i = 0, e = LLCArgs.size()-1; i != e; ++i) - errs() << " " << LLCArgs[i]; - errs() << "\n"; - ); - if (RunProgramWithTimeout(LLCPath, &LLCArgs[0], sys::Path(), sys::Path(), - sys::Path(), Timeout, MemoryLimit)) - Error = ProcessFailure(LLCPath, &LLCArgs[0], Timeout, MemoryLimit); - return GCC::CFile; -} - -void CBE::compileProgram(const std::string &Bitcode, std::string *Error, - unsigned Timeout, unsigned MemoryLimit) { - sys::Path OutputCFile; - OutputCode(Bitcode, OutputCFile, *Error, Timeout, MemoryLimit); - OutputCFile.eraseFromDisk(); -} - -int CBE::ExecuteProgram(const std::string &Bitcode, - const std::vector<std::string> &Args, - const std::string &InputFile, - const std::string &OutputFile, - std::string *Error, - const std::vector<std::string> &ArgsForGCC, - const std::vector<std::string> &SharedLibs, - unsigned Timeout, - unsigned MemoryLimit) { - sys::Path OutputCFile; - OutputCode(Bitcode, OutputCFile, *Error, Timeout, MemoryLimit); - - FileRemover CFileRemove(OutputCFile, !SaveTemps); - - std::vector<std::string> GCCArgs(ArgsForGCC); - GCCArgs.insert(GCCArgs.end(), SharedLibs.begin(), SharedLibs.end()); - - return gcc->ExecuteProgram(OutputCFile.str(), Args, GCC::CFile, - InputFile, OutputFile, Error, GCCArgs, - Timeout, MemoryLimit); -} - -/// createCBE - Try to find the 'llc' executable -/// -CBE *AbstractInterpreter::createCBE(const char *Argv0, - std::string &Message, - const std::string &GCCBinary, - const std::vector<std::string> *Args, - const std::vector<std::string> *GCCArgs) { - sys::Path LLCPath = - FindExecutable("llc", Argv0, (void *)(intptr_t)&createCBE); - if (LLCPath.isEmpty()) { - Message = - "Cannot find `llc' in executable directory or PATH!\n"; - return 0; - } - - Message = "Found llc: " + LLCPath.str() + "\n"; - GCC *gcc = GCC::create(Message, GCCBinary, GCCArgs); - if (!gcc) { - errs() << Message << "\n"; - exit(1); - } - return new CBE(LLCPath, gcc, Args); -} - -//===---------------------------------------------------------------------===// -// GCC abstraction -// - -static bool IsARMArchitecture(std::vector<const char*> Args) { - for (std::vector<const char*>::const_iterator - I = Args.begin(), E = Args.end(); I != E; ++I) { - if (StringRef(*I).equals_lower("-arch")) { - ++I; - if (I != E && StringRef(*I).substr(0, strlen("arm")).equals_lower("arm")) - return true; - } - } - - return false; -} - -int GCC::ExecuteProgram(const std::string &ProgramFile, - const std::vector<std::string> &Args, - FileType fileType, - const std::string &InputFile, - const std::string &OutputFile, - std::string *Error, - const std::vector<std::string> &ArgsForGCC, - unsigned Timeout, - unsigned MemoryLimit) { - std::vector<const char*> GCCArgs; - - GCCArgs.push_back(GCCPath.c_str()); - - if (TargetTriple.getArch() == Triple::x86) - GCCArgs.push_back("-m32"); - - for (std::vector<std::string>::const_iterator - I = gccArgs.begin(), E = gccArgs.end(); I != E; ++I) - GCCArgs.push_back(I->c_str()); - - // Specify -x explicitly in case the extension is wonky - if (fileType != ObjectFile) { - GCCArgs.push_back("-x"); - if (fileType == CFile) { - GCCArgs.push_back("c"); - GCCArgs.push_back("-fno-strict-aliasing"); - } else { - GCCArgs.push_back("assembler"); - - // For ARM architectures we don't want this flag. bugpoint isn't - // explicitly told what architecture it is working on, so we get - // it from gcc flags - if ((TargetTriple.getOS() == Triple::Darwin) && - !IsARMArchitecture(GCCArgs)) - GCCArgs.push_back("-force_cpusubtype_ALL"); - } - } - - 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)) { - errs() << "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 - if (TargetTriple.getArch() == Triple::sparc) - GCCArgs.push_back("-mcpu=v9"); - GCCArgs.push_back(0); // NULL terminator - - outs() << "<gcc>"; outs().flush(); - DEBUG(errs() << "\nAbout to run:\t"; - for (unsigned i = 0, e = GCCArgs.size()-1; i != e; ++i) - errs() << " " << GCCArgs[i]; - errs() << "\n"; - ); - if (RunProgramWithTimeout(GCCPath, &GCCArgs[0], sys::Path(), sys::Path(), - sys::Path())) { - *Error = ProcessFailure(GCCPath, &GCCArgs[0]); - return -1; - } - - std::vector<const char*> ProgramArgs; - - // Declared here so that the destructor only runs after - // ProgramArgs is used. - std::string Exec; - - if (RemoteClientPath.isEmpty()) - ProgramArgs.push_back(OutputBinary.c_str()); - else { - ProgramArgs.push_back(RemoteClientPath.c_str()); - ProgramArgs.push_back(RemoteHost.c_str()); - if (!RemoteUser.empty()) { - ProgramArgs.push_back("-l"); - ProgramArgs.push_back(RemoteUser.c_str()); - } - if (!RemotePort.empty()) { - ProgramArgs.push_back("-p"); - ProgramArgs.push_back(RemotePort.c_str()); - } - if (!RemoteExtra.empty()) { - ProgramArgs.push_back(RemoteExtra.c_str()); - } - - // Full path to the binary. We need to cd to the exec directory because - // there is a dylib there that the exec expects to find in the CWD - char* env_pwd = getenv("PWD"); - 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! - outs() << "<program>"; outs().flush(); - DEBUG(errs() << "\nAbout to run:\t"; - for (unsigned i = 0, e = ProgramArgs.size()-1; i != e; ++i) - errs() << " " << ProgramArgs[i]; - errs() << "\n"; - ); - - FileRemover OutputBinaryRemover(OutputBinary, !SaveTemps); - - if (RemoteClientPath.isEmpty()) { - DEBUG(errs() << "<run locally>"); - return RunProgramWithTimeout(OutputBinary, &ProgramArgs[0], - sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile), - Timeout, MemoryLimit); - } else { - outs() << "<run remotely>"; outs().flush(); - return RunProgramRemotelyWithTimeout(sys::Path(RemoteClientPath), - &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, - std::string &Error) { - sys::Path uniqueFilename(InputFile+LTDL_SHLIB_EXT); - std::string ErrMsg; - if (uniqueFilename.makeUnique(true, &ErrMsg)) { - errs() << "Error making unique filename: " << ErrMsg << "\n"; - exit(1); - } - OutputFile = uniqueFilename.str(); - - std::vector<const char*> GCCArgs; - - GCCArgs.push_back(GCCPath.c_str()); - - if (TargetTriple.getArch() == Triple::x86) - GCCArgs.push_back("-m32"); - - for (std::vector<std::string>::const_iterator - I = gccArgs.begin(), E = gccArgs.end(); I != E; ++I) - GCCArgs.push_back(I->c_str()); - - // Compile the C/asm file into a shared object - if (fileType != ObjectFile) { - 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 (TargetTriple.getArch() == Triple::sparc) - GCCArgs.push_back("-G"); // Compile a shared library, `-G' for Sparc - else if (TargetTriple.getOS() == Triple::Darwin) { - // 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 - - if ((TargetTriple.getArch() == Triple::alpha) || - (TargetTriple.getArch() == Triple::x86_64)) - GCCArgs.push_back("-fPIC"); // Requires shared objs to contain PIC - - if (TargetTriple.getArch() == Triple::sparc) - GCCArgs.push_back("-mcpu=v9"); - - 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 - - - - outs() << "<gcc>"; outs().flush(); - DEBUG(errs() << "\nAbout to run:\t"; - for (unsigned i = 0, e = GCCArgs.size()-1; i != e; ++i) - errs() << " " << GCCArgs[i]; - errs() << "\n"; - ); - if (RunProgramWithTimeout(GCCPath, &GCCArgs[0], sys::Path(), sys::Path(), - sys::Path())) { - Error = ProcessFailure(GCCPath, &GCCArgs[0]); - return 1; - } - return 0; -} - -/// create - Try to find the `gcc' executable -/// -GCC *GCC::create(std::string &Message, - const std::string &GCCBinary, - const std::vector<std::string> *Args) { - sys::Path GCCPath = sys::Program::FindProgramByName(GCCBinary); - if (GCCPath.isEmpty()) { - Message = "Cannot find `"+ GCCBinary +"' in executable directory or PATH!\n"; - return 0; - } - - sys::Path RemoteClientPath; - if (!RemoteClient.empty()) - RemoteClientPath = sys::Program::FindProgramByName(RemoteClient); - - Message = "Found gcc: " + GCCPath.str() + "\n"; - return new GCC(GCCPath, RemoteClientPath, Args); -} diff --git a/contrib/llvm/tools/bugpoint/ToolRunner.h b/contrib/llvm/tools/bugpoint/ToolRunner.h deleted file mode 100644 index cda0ddf..0000000 --- a/contrib/llvm/tools/bugpoint/ToolRunner.h +++ /dev/null @@ -1,242 +0,0 @@ -//===-- tools/bugpoint/ToolRunner.h -----------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file 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/ADT/Triple.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/SystemUtils.h" -#include "llvm/System/Path.h" -#include <exception> -#include <vector> - -namespace llvm { - -extern cl::opt<bool> SaveTemps; -extern Triple TargetTriple; - -class CBE; -class LLC; - -//===---------------------------------------------------------------------===// -// GCC abstraction -// -class GCC { - sys::Path GCCPath; // The path to the gcc executable. - sys::Path RemoteClientPath; // The path to the rsh / ssh executable. - std::vector<std::string> gccArgs; // GCC-specific arguments. - GCC(const sys::Path &gccPath, const sys::Path &RemotePath, - const std::vector<std::string> *GCCArgs) - : GCCPath(gccPath), RemoteClientPath(RemotePath) { - if (GCCArgs) gccArgs = *GCCArgs; - } -public: - enum FileType { AsmFile, ObjectFile, CFile }; - - static GCC *create(std::string &Message, - const std::string &GCCBinary, - const std::vector<std::string> *Args); - - /// 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, - std::string *Error = 0, - 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, - std::string &Error); -}; - - -//===---------------------------------------------------------------------===// -/// 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 char *Argv0, std::string &Message, - const std::string &GCCBinary, - const std::vector<std::string> *Args = 0, - const std::vector<std::string> *GCCArgs = 0); - static LLC *createLLC(const char *Argv0, std::string &Message, - const std::string &GCCBinary, - const std::vector<std::string> *Args = 0, - const std::vector<std::string> *GCCArgs = 0, - bool UseIntegratedAssembler = false); - - static AbstractInterpreter* createLLI(const char *Argv0, std::string &Message, - const std::vector<std::string> *Args=0); - - static AbstractInterpreter* createJIT(const char *Argv0, std::string &Message, - const std::vector<std::string> *Args=0); - - static AbstractInterpreter* createCustom(std::string &Message, - const std::string &ExecCommandLine); - - - 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. It returns false if the code generator fails. - virtual void compileProgram(const std::string &Bitcode, std::string *Error, - 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, it sets Error, otherwise, this function returns the type of code - /// emitted. - virtual GCC::FileType OutputCode(const std::string &Bitcode, - sys::Path &OutFile, std::string &Error, - unsigned Timeout = 0, - unsigned MemoryLimit = 0) { - Error = "OutputCode not supported by this AbstractInterpreter!"; - return GCC::AsmFile; - } - - /// ExecuteProgram - Run the specified bitcode file, emitting output to the - /// specified filename. This sets RetVal to the exit code of the program or - /// returns false if a problem was encountered that prevented execution of - /// the program. - /// - virtual int ExecuteProgram(const std::string &Bitcode, - const std::vector<std::string> &Args, - const std::string &InputFile, - const std::string &OutputFile, - std::string *Error, - 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. Returns false if the code generator fails. - virtual void compileProgram(const std::string &Bitcode, std::string *Error, - unsigned Timeout = 0, unsigned MemoryLimit = 0); - - virtual int ExecuteProgram(const std::string &Bitcode, - const std::vector<std::string> &Args, - const std::string &InputFile, - const std::string &OutputFile, - std::string *Error, - 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, it sets Error, otherwise, this function returns the type of code - /// emitted. - virtual GCC::FileType OutputCode(const std::string &Bitcode, - sys::Path &OutFile, std::string &Error, - unsigned Timeout = 0, - unsigned MemoryLimit = 0); -}; - - -//===---------------------------------------------------------------------===// -// 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; - bool UseIntegratedAssembler; -public: - LLC(const std::string &llcPath, GCC *Gcc, - const std::vector<std::string> *Args, - bool useIntegratedAssembler) - : LLCPath(llcPath), gcc(Gcc), - UseIntegratedAssembler(useIntegratedAssembler) { - 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. Returns false if the code generator fails. - virtual void compileProgram(const std::string &Bitcode, std::string *Error, - unsigned Timeout = 0, unsigned MemoryLimit = 0); - - virtual int ExecuteProgram(const std::string &Bitcode, - const std::vector<std::string> &Args, - const std::string &InputFile, - const std::string &OutputFile, - std::string *Error, - 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, it sets Error, otherwise, this function returns the type of code - /// emitted. - virtual GCC::FileType OutputCode(const std::string &Bitcode, - sys::Path &OutFile, std::string &Error, - unsigned Timeout = 0, - unsigned MemoryLimit = 0); -}; - -} // End llvm namespace - -#endif diff --git a/contrib/llvm/tools/bugpoint/bugpoint.cpp b/contrib/llvm/tools/bugpoint/bugpoint.cpp deleted file mode 100644 index 79cf563..0000000 --- a/contrib/llvm/tools/bugpoint/bugpoint.cpp +++ /dev/null @@ -1,159 +0,0 @@ -//===- bugpoint.cpp - The LLVM Bugpoint utility ---------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file 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/LLVMContext.h" -#include "llvm/Support/PassNameParser.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/PluginLoader.h" -#include "llvm/Support/PrettyStackTrace.h" -#include "llvm/Support/StandardPasses.h" -#include "llvm/System/Process.h" -#include "llvm/System/Signals.h" -#include "llvm/System/Valgrind.h" -#include "llvm/LinkAllVMCore.h" -using namespace llvm; - -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<int> -MemoryLimit("mlimit", cl::init(-1), cl::value_desc("MBytes"), - cl::desc("Maximum amount of memory to use. 0 disables check." - " Defaults to 100MB (800MB under valgrind).")); - -static cl::opt<bool> -UseValgrind("enable-valgrind", - cl::desc("Run optimizations through valgrind")); - -// 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); - -static cl::opt<bool> -StandardCompileOpts("std-compile-opts", - cl::desc("Include the standard compile time optimizations")); - -static cl::opt<bool> -StandardLinkOpts("std-link-opts", - cl::desc("Include the standard link time optimizations")); - -static cl::opt<std::string> -OverrideTriple("mtriple", cl::desc("Override target triple for module")); - -/// BugpointIsInterrupted - Set to true when the user presses ctrl-c. -bool llvm::BugpointIsInterrupted = false; - -static void BugpointInterruptFunction() { - BugpointIsInterrupted = true; -} - -// Hack to capture a pass list. -namespace { - class AddToDriver : public PassManager { - BugDriver &D; - public: - AddToDriver(BugDriver &_D) : D(_D) {} - - virtual void add(Pass *P) { - const void *ID = P->getPassID(); - const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(ID); - D.addPass(PI->getPassArgument()); - } - }; -} - -int main(int argc, char **argv) { - llvm::sys::PrintStackTraceOnErrorSignal(); - llvm::PrettyStackTraceProgram X(argc, argv); - llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. - cl::ParseCommandLineOptions(argc, argv, - "LLVM automatic testcase reducer. See\nhttp://" - "llvm.org/cmds/bugpoint.html" - " for more information.\n"); - sys::SetInterruptFunction(BugpointInterruptFunction); - - LLVMContext& Context = getGlobalContext(); - // If we have an override, set it and then track the triple we want Modules - // to use. - if (!OverrideTriple.empty()) { - TargetTriple.setTriple(Triple::normalize(OverrideTriple)); - outs() << "Override triple set to '" << TargetTriple.getTriple() << "'\n"; - } - - if (MemoryLimit < 0) { - // Set the default MemoryLimit. Be sure to update the flag's description if - // you change this. - if (sys::RunningOnValgrind() || UseValgrind) - MemoryLimit = 800; - else - MemoryLimit = 100; - } - - BugDriver D(argv[0], FindBugs, TimeoutValue, MemoryLimit, - UseValgrind, Context); - if (D.addSources(InputFilenames)) return 1; - - AddToDriver PM(D); - if (StandardCompileOpts) { - createStandardModulePasses(&PM, 3, - /*OptimizeSize=*/ false, - /*UnitAtATime=*/ true, - /*UnrollLoops=*/ true, - /*SimplifyLibCalls=*/ true, - /*HaveExceptions=*/ true, - createFunctionInliningPass()); - } - - if (StandardLinkOpts) - createStandardLTOPasses(&PM, /*Internalize=*/true, - /*RunInliner=*/true, - /*VerifyEach=*/false); - - - for (std::vector<const PassInfo*>::iterator I = PassList.begin(), - E = PassList.end(); - I != E; ++I) { - const PassInfo* PI = *I; - D.addPass(PI->getPassArgument()); - } - - // Bugpoint has the ability of generating a plethora of core files, so to - // avoid filling up the disk, we prevent it - sys::Process::PreventCoreFiles(); - - std::string Error; - bool Failure = D.run(Error); - if (!Error.empty()) { - errs() << Error; - return 1; - } - return Failure; -} diff --git a/contrib/llvm/tools/clang/CMakeLists.txt b/contrib/llvm/tools/clang/CMakeLists.txt deleted file mode 100644 index 1ba2a62..0000000 --- a/contrib/llvm/tools/clang/CMakeLists.txt +++ /dev/null @@ -1,152 +0,0 @@ -# Clang version information - -set(CLANG_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) -set(CLANG_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) - -if( CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR AND NOT MSVC_IDE ) - message(FATAL_ERROR "In-source builds are not allowed. CMake would overwrite " -"the makefiles distributed with LLVM. Please create a directory and run cmake " -"from there, passing the path to this source directory as the last argument. " -"This process created the file `CMakeCache.txt' and the directory " -"`CMakeFiles'. Please delete them.") -endif() - -if( NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR ) - file(GLOB_RECURSE - tablegenned_files_on_include_dir - "${CLANG_SOURCE_DIR}/include/clang/*.inc") - if( tablegenned_files_on_include_dir ) - message(FATAL_ERROR "Apparently there is a previous in-source build, " -"probably as the result of running `configure' and `make' on " -"${CLANG_SOURCE_DIR}. This may cause problems. The suspicious files are:\n" -"${tablegenned_files_on_include_dir}\nPlease clean the source directory.") - endif() -endif() - -# Compute the Clang version from the LLVM version. -string(REGEX MATCH "[0-9]+\\.[0-9]+(\\.[0-9]+)?" CLANG_VERSION - ${PACKAGE_VERSION}) -message(STATUS "Clang version: ${CLANG_VERSION}") - -string(REGEX REPLACE "([0-9]+)\\.[0-9]+(\\.[0-9]+)?" "\\1" CLANG_VERSION_MAJOR - ${CLANG_VERSION}) -string(REGEX REPLACE "[0-9]+\\.([0-9]+)(\\.[0-9]+)?" "\\1" CLANG_VERSION_MINOR - ${CLANG_VERSION}) -if (${CLANG_VERSION} MATCHES "[0-9]+\\.[0-9]+\\.[0-9]+") - set(CLANG_HAS_VERSION_PATCHLEVEL 1) - string(REGEX REPLACE "[0-9]+\\.[0-9]+\\.([0-9]+)" "\\1" CLANG_VERSION_PATCHLEVEL - ${CLANG_VERSION}) -else() - set(CLANG_HAS_VERSION_PATCHLEVEL 0) -endif() - -# Configure the Version.inc file. -configure_file( - ${CMAKE_CURRENT_SOURCE_DIR}/include/clang/Basic/Version.inc.in - ${CMAKE_CURRENT_BINARY_DIR}/include/clang/Basic/Version.inc) - -# Add appropriate flags for GCC -if (CMAKE_COMPILER_IS_GNUCXX) - # FIXME: Turn off exceptions, RTTI: - # -fno-exceptions -fno-rtti - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-common -Woverloaded-virtual -pedantic -Wno-long-long -Wall -W -Wno-unused-parameter -Wwrite-strings") -endif () - -if (APPLE) - set(CMAKE_MODULE_LINKER_FLAGS "-Wl,-flat_namespace -Wl,-undefined -Wl,suppress") -endif () - -macro(add_clang_library name) - set(srcs ${ARGN}) - if(MSVC_IDE OR XCODE) - file( GLOB_RECURSE headers *.h *.td *.def) - set(srcs ${srcs} ${headers}) - string( REGEX MATCHALL "/[^/]+" split_path ${CMAKE_CURRENT_SOURCE_DIR}) - list( GET split_path -1 dir) - file( GLOB_RECURSE headers - ../../include/clang${dir}/*.h - ../../include/clang${dir}/*.td - ../../include/clang${dir}/*.def) - set(srcs ${srcs} ${headers}) - endif(MSVC_IDE OR XCODE) - if (MODULE) - set(libkind MODULE) - elseif (SHARED_LIBRARY) - set(libkind SHARED) - else() - set(libkind) - endif() - add_library( ${name} ${libkind} ${srcs} ) - if( LLVM_COMMON_DEPENDS ) - add_dependencies( ${name} ${LLVM_COMMON_DEPENDS} ) - endif( LLVM_COMMON_DEPENDS ) - if( LLVM_USED_LIBS ) - foreach(lib ${LLVM_USED_LIBS}) - target_link_libraries( ${name} ${lib} ) - endforeach(lib) - endif( LLVM_USED_LIBS ) - if( LLVM_LINK_COMPONENTS ) - llvm_config(${name} ${LLVM_LINK_COMPONENTS}) - endif( LLVM_LINK_COMPONENTS ) - get_system_libs(llvm_system_libs) - if( llvm_system_libs ) - target_link_libraries(${name} ${llvm_system_libs}) - endif( llvm_system_libs ) - add_dependencies(${name} ClangDiagnosticCommon) - if(MSVC) - get_target_property(cflag ${name} COMPILE_FLAGS) - if(NOT cflag) - set(cflag "") - endif(NOT cflag) - set(cflag "${cflag} /Za") - set_target_properties(${name} PROPERTIES COMPILE_FLAGS ${cflag}) - endif(MSVC) - install(TARGETS ${name} - LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX} - ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX}) -endmacro(add_clang_library) - -macro(add_clang_executable name) - set(srcs ${ARGN}) - if(MSVC_IDE) - file( GLOB_RECURSE headers *.h *.td *.def) - set(srcs ${srcs} ${headers}) - endif(MSVC_IDE) - add_llvm_executable( ${name} ${srcs} ) -endmacro(add_clang_executable) - -include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/include - ${CMAKE_CURRENT_BINARY_DIR}/include - ) - -install(DIRECTORY include/ - DESTINATION include - FILES_MATCHING - PATTERN "*.def" - PATTERN "*.h" - PATTERN "*.td" - PATTERN ".svn" EXCLUDE - ) - -install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/ - DESTINATION include - FILES_MATCHING - PATTERN "CMakeFiles" EXCLUDE - PATTERN "*.inc" - ) - -add_definitions( -D_GNU_SOURCE ) - -option(CLANG_BUILD_EXAMPLES "Build CLANG example programs." OFF) -if(CLANG_BUILD_EXAMPLES) - add_subdirectory(examples) -endif () - -add_subdirectory(include) -add_subdirectory(lib) -add_subdirectory(tools) - -# TODO: docs. -add_subdirectory(test) - diff --git a/contrib/llvm/tools/clang/INSTALL.txt b/contrib/llvm/tools/clang/INSTALL.txt deleted file mode 100644 index e8e3209..0000000 --- a/contrib/llvm/tools/clang/INSTALL.txt +++ /dev/null @@ -1,49 +0,0 @@ -//===----------------------------------------------------------------------===// -// Clang Installation Instructions -//===----------------------------------------------------------------------===// - -These instructions describe how to build and install Clang. - -//===----------------------------------------------------------------------===// -// Step 1: Organization -//===----------------------------------------------------------------------===// - -Clang is designed to be built as part of an LLVM build. Assuming that the LLVM -source code is located at $LLVM_SRC_ROOT, then the clang source code should be -installed as: - - $LLVM_SRC_ROOT/tools/clang - -The directory is not required to be called clang, but doing so will allow the -LLVM build system to automatically recognize it and build it along with LLVM. - -//===----------------------------------------------------------------------===// -// Step 2: Configure and Build LLVM -//===----------------------------------------------------------------------===// - -Configure and build your copy of LLVM (see $LLVM_SRC_ROOT/GettingStarted.html -for more information). - -Assuming you installed clang at $LLVM_SRC_ROOT/tools/clang then Clang will -automatically be built with LLVM. Otherwise, run 'make' in the Clang source -directory to build Clang. - -//===----------------------------------------------------------------------===// -// Step 3: (Optional) Verify Your Build -//===----------------------------------------------------------------------===// - -It is a good idea to run the Clang tests to make sure your build works -correctly. From inside the Clang build directory, run 'make test' to run the -tests. - -//===----------------------------------------------------------------------===// -// Step 4: Install Clang -//===----------------------------------------------------------------------===// - -From inside the Clang build directory, run 'make install' to install the Clang -compiler and header files into the prefix directory selected when LLVM was -configured. - -The Clang compiler is available as 'clang' and supports a gcc like command line -interface. See the man page for clang (installed into $prefix/share/man/man1) -for more information. diff --git a/contrib/llvm/tools/clang/LICENSE.TXT b/contrib/llvm/tools/clang/LICENSE.TXT deleted file mode 100644 index a378a5f..0000000 --- a/contrib/llvm/tools/clang/LICENSE.TXT +++ /dev/null @@ -1,63 +0,0 @@ -============================================================================== -LLVM Release License -============================================================================== -University of Illinois/NCSA -Open Source License - -Copyright (c) 2007-2010 University of Illinois at Urbana-Champaign. -All rights reserved. - -Developed by: - - LLVM Team - - University of Illinois at Urbana-Champaign - - http://llvm.org - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal with -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimers. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimers in the - documentation and/or other materials provided with the distribution. - - * Neither the names of the LLVM Team, University of Illinois at - Urbana-Champaign, nor the names of its contributors may be used to - endorse or promote products derived from this Software without specific - prior written permission. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE -SOFTWARE. - -============================================================================== -The LLVM software contains code written by third parties. Such software will -have its own individual LICENSE.TXT file in the directory in which it appears. -This file will describe the copyrights, license, and restrictions which apply -to that code. - -The disclaimer of warranty in the University of Illinois Open Source License -applies to all code in the LLVM Distribution, and nothing in any of the -other licenses gives permission to use the names of the LLVM Team or the -University of Illinois to endorse or promote products derived from this -Software. - -The following pieces of software have additional or alternate copyrights, -licenses, and/or restrictions: - -Program Directory -------- --------- -<none yet> - diff --git a/contrib/llvm/tools/clang/Makefile b/contrib/llvm/tools/clang/Makefile deleted file mode 100644 index f871c25..0000000 --- a/contrib/llvm/tools/clang/Makefile +++ /dev/null @@ -1,92 +0,0 @@ -##===- Makefile --------------------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -# If CLANG_LEVEL is not set, then we are the top-level Makefile. Otherwise, we -# are being included from a subdirectory makefile. - -ifndef CLANG_LEVEL - -IS_TOP_LEVEL := 1 -CLANG_LEVEL := . -DIRS := include lib tools runtime docs - -PARALLEL_DIRS := - -ifeq ($(BUILD_EXAMPLES),1) - PARALLEL_DIRS += examples -endif -endif - -ifeq ($(MAKECMDGOALS),libs-only) - DIRS := $(filter-out tools docs, $(DIRS)) - OPTIONAL_DIRS := -endif - -### -# Common Makefile code, shared by all Clang Makefiles. - -# Set LLVM source root level. -LEVEL := $(CLANG_LEVEL)/../.. - -# Include LLVM common makefile. -include $(LEVEL)/Makefile.common - -# Set common Clang build flags. -CPP.Flags += -I$(PROJ_SRC_DIR)/$(CLANG_LEVEL)/include -I$(PROJ_OBJ_DIR)/$(CLANG_LEVEL)/include -ifdef CLANG_VENDOR -CPP.Flags += -DCLANG_VENDOR='"$(CLANG_VENDOR) "' -endif - -# Disable -fstrict-aliasing. Darwin disables it by default (and LLVM doesn't -# work with it enabled with GCC), Clang/llvm-gc don't support it yet, and newer -# GCC's have false positive warnings with it on Linux (which prove a pain to -# fix). For example: -# http://gcc.gnu.org/PR41874 -# http://gcc.gnu.org/PR41838 -# -# We can revisit this when LLVM/Clang support it. -CXX.Flags += -fno-strict-aliasing - -### -# Clang Top Level specific stuff. - -ifeq ($(IS_TOP_LEVEL),1) - -ifneq ($(PROJ_SRC_ROOT),$(PROJ_OBJ_ROOT)) -$(RecursiveTargets):: - $(Verb) if [ ! -f test/Makefile ]; then \ - $(MKDIR) test; \ - $(CP) $(PROJ_SRC_DIR)/test/Makefile test/Makefile; \ - fi -endif - -test:: - @ $(MAKE) -C test - -report:: - @ $(MAKE) -C test report - -clean:: - @ $(MAKE) -C test clean - -libs-only: all - -tags:: - $(Verb) etags `find . -type f -name '*.h' -or -name '*.cpp' | \ - grep -v /lib/Headers | grep -v /test/` - -cscope.files: - find tools lib include -name '*.cpp' \ - -or -name '*.def' \ - -or -name '*.td' \ - -or -name '*.h' > cscope.files - -.PHONY: test report clean cscope.files - -endif diff --git a/contrib/llvm/tools/clang/ModuleInfo.txt b/contrib/llvm/tools/clang/ModuleInfo.txt deleted file mode 100644 index 4368ef0..0000000 --- a/contrib/llvm/tools/clang/ModuleInfo.txt +++ /dev/null @@ -1,5 +0,0 @@ -# This file provides information for llvm-top -DepModule: llvm -ConfigCmd: -ConfigTest: -BuildCmd: diff --git a/contrib/llvm/tools/clang/NOTES.txt b/contrib/llvm/tools/clang/NOTES.txt deleted file mode 100644 index f66a961..0000000 --- a/contrib/llvm/tools/clang/NOTES.txt +++ /dev/null @@ -1,85 +0,0 @@ -//===---------------------------------------------------------------------===// -// Random Notes -//===---------------------------------------------------------------------===// - -C90/C99/C++ Comparisons: -http://david.tribble.com/text/cdiffs.htm - -//===---------------------------------------------------------------------===// - -To time GCC preprocessing speed without output, use: - "time gcc -MM file" -This is similar to -Eonly. - -//===---------------------------------------------------------------------===// - -Creating and using a PTH file for performance measurement (use a release build). - -$ clang -ccc-pch-is-pth -x objective-c-header INPUTS/Cocoa_h.m -o /tmp/tokencache -$ clang -cc1 -token-cache /tmp/tokencache INPUTS/Cocoa_h.m - -//===---------------------------------------------------------------------===// - - C++ Template Instantiation benchmark: - http://users.rcn.com/abrahams/instantiation_speed/index.html - -//===---------------------------------------------------------------------===// - -TODO: File Manager Speedup: - - We currently do a lot of stat'ing for files that don't exist, particularly - when lots of -I paths exist (e.g. see the <iostream> example, check for - failures in stat in FileManager::getFile). It would be far better to make - the following changes: - 1. FileEntry contains a sys::Path instead of a std::string for Name. - 2. sys::Path contains timestamp and size, lazily computed. Eliminate from - FileEntry. - 3. File UIDs are created on request, not when files are opened. - These changes make it possible to efficiently have FileEntry objects for - files that exist on the file system, but have not been used yet. - - Once this is done: - 1. DirectoryEntry gets a boolean value "has read entries". When false, not - all entries in the directory are in the file mgr, when true, they are. - 2. Instead of stat'ing the file in FileManager::getFile, check to see if - the dir has been read. If so, fail immediately, if not, read the dir, - then retry. - 3. Reading the dir uses the getdirentries syscall, creating an FileEntry - for all files found. - -//===---------------------------------------------------------------------===// -// Specifying targets: -triple and -arch -//===---------------------------------------------------------------------===// - -The clang supports "-triple" and "-arch" options. At most one -triple and one --arch option may be specified. Both are optional. - -The "selection of target" behavior is defined as follows: - -(1) If the user does not specify -triple, we default to the host triple. -(2) If the user specifies a -arch, that overrides the arch in the host or - specified triple. - -//===---------------------------------------------------------------------===// - - -verifyInputConstraint and verifyOutputConstraint should not return bool. - -Instead we should return something like: - -enum VerifyConstraintResult { - Valid, - - // Output only - OutputOperandConstraintLacksEqualsCharacter, - MatchingConstraintNotValidInOutputOperand, - - // Input only - InputOperandConstraintContainsEqualsCharacter, - MatchingConstraintReferencesInvalidOperandNumber, - - // Both - PercentConstraintUsedWithLastOperand -}; - -//===---------------------------------------------------------------------===// diff --git a/contrib/llvm/tools/clang/README.txt b/contrib/llvm/tools/clang/README.txt deleted file mode 100644 index 44ce723a..0000000 --- a/contrib/llvm/tools/clang/README.txt +++ /dev/null @@ -1,26 +0,0 @@ -//===----------------------------------------------------------------------===// -// C Language Family Front-end -//===----------------------------------------------------------------------===// - -Welcome to Clang. This is a compiler front-end for the C family of languages -(C, C++, Objective-C, and Objective-C++) which is built as part of the LLVM -compiler infrastructure project. - -Unlike many other compiler frontends, Clang is useful for a number of things -beyond just compiling code: we intend for Clang to be host to a number of -different source level tools. One example of this is the Clang Static Analyzer. - -If you're interested in more (including how to build Clang) it is best to read -the relevant web sites. Here are some pointers: - -Information on Clang: http://clang.llvm.org/ -Building and using Clang: http://clang.llvm.org/get_started.html -Clang Static Analyzer: http://clang-analyzer.llvm.org/ -Information on the LLVM project: http://llvm.org/ - -If you have questions or comments about Clang, a great place to discuss them is -on the Clang development mailing list: - http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev - -If you find a bug in Clang, please file it in the LLVM bug tracker: - http://llvm.org/bugs/ diff --git a/contrib/llvm/tools/clang/TODO.txt b/contrib/llvm/tools/clang/TODO.txt deleted file mode 100644 index c63b1b3..0000000 --- a/contrib/llvm/tools/clang/TODO.txt +++ /dev/null @@ -1,75 +0,0 @@ -//===---------------------------------------------------------------------===// -// Minor random things that can be improved -//===---------------------------------------------------------------------===// - - -Warn about "X && 0x1000" saying that the user may mean "X & 0x1000". -We should do this for any immediate except zero, so long as it doesn't come -from a macro expansion. Likewise for ||. - -//===---------------------------------------------------------------------===// - -Lexer-related diagnostics should point to the problematic character, not the -start of the token. For example: - -int y = 0000\ -00080; - -diag.c:4:9: error: invalid digit '8' in octal constant -int y = 0000\ - ^ - -should be: - -diag.c:4:9: error: invalid digit '8' in octal constant -00080; - ^ - -This specific diagnostic is implemented, but others should be updated. - -//===---------------------------------------------------------------------===// - -C++ (checker): For iterators, warn of the use of "iterator++" instead - of "++iterator" when when the value returned by operator++(int) is - ignored. - -//===---------------------------------------------------------------------===// - -We want to keep more source range information in Declarator to help -produce better diagnostics. Declarator::getSourceRange() should be -implemented to give a range for the whole declarator with all of its -specifiers, and DeclaratorChunk::ParamInfo should also have a source -range covering the whole parameter, so that an error message like this: - -overloaded-operator-decl.cpp:37:23: error: parameter of overloaded post-increment operator must have type 'int' (not 'float') -X operator++(X&, const float& f); - ^ -can be turned into something like this: - -overloaded-operator-decl.cpp:37:23: error: parameter of overloaded post-increment operator must have type 'int' (not 'float') -X operator++(X&, const float& f); - ^ ~~~~~~~~~~~~~~ - -//===---------------------------------------------------------------------===// - -For terminal output, we should consider limiting the amount of -diagnostic text we print once the first error has been -encountered. For example, once we have produced an error diagnostic, -we should only continue producing diagnostics until we have produced a -page full of results (say, 50 lines of text). Beyond that, (1) the -remaining errors are likely to be less interesting, and (2) the poor -user has to scroll his terminal to find out where things went wrong. - -//===---------------------------------------------------------------------===// -More ideas for code modification hints: - - If no member of a given name is found in a class/struct, search through the names of entities that do exist in the class and suggest the closest candidate. e.g., if I write "DS.setTypeSpecType", it would suggest "DS.SetTypeSpecType" (edit distance = 1). - - If a class member is defined out-of-line but isn't in the class declaration (and there are no close matches!), provide the option to add an in-class declaration. - - Fix-it hints for the inclusion of headers when needed for particular features (e.g., <typeinfo> for typeid) - -//===---------------------------------------------------------------------===// - -Options to support: - -ftabstop=width - -fpreprocessed mode. - -nostdinc++ - -imultilib diff --git a/contrib/llvm/tools/clang/bindings/python/README.txt b/contrib/llvm/tools/clang/bindings/python/README.txt deleted file mode 100644 index 742cf8f..0000000 --- a/contrib/llvm/tools/clang/bindings/python/README.txt +++ /dev/null @@ -1,17 +0,0 @@ -//===----------------------------------------------------------------------===// -// Clang Python Bindings -//===----------------------------------------------------------------------===// - -This directory implements Python bindings for Clang. - -You may need to alter LD_LIBRARY_PATH so that the Clang library can be -found. The unit tests are designed to be run with 'nosetests'. For example: --- -$ env PYTHONPATH=$(echo ~/llvm/tools/clang/bindings/python/) \ - LD_LIBRARY_PATH=$(llvm-config --libdir) \ - nosetests -v -tests.cindex.test_index.test_create ... ok -... - -OK --- diff --git a/contrib/llvm/tools/clang/bindings/python/clang/__init__.py b/contrib/llvm/tools/clang/bindings/python/clang/__init__.py deleted file mode 100644 index 88f3081..0000000 --- a/contrib/llvm/tools/clang/bindings/python/clang/__init__.py +++ /dev/null @@ -1,24 +0,0 @@ -#===- __init__.py - Clang Python Bindings --------------------*- python -*--===# -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -#===------------------------------------------------------------------------===# - -r""" -Clang Library Bindings -====================== - -This package provides access to the Clang compiler and libraries. - -The available modules are: - - cindex - - Bindings for the Clang indexing library. -""" - -__all__ = ['cindex'] - diff --git a/contrib/llvm/tools/clang/bindings/python/clang/cindex.py b/contrib/llvm/tools/clang/bindings/python/clang/cindex.py deleted file mode 100644 index f0f81b5..0000000 --- a/contrib/llvm/tools/clang/bindings/python/clang/cindex.py +++ /dev/null @@ -1,935 +0,0 @@ -#===- cindex.py - Python Indexing Library Bindings -----------*- python -*--===# -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -#===------------------------------------------------------------------------===# - -r""" -Clang Indexing Library Bindings -=============================== - -This module provides an interface to the Clang indexing library. It is a -low-level interface to the indexing library which attempts to match the Clang -API directly while also being "pythonic". Notable differences from the C API -are: - - * string results are returned as Python strings, not CXString objects. - - * null cursors are translated to None. - - * access to child cursors is done via iteration, not visitation. - -The major indexing objects are: - - Index - - The top-level object which manages some global library state. - - TranslationUnit - - High-level object encapsulating the AST for a single translation unit. These - can be loaded from .ast files or parsed on the fly. - - Cursor - - Generic object for representing a node in the AST. - - SourceRange, SourceLocation, and File - - Objects representing information about the input source. - -Most object information is exposed using properties, when the underlying API -call is efficient. -""" - -# TODO -# ==== -# -# o API support for invalid translation units. Currently we can't even get the -# diagnostics on failure because they refer to locations in an object that -# will have been invalidated. -# -# o fix memory management issues (currently client must hold on to index and -# translation unit, or risk crashes). -# -# o expose code completion APIs. -# -# o cleanup ctypes wrapping, would be nice to separate the ctypes details more -# clearly, and hide from the external interface (i.e., help(cindex)). -# -# o implement additional SourceLocation, SourceRange, and File methods. - -from ctypes import * - -def get_cindex_library(): - # FIXME: It's probably not the case that the library is actually found in - # this location. We need a better system of identifying and loading the - # CIndex library. It could be on path or elsewhere, or versioned, etc. - import platform - name = platform.system() - if name == 'Darwin': - return cdll.LoadLibrary('libclang.dylib') - elif name == 'Windows': - return cdll.LoadLibrary('libclang.dll') - else: - return cdll.LoadLibrary('libclang.so') - -# ctypes doesn't implicitly convert c_void_p to the appropriate wrapper -# object. This is a problem, because it means that from_parameter will see an -# integer and pass the wrong value on platforms where int != void*. Work around -# this by marshalling object arguments as void**. -c_object_p = POINTER(c_void_p) - -lib = get_cindex_library() - -### Structures and Utility Classes ### - -class _CXString(Structure): - """Helper for transforming CXString results.""" - - _fields_ = [("spelling", c_char_p), ("free", c_int)] - - def __del__(self): - _CXString_dispose(self) - - @staticmethod - def from_result(res, fn, args): - assert isinstance(res, _CXString) - return _CXString_getCString(res) - -class SourceLocation(Structure): - """ - A SourceLocation represents a particular location within a source file. - """ - _fields_ = [("ptr_data", c_void_p * 2), ("int_data", c_uint)] - _data = None - - def _get_instantiation(self): - if self._data is None: - f, l, c, o = c_object_p(), c_uint(), c_uint(), c_uint() - SourceLocation_loc(self, byref(f), byref(l), byref(c), byref(o)) - f = File(f) if f else None - self._data = (f, int(l.value), int(c.value), int(c.value)) - return self._data - - @property - def file(self): - """Get the file represented by this source location.""" - return self._get_instantiation()[0] - - @property - def line(self): - """Get the line represented by this source location.""" - return self._get_instantiation()[1] - - @property - def column(self): - """Get the column represented by this source location.""" - return self._get_instantiation()[2] - - @property - def offset(self): - """Get the file offset represented by this source location.""" - return self._get_instantiation()[3] - - def __repr__(self): - return "<SourceLocation file %r, line %r, column %r>" % ( - self.file.name if self.file else None, self.line, self.column) - -class SourceRange(Structure): - """ - A SourceRange describes a range of source locations within the source - code. - """ - _fields_ = [ - ("ptr_data", c_void_p * 2), - ("begin_int_data", c_uint), - ("end_int_data", c_uint)] - - # FIXME: Eliminate this and make normal constructor? Requires hiding ctypes - # object. - @staticmethod - def from_locations(start, end): - return SourceRange_getRange(start, end) - - @property - def start(self): - """ - Return a SourceLocation representing the first character within a - source range. - """ - return SourceRange_start(self) - - @property - def end(self): - """ - Return a SourceLocation representing the last character within a - source range. - """ - return SourceRange_end(self) - - def __repr__(self): - return "<SourceRange start %r, end %r>" % (self.start, self.end) - -class Diagnostic(object): - """ - A Diagnostic is a single instance of a Clang diagnostic. It includes the - diagnostic severity, the message, the location the diagnostic occurred, as - well as additional source ranges and associated fix-it hints. - """ - - Ignored = 0 - Note = 1 - Warning = 2 - Error = 3 - Fatal = 4 - - def __init__(self, ptr): - self.ptr = ptr - - def __del__(self): - _clang_disposeDiagnostic(self.ptr) - - @property - def severity(self): - return _clang_getDiagnosticSeverity(self.ptr) - - @property - def location(self): - return _clang_getDiagnosticLocation(self.ptr) - - @property - def spelling(self): - return _clang_getDiagnosticSpelling(self.ptr) - - @property - def ranges(self): - class RangeIterator: - def __init__(self, diag): - self.diag = diag - - def __len__(self): - return int(_clang_getDiagnosticNumRanges(self.diag)) - - def __getitem__(self, key): - return _clang_getDiagnosticRange(self.diag, key) - - return RangeIterator(self.ptr) - - @property - def fixits(self): - class FixItIterator: - def __init__(self, diag): - self.diag = diag - - def __len__(self): - return int(_clang_getDiagnosticNumFixIts(self.diag)) - - def __getitem__(self, key): - range = SourceRange() - value = _clang_getDiagnosticFixIt(self.diag, key, byref(range)) - if len(value) == 0: - raise IndexError - - return FixIt(range, value) - - return FixItIterator(self.ptr) - - def __repr__(self): - return "<Diagnostic severity %r, location %r, spelling %r>" % ( - self.severity, self.location, self.spelling) - -class FixIt(object): - """ - A FixIt represents a transformation to be applied to the source to - "fix-it". The fix-it shouldbe applied by replacing the given source range - with the given value. - """ - - def __init__(self, range, value): - self.range = range - self.value = value - - def __repr__(self): - return "<FixIt range %r, value %r>" % (self.range, self.value) - -### Cursor Kinds ### - -class CursorKind(object): - """ - A CursorKind describes the kind of entity that a cursor points to. - """ - - # The unique kind objects, indexed by id. - _kinds = [] - _name_map = None - - def __init__(self, value): - if value >= len(CursorKind._kinds): - CursorKind._kinds += [None] * (value - len(CursorKind._kinds) + 1) - if CursorKind._kinds[value] is not None: - raise ValueError,'CursorKind already loaded' - self.value = value - CursorKind._kinds[value] = self - CursorKind._name_map = None - - def from_param(self): - return self.value - - @property - def name(self): - """Get the enumeration name of this cursor kind.""" - if self._name_map is None: - self._name_map = {} - for key,value in CursorKind.__dict__.items(): - if isinstance(value,CursorKind): - self._name_map[value] = key - return self._name_map[self] - - @staticmethod - def from_id(id): - if id >= len(CursorKind._kinds) or CursorKind._kinds[id] is None: - raise ValueError,'Unknown cursor kind' - return CursorKind._kinds[id] - - @staticmethod - def get_all_kinds(): - """Return all CursorKind enumeration instances.""" - return filter(None, CursorKind._kinds) - - def is_declaration(self): - """Test if this is a declaration kind.""" - return CursorKind_is_decl(self) - - def is_reference(self): - """Test if this is a reference kind.""" - return CursorKind_is_ref(self) - - def is_expression(self): - """Test if this is an expression kind.""" - return CursorKind_is_expr(self) - - def is_statement(self): - """Test if this is a statement kind.""" - return CursorKind_is_stmt(self) - - def is_invalid(self): - """Test if this is an invalid kind.""" - return CursorKind_is_inv(self) - - def __repr__(self): - return 'CursorKind.%s' % (self.name,) - -# FIXME: Is there a nicer way to expose this enumeration? We could potentially -# represent the nested structure, or even build a class hierarchy. The main -# things we want for sure are (a) simple external access to kinds, (b) a place -# to hang a description and name, (c) easy to keep in sync with Index.h. - -### -# Declaration Kinds - -# A declaration whose specific kind is not exposed via this interface. -# -# Unexposed declarations have the same operations as any other kind of -# declaration; one can extract their location information, spelling, find their -# definitions, etc. However, the specific kind of the declaration is not -# reported. -CursorKind.UNEXPOSED_DECL = CursorKind(1) - -# A C or C++ struct. -CursorKind.STRUCT_DECL = CursorKind(2) - -# A C or C++ union. -CursorKind.UNION_DECL = CursorKind(3) - -# A C++ class. -CursorKind.CLASS_DECL = CursorKind(4) - -# An enumeration. -CursorKind.ENUM_DECL = CursorKind(5) - -# A field (in C) or non-static data member (in C++) in a struct, union, or C++ -# class. -CursorKind.FIELD_DECL = CursorKind(6) - -# An enumerator constant. -CursorKind.ENUM_CONSTANT_DECL = CursorKind(7) - -# A function. -CursorKind.FUNCTION_DECL = CursorKind(8) - -# A variable. -CursorKind.VAR_DECL = CursorKind(9) - -# A function or method parameter. -CursorKind.PARM_DECL = CursorKind(10) - -# An Objective-C @interface. -CursorKind.OBJC_INTERFACE_DECL = CursorKind(11) - -# An Objective-C @interface for a category. -CursorKind.OBJC_CATEGORY_DECL = CursorKind(12) - -# An Objective-C @protocol declaration. -CursorKind.OBJC_PROTOCOL_DECL = CursorKind(13) - -# An Objective-C @property declaration. -CursorKind.OBJC_PROPERTY_DECL = CursorKind(14) - -# An Objective-C instance variable. -CursorKind.OBJC_IVAR_DECL = CursorKind(15) - -# An Objective-C instance method. -CursorKind.OBJC_INSTANCE_METHOD_DECL = CursorKind(16) - -# An Objective-C class method. -CursorKind.OBJC_CLASS_METHOD_DECL = CursorKind(17) - -# An Objective-C @implementation. -CursorKind.OBJC_IMPLEMENTATION_DECL = CursorKind(18) - -# An Objective-C @implementation for a category. -CursorKind.OBJC_CATEGORY_IMPL_DECL = CursorKind(19) - -# A typedef. -CursorKind.TYPEDEF_DECL = CursorKind(20) - -### -# Reference Kinds - -CursorKind.OBJC_SUPER_CLASS_REF = CursorKind(40) -CursorKind.OBJC_PROTOCOL_REF = CursorKind(41) -CursorKind.OBJC_CLASS_REF = CursorKind(42) - -# A reference to a type declaration. -# -# A type reference occurs anywhere where a type is named but not -# declared. For example, given: -# typedef unsigned size_type; -# size_type size; -# -# The typedef is a declaration of size_type (CXCursor_TypedefDecl), -# while the type of the variable "size" is referenced. The cursor -# referenced by the type of size is the typedef for size_type. -CursorKind.TYPE_REF = CursorKind(43) - -### -# Invalid/Error Kinds - -CursorKind.INVALID_FILE = CursorKind(70) -CursorKind.NO_DECL_FOUND = CursorKind(71) -CursorKind.NOT_IMPLEMENTED = CursorKind(72) - -### -# Expression Kinds - -# An expression whose specific kind is not exposed via this interface. -# -# Unexposed expressions have the same operations as any other kind of -# expression; one can extract their location information, spelling, children, -# etc. However, the specific kind of the expression is not reported. -CursorKind.UNEXPOSED_EXPR = CursorKind(100) - -# An expression that refers to some value declaration, such as a function, -# varible, or enumerator. -CursorKind.DECL_REF_EXPR = CursorKind(101) - -# An expression that refers to a member of a struct, union, class, Objective-C -# class, etc. -CursorKind.MEMBER_REF_EXPR = CursorKind(102) - -# An expression that calls a function. -CursorKind.CALL_EXPR = CursorKind(103) - -# An expression that sends a message to an Objective-C object or class. -CursorKind.OBJC_MESSAGE_EXPR = CursorKind(104) - -# A statement whose specific kind is not exposed via this interface. -# -# Unexposed statements have the same operations as any other kind of statement; -# one can extract their location information, spelling, children, etc. However, -# the specific kind of the statement is not reported. -CursorKind.UNEXPOSED_STMT = CursorKind(200) - -### -# Other Kinds - -# Cursor that represents the translation unit itself. -# -# The translation unit cursor exists primarily to act as the root cursor for -# traversing the contents of a translation unit. -CursorKind.TRANSLATION_UNIT = CursorKind(300) - -### Cursors ### - -class Cursor(Structure): - """ - The Cursor class represents a reference to an element within the AST. It - acts as a kind of iterator. - """ - _fields_ = [("_kind_id", c_int), ("data", c_void_p * 3)] - - def __eq__(self, other): - return Cursor_eq(self, other) - - def __ne__(self, other): - return not Cursor_eq(self, other) - - def is_definition(self): - """ - Returns true if the declaration pointed at by the cursor is also a - definition of that entity. - """ - return Cursor_is_def(self) - - def get_definition(self): - """ - If the cursor is a reference to a declaration or a declaration of - some entity, return a cursor that points to the definition of that - entity. - """ - # TODO: Should probably check that this is either a reference or - # declaration prior to issuing the lookup. - return Cursor_def(self) - - def get_usr(self): - """Return the Unified Symbol Resultion (USR) for the entity referenced - by the given cursor (or None). - - A Unified Symbol Resolution (USR) is a string that identifies a - particular entity (function, class, variable, etc.) within a - program. USRs can be compared across translation units to determine, - e.g., when references in one translation refer to an entity defined in - another translation unit.""" - return Cursor_usr(self) - - @property - def kind(self): - """Return the kind of this cursor.""" - return CursorKind.from_id(self._kind_id) - - @property - def spelling(self): - """Return the spelling of the entity pointed at by the cursor.""" - if not self.kind.is_declaration(): - # FIXME: clang_getCursorSpelling should be fixed to not assert on - # this, for consistency with clang_getCursorUSR. - return None - return Cursor_spelling(self) - - @property - def location(self): - """ - Return the source location (the starting character) of the entity - pointed at by the cursor. - """ - return Cursor_loc(self) - - @property - def extent(self): - """ - Return the source range (the range of text) occupied by the entity - pointed at by the cursor. - """ - return Cursor_extent(self) - - def get_children(self): - """Return an iterator for accessing the children of this cursor.""" - - # FIXME: Expose iteration from CIndex, PR6125. - def visitor(child, parent, children): - # FIXME: Document this assertion in API. - # FIXME: There should just be an isNull method. - assert child != Cursor_null() - children.append(child) - return 1 # continue - children = [] - Cursor_visit(self, Cursor_visit_callback(visitor), children) - return iter(children) - - @staticmethod - def from_result(res, fn, args): - assert isinstance(res, Cursor) - # FIXME: There should just be an isNull method. - if res == Cursor_null(): - return None - return res - -## CIndex Objects ## - -# CIndex objects (derived from ClangObject) are essentially lightweight -# wrappers attached to some underlying object, which is exposed via CIndex as -# a void*. - -class ClangObject(object): - """ - A helper for Clang objects. This class helps act as an intermediary for - the ctypes library and the Clang CIndex library. - """ - def __init__(self, obj): - assert isinstance(obj, c_object_p) and obj - self.obj = self._as_parameter_ = obj - - def from_param(self): - return self._as_parameter_ - - -class _CXUnsavedFile(Structure): - """Helper for passing unsaved file arguments.""" - _fields_ = [("name", c_char_p), ("contents", c_char_p), ('length', c_ulong)] - -## Diagnostic Conversion ## - -_clang_getNumDiagnostics = lib.clang_getNumDiagnostics -_clang_getNumDiagnostics.argtypes = [c_object_p] -_clang_getNumDiagnostics.restype = c_uint - -_clang_getDiagnostic = lib.clang_getDiagnostic -_clang_getDiagnostic.argtypes = [c_object_p, c_uint] -_clang_getDiagnostic.restype = c_object_p - -_clang_disposeDiagnostic = lib.clang_disposeDiagnostic -_clang_disposeDiagnostic.argtypes = [c_object_p] - -_clang_getDiagnosticSeverity = lib.clang_getDiagnosticSeverity -_clang_getDiagnosticSeverity.argtypes = [c_object_p] -_clang_getDiagnosticSeverity.restype = c_int - -_clang_getDiagnosticLocation = lib.clang_getDiagnosticLocation -_clang_getDiagnosticLocation.argtypes = [c_object_p] -_clang_getDiagnosticLocation.restype = SourceLocation - -_clang_getDiagnosticSpelling = lib.clang_getDiagnosticSpelling -_clang_getDiagnosticSpelling.argtypes = [c_object_p] -_clang_getDiagnosticSpelling.restype = _CXString -_clang_getDiagnosticSpelling.errcheck = _CXString.from_result - -_clang_getDiagnosticNumRanges = lib.clang_getDiagnosticNumRanges -_clang_getDiagnosticNumRanges.argtypes = [c_object_p] -_clang_getDiagnosticNumRanges.restype = c_uint - -_clang_getDiagnosticRange = lib.clang_getDiagnosticRange -_clang_getDiagnosticRange.argtypes = [c_object_p, c_uint] -_clang_getDiagnosticRange.restype = SourceRange - -_clang_getDiagnosticNumFixIts = lib.clang_getDiagnosticNumFixIts -_clang_getDiagnosticNumFixIts.argtypes = [c_object_p] -_clang_getDiagnosticNumFixIts.restype = c_uint - -_clang_getDiagnosticFixIt = lib.clang_getDiagnosticFixIt -_clang_getDiagnosticFixIt.argtypes = [c_object_p, c_uint, POINTER(SourceRange)] -_clang_getDiagnosticFixIt.restype = _CXString -_clang_getDiagnosticFixIt.errcheck = _CXString.from_result - -### - -class Index(ClangObject): - """ - The Index type provides the primary interface to the Clang CIndex library, - primarily by providing an interface for reading and parsing translation - units. - """ - - @staticmethod - def create(excludeDecls=False): - """ - Create a new Index. - Parameters: - excludeDecls -- Exclude local declarations from translation units. - """ - return Index(Index_create(excludeDecls, 0)) - - def __del__(self): - Index_dispose(self) - - def read(self, path): - """Load the translation unit from the given AST file.""" - ptr = TranslationUnit_read(self, path) - return TranslationUnit(ptr) if ptr else None - - def parse(self, path, args = [], unsaved_files = []): - """ - Load the translation unit from the given source code file by running - clang and generating the AST before loading. Additional command line - parameters can be passed to clang via the args parameter. - - In-memory contents for files can be provided by passing a list of pairs - to as unsaved_files, the first item should be the filenames to be mapped - and the second should be the contents to be substituted for the - file. The contents may be passed as strings or file objects. - """ - arg_array = 0 - if len(args): - arg_array = (c_char_p * len(args))(* args) - unsaved_files_array = 0 - if len(unsaved_files): - unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))() - for i,(name,value) in enumerate(unsaved_files): - if not isinstance(value, str): - # FIXME: It would be great to support an efficient version - # of this, one day. - value = value.read() - print value - if not isinstance(value, str): - raise TypeError,'Unexpected unsaved file contents.' - unsaved_files_array[i].name = name - unsaved_files_array[i].contents = value - unsaved_files_array[i].length = len(value) - ptr = TranslationUnit_parse(self, path, len(args), arg_array, - len(unsaved_files), unsaved_files_array) - return TranslationUnit(ptr) if ptr else None - - -class TranslationUnit(ClangObject): - """ - The TranslationUnit class represents a source code translation unit and - provides read-only access to its top-level declarations. - """ - - def __init__(self, ptr): - ClangObject.__init__(self, ptr) - - def __del__(self): - TranslationUnit_dispose(self) - - @property - def cursor(self): - """Retrieve the cursor that represents the given translation unit.""" - return TranslationUnit_cursor(self) - - @property - def spelling(self): - """Get the original translation unit source file name.""" - return TranslationUnit_spelling(self) - - def get_includes(self): - """ - Return an iterable sequence of FileInclusion objects that describe the - sequence of inclusions in a translation unit. The first object in - this sequence is always the input file. Note that this method will not - recursively iterate over header files included through precompiled - headers. - """ - def visitor(fobj, lptr, depth, includes): - loc = lptr.contents - includes.append(FileInclusion(loc.file, File(fobj), loc, depth)) - - # Automatically adapt CIndex/ctype pointers to python objects - includes = [] - TranslationUnit_includes(self, - TranslationUnit_includes_callback(visitor), - includes) - return iter(includes) - - @property - def diagnostics(self): - """ - Return an iterable (and indexable) object containing the diagnostics. - """ - class DiagIterator: - def __init__(self, tu): - self.tu = tu - - def __len__(self): - return int(_clang_getNumDiagnostics(self.tu)) - - def __getitem__(self, key): - diag = _clang_getDiagnostic(self.tu, key) - if not diag: - raise IndexError - return Diagnostic(diag) - - return DiagIterator(self) - -class File(ClangObject): - """ - The File class represents a particular source file that is part of a - translation unit. - """ - - @property - def name(self): - """Return the complete file and path name of the file.""" - return File_name(self) - - @property - def time(self): - """Return the last modification time of the file.""" - return File_time(self) - -class FileInclusion(object): - """ - The FileInclusion class represents the inclusion of one source file by - another via a '#include' directive or as the input file for the translation - unit. This class provides information about the included file, the including - file, the location of the '#include' directive and the depth of the included - file in the stack. Note that the input file has depth 0. - """ - - def __init__(self, src, tgt, loc, depth): - self.source = src - self.include = tgt - self.location = loc - self.depth = depth - - @property - def is_input_file(self): - """True if the included file is the input file.""" - return self.depth == 0 - -# Additional Functions and Types - -# String Functions -_CXString_dispose = lib.clang_disposeString -_CXString_dispose.argtypes = [_CXString] - -_CXString_getCString = lib.clang_getCString -_CXString_getCString.argtypes = [_CXString] -_CXString_getCString.restype = c_char_p - -# Source Location Functions -SourceLocation_loc = lib.clang_getInstantiationLocation -SourceLocation_loc.argtypes = [SourceLocation, POINTER(c_object_p), - POINTER(c_uint), POINTER(c_uint), - POINTER(c_uint)] - -# Source Range Functions -SourceRange_getRange = lib.clang_getRange -SourceRange_getRange.argtypes = [SourceLocation, SourceLocation] -SourceRange_getRange.restype = SourceRange - -SourceRange_start = lib.clang_getRangeStart -SourceRange_start.argtypes = [SourceRange] -SourceRange_start.restype = SourceLocation - -SourceRange_end = lib.clang_getRangeEnd -SourceRange_end.argtypes = [SourceRange] -SourceRange_end.restype = SourceLocation - -# CursorKind Functions -CursorKind_is_decl = lib.clang_isDeclaration -CursorKind_is_decl.argtypes = [CursorKind] -CursorKind_is_decl.restype = bool - -CursorKind_is_ref = lib.clang_isReference -CursorKind_is_ref.argtypes = [CursorKind] -CursorKind_is_ref.restype = bool - -CursorKind_is_expr = lib.clang_isExpression -CursorKind_is_expr.argtypes = [CursorKind] -CursorKind_is_expr.restype = bool - -CursorKind_is_stmt = lib.clang_isStatement -CursorKind_is_stmt.argtypes = [CursorKind] -CursorKind_is_stmt.restype = bool - -CursorKind_is_inv = lib.clang_isInvalid -CursorKind_is_inv.argtypes = [CursorKind] -CursorKind_is_inv.restype = bool - -# Cursor Functions -# TODO: Implement this function -Cursor_get = lib.clang_getCursor -Cursor_get.argtypes = [TranslationUnit, SourceLocation] -Cursor_get.restype = Cursor - -Cursor_null = lib.clang_getNullCursor -Cursor_null.restype = Cursor - -Cursor_usr = lib.clang_getCursorUSR -Cursor_usr.argtypes = [Cursor] -Cursor_usr.restype = _CXString -Cursor_usr.errcheck = _CXString.from_result - -Cursor_is_def = lib.clang_isCursorDefinition -Cursor_is_def.argtypes = [Cursor] -Cursor_is_def.restype = bool - -Cursor_def = lib.clang_getCursorDefinition -Cursor_def.argtypes = [Cursor] -Cursor_def.restype = Cursor -Cursor_def.errcheck = Cursor.from_result - -Cursor_eq = lib.clang_equalCursors -Cursor_eq.argtypes = [Cursor, Cursor] -Cursor_eq.restype = c_uint - -Cursor_spelling = lib.clang_getCursorSpelling -Cursor_spelling.argtypes = [Cursor] -Cursor_spelling.restype = _CXString -Cursor_spelling.errcheck = _CXString.from_result - -Cursor_loc = lib.clang_getCursorLocation -Cursor_loc.argtypes = [Cursor] -Cursor_loc.restype = SourceLocation - -Cursor_extent = lib.clang_getCursorExtent -Cursor_extent.argtypes = [Cursor] -Cursor_extent.restype = SourceRange - -Cursor_ref = lib.clang_getCursorReferenced -Cursor_ref.argtypes = [Cursor] -Cursor_ref.restype = Cursor -Cursor_ref.errcheck = Cursor.from_result - -Cursor_visit_callback = CFUNCTYPE(c_int, Cursor, Cursor, py_object) -Cursor_visit = lib.clang_visitChildren -Cursor_visit.argtypes = [Cursor, Cursor_visit_callback, py_object] -Cursor_visit.restype = c_uint - -# Index Functions -Index_create = lib.clang_createIndex -Index_create.argtypes = [c_int, c_int] -Index_create.restype = c_object_p - -Index_dispose = lib.clang_disposeIndex -Index_dispose.argtypes = [Index] - -# Translation Unit Functions -TranslationUnit_read = lib.clang_createTranslationUnit -TranslationUnit_read.argtypes = [Index, c_char_p] -TranslationUnit_read.restype = c_object_p - -TranslationUnit_parse = lib.clang_createTranslationUnitFromSourceFile -TranslationUnit_parse.argtypes = [Index, c_char_p, c_int, c_void_p, - c_int, c_void_p] -TranslationUnit_parse.restype = c_object_p - -TranslationUnit_cursor = lib.clang_getTranslationUnitCursor -TranslationUnit_cursor.argtypes = [TranslationUnit] -TranslationUnit_cursor.restype = Cursor -TranslationUnit_cursor.errcheck = Cursor.from_result - -TranslationUnit_spelling = lib.clang_getTranslationUnitSpelling -TranslationUnit_spelling.argtypes = [TranslationUnit] -TranslationUnit_spelling.restype = _CXString -TranslationUnit_spelling.errcheck = _CXString.from_result - -TranslationUnit_dispose = lib.clang_disposeTranslationUnit -TranslationUnit_dispose.argtypes = [TranslationUnit] - -TranslationUnit_includes_callback = CFUNCTYPE(None, - c_object_p, - POINTER(SourceLocation), - c_uint, py_object) -TranslationUnit_includes = lib.clang_getInclusions -TranslationUnit_includes.argtypes = [TranslationUnit, - TranslationUnit_includes_callback, - py_object] - -# File Functions -File_name = lib.clang_getFileName -File_name.argtypes = [File] -File_name.restype = c_char_p - -File_time = lib.clang_getFileTime -File_time.argtypes = [File] -File_time.restype = c_uint - -### - -__all__ = ['Index', 'TranslationUnit', 'Cursor', 'CursorKind', - 'Diagnostic', 'FixIt', 'SourceRange', 'SourceLocation', 'File'] diff --git a/contrib/llvm/tools/clang/bindings/python/examples/cindex/cindex-dump.py b/contrib/llvm/tools/clang/bindings/python/examples/cindex/cindex-dump.py deleted file mode 100644 index af7ddab..0000000 --- a/contrib/llvm/tools/clang/bindings/python/examples/cindex/cindex-dump.py +++ /dev/null @@ -1,87 +0,0 @@ -#!/usr/bin/env python - -#===- cindex-dump.py - cindex/Python Source Dump -------------*- python -*--===# -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -#===------------------------------------------------------------------------===# - -""" -A simple command line tool for dumping a source file using the Clang Index -Library. -""" - -def get_diag_info(diag): - return { 'severity' : diag.severity, - 'location' : diag.location, - 'spelling' : diag.spelling, - 'ranges' : diag.ranges, - 'fixits' : diag.fixits } - -def get_cursor_id(cursor, cursor_list = []): - if not opts.showIDs: - return None - - if cursor is None: - return None - - # FIXME: This is really slow. It would be nice if the index API exposed - # something that let us hash cursors. - for i,c in enumerate(cursor_list): - if cursor == c: - return i - cursor_list.append(cursor) - return len(cursor_list) - 1 - -def get_info(node, depth=0): - if opts.maxDepth is not None and depth >= opts.maxDepth: - children = None - else: - children = [get_info(c, depth+1) - for c in node.get_children()] - return { 'id' : get_cursor_id(node), - 'kind' : node.kind, - 'usr' : node.get_usr(), - 'spelling' : node.spelling, - 'location' : node.location, - 'extent.start' : node.extent.start, - 'extent.end' : node.extent.end, - 'is_definition' : node.is_definition(), - 'definition id' : get_cursor_id(node.get_definition()), - 'children' : children } - -def main(): - from clang.cindex import Index - from pprint import pprint - - from optparse import OptionParser, OptionGroup - - global opts - - parser = OptionParser("usage: %prog [options] {filename} [clang-args*]") - parser.add_option("", "--show-ids", dest="showIDs", - help="Don't compute cursor IDs (very slow)", - default=False) - parser.add_option("", "--max-depth", dest="maxDepth", - help="Limit cursor expansion to depth N", - metavar="N", type=int, default=None) - parser.disable_interspersed_args() - (opts, args) = parser.parse_args() - - if len(args) == 0: - parser.error('invalid number arguments') - - index = Index.create() - tu = index.parse(None, args) - if not tu: - parser.error("unable to load input") - - pprint(('diags', map(get_diag_info, tu.diagnostics))) - pprint(('nodes', get_info(tu.cursor))) - -if __name__ == '__main__': - main() - diff --git a/contrib/llvm/tools/clang/bindings/python/examples/cindex/cindex-includes.py b/contrib/llvm/tools/clang/bindings/python/examples/cindex/cindex-includes.py deleted file mode 100644 index 1750022..0000000 --- a/contrib/llvm/tools/clang/bindings/python/examples/cindex/cindex-includes.py +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env python - -#===- cindex-includes.py - cindex/Python Inclusion Graph -----*- python -*--===# -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -#===------------------------------------------------------------------------===# - -""" -A simple command line tool for dumping a Graphviz description (dot) that -describes include dependencies. -""" - -def main(): - import sys - from clang.cindex import Index - - from optparse import OptionParser, OptionGroup - - parser = OptionParser("usage: %prog [options] {filename} [clang-args*]") - parser.disable_interspersed_args() - (opts, args) = parser.parse_args() - if len(args) == 0: - parser.error('invalid number arguments') - - # FIXME: Add an output file option - out = sys.stdout - - index = Index.create() - tu = index.parse(None, args) - if not tu: - parser.error("unable to load input") - - # A helper function for generating the node name. - def name(f): - if f: - return "\"" + f.name + "\"" - - # Generate the include graph - out.write("digraph G {\n") - for i in tu.get_includes(): - line = " "; - if i.is_input_file: - # Always write the input file as a node just in case it doesn't - # actually include anything. This would generate a 1 node graph. - line += name(i.include) - else: - line += '%s->%s' % (name(i.source), name(i.include)) - line += "\n"; - out.write(line) - out.write("}\n") - -if __name__ == '__main__': - main() - diff --git a/contrib/llvm/tools/clang/bindings/python/tests/__init__.py b/contrib/llvm/tools/clang/bindings/python/tests/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/contrib/llvm/tools/clang/bindings/python/tests/__init__.py +++ /dev/null diff --git a/contrib/llvm/tools/clang/bindings/python/tests/cindex/INPUTS/header1.h b/contrib/llvm/tools/clang/bindings/python/tests/cindex/INPUTS/header1.h deleted file mode 100644 index b4eacbe..0000000 --- a/contrib/llvm/tools/clang/bindings/python/tests/cindex/INPUTS/header1.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef HEADER1 -#define HEADER1 - -#include "header3.h" - -#endif diff --git a/contrib/llvm/tools/clang/bindings/python/tests/cindex/INPUTS/header2.h b/contrib/llvm/tools/clang/bindings/python/tests/cindex/INPUTS/header2.h deleted file mode 100644 index c4eddc0..0000000 --- a/contrib/llvm/tools/clang/bindings/python/tests/cindex/INPUTS/header2.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef HEADER2 -#define HEADER2 - -#include "header3.h" - -#endif diff --git a/contrib/llvm/tools/clang/bindings/python/tests/cindex/INPUTS/header3.h b/contrib/llvm/tools/clang/bindings/python/tests/cindex/INPUTS/header3.h deleted file mode 100644 index 6dca764..0000000 --- a/contrib/llvm/tools/clang/bindings/python/tests/cindex/INPUTS/header3.h +++ /dev/null @@ -1,3 +0,0 @@ -// Not a guarded header! - -void f(); diff --git a/contrib/llvm/tools/clang/bindings/python/tests/cindex/INPUTS/hello.cpp b/contrib/llvm/tools/clang/bindings/python/tests/cindex/INPUTS/hello.cpp deleted file mode 100644 index 7ef086e..0000000 --- a/contrib/llvm/tools/clang/bindings/python/tests/cindex/INPUTS/hello.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "stdio.h" - -int main(int argc, char* argv[]) { - printf("hello world\n"); - return 0; -} diff --git a/contrib/llvm/tools/clang/bindings/python/tests/cindex/INPUTS/include.cpp b/contrib/llvm/tools/clang/bindings/python/tests/cindex/INPUTS/include.cpp deleted file mode 100644 index 60cfdaa..0000000 --- a/contrib/llvm/tools/clang/bindings/python/tests/cindex/INPUTS/include.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "header1.h" -#include "header2.h" -#include "header1.h" - -int main() { } diff --git a/contrib/llvm/tools/clang/bindings/python/tests/cindex/INPUTS/parse_arguments.c b/contrib/llvm/tools/clang/bindings/python/tests/cindex/INPUTS/parse_arguments.c deleted file mode 100644 index 7196486..0000000 --- a/contrib/llvm/tools/clang/bindings/python/tests/cindex/INPUTS/parse_arguments.c +++ /dev/null @@ -1,2 +0,0 @@ -int DECL_ONE = 1; -int DECL_TWO = 2; diff --git a/contrib/llvm/tools/clang/bindings/python/tests/cindex/__init__.py b/contrib/llvm/tools/clang/bindings/python/tests/cindex/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/contrib/llvm/tools/clang/bindings/python/tests/cindex/__init__.py +++ /dev/null diff --git a/contrib/llvm/tools/clang/bindings/python/tests/cindex/test_cursor.py b/contrib/llvm/tools/clang/bindings/python/tests/cindex/test_cursor.py deleted file mode 100644 index a653ba7..0000000 --- a/contrib/llvm/tools/clang/bindings/python/tests/cindex/test_cursor.py +++ /dev/null @@ -1,59 +0,0 @@ -from clang.cindex import Index, CursorKind - -kInput = """\ -// FIXME: Find nicer way to drop builtins and other cruft. -int start_decl; - -struct s0 { - int a; - int b; -}; - -struct s1; - -void f0(int a0, int a1) { - int l0, l1; - - if (a0) - return; - - for (;;) { - break; - } -} -""" - -def test_get_children(): - index = Index.create() - tu = index.parse('t.c', unsaved_files = [('t.c',kInput)]) - - # Skip until past start_decl. - it = tu.cursor.get_children() - while it.next().spelling != 'start_decl': - pass - - tu_nodes = list(it) - - assert len(tu_nodes) == 3 - - assert tu_nodes[0].kind == CursorKind.STRUCT_DECL - assert tu_nodes[0].spelling == 's0' - assert tu_nodes[0].is_definition() == True - assert tu_nodes[0].location.file.name == 't.c' - assert tu_nodes[0].location.line == 4 - assert tu_nodes[0].location.column == 8 - - s0_nodes = list(tu_nodes[0].get_children()) - assert len(s0_nodes) == 2 - assert s0_nodes[0].kind == CursorKind.FIELD_DECL - assert s0_nodes[0].spelling == 'a' - assert s0_nodes[1].kind == CursorKind.FIELD_DECL - assert s0_nodes[1].spelling == 'b' - - assert tu_nodes[1].kind == CursorKind.STRUCT_DECL - assert tu_nodes[1].spelling == 's1' - assert tu_nodes[1].is_definition() == False - - assert tu_nodes[2].kind == CursorKind.FUNCTION_DECL - assert tu_nodes[2].spelling == 'f0' - assert tu_nodes[2].is_definition() == True diff --git a/contrib/llvm/tools/clang/bindings/python/tests/cindex/test_cursor_kind.py b/contrib/llvm/tools/clang/bindings/python/tests/cindex/test_cursor_kind.py deleted file mode 100644 index bdfa318..0000000 --- a/contrib/llvm/tools/clang/bindings/python/tests/cindex/test_cursor_kind.py +++ /dev/null @@ -1,27 +0,0 @@ -from clang.cindex import CursorKind - -def test_name(): - assert CursorKind.UNEXPOSED_DECL.name is 'UNEXPOSED_DECL' - -def test_get_all_kinds(): - assert CursorKind.UNEXPOSED_DECL in CursorKind.get_all_kinds() - assert CursorKind.TRANSLATION_UNIT in CursorKind.get_all_kinds() - -def test_kind_groups(): - """Check that every kind classifies to exactly one group.""" - - assert CursorKind.UNEXPOSED_DECL.is_declaration() - assert CursorKind.TYPE_REF.is_reference() - assert CursorKind.DECL_REF_EXPR.is_expression() - assert CursorKind.UNEXPOSED_STMT.is_statement() - assert CursorKind.INVALID_FILE.is_invalid() - - for k in CursorKind.get_all_kinds(): - group = [n for n in ('is_declaration', 'is_reference', 'is_expression', - 'is_statement', 'is_invalid') - if getattr(k, n)()] - - if k == CursorKind.TRANSLATION_UNIT: - assert len(group) == 0 - else: - assert len(group) == 1 diff --git a/contrib/llvm/tools/clang/bindings/python/tests/cindex/test_diagnostics.py b/contrib/llvm/tools/clang/bindings/python/tests/cindex/test_diagnostics.py deleted file mode 100644 index 8518765..0000000 --- a/contrib/llvm/tools/clang/bindings/python/tests/cindex/test_diagnostics.py +++ /dev/null @@ -1,48 +0,0 @@ -from clang.cindex import * - -def tu_from_source(source): - index = Index.create() - tu = index.parse('INPUT.c', unsaved_files = [('INPUT.c', source)]) - # FIXME: Remove the need for this. - tu.index = index - return tu - -# FIXME: We need support for invalid translation units to test better. - -def test_diagnostic_warning(): - tu = tu_from_source("""int f0() {}\n""") - assert len(tu.diagnostics) == 1 - assert tu.diagnostics[0].severity == Diagnostic.Warning - assert tu.diagnostics[0].location.line == 1 - assert tu.diagnostics[0].location.column == 11 - assert (tu.diagnostics[0].spelling == - 'control reaches end of non-void function') - -def test_diagnostic_note(): - # FIXME: We aren't getting notes here for some reason. - index = Index.create() - tu = tu_from_source("""#define A x\nvoid *A = 1;\n""") - assert len(tu.diagnostics) == 1 - assert tu.diagnostics[0].severity == Diagnostic.Warning - assert tu.diagnostics[0].location.line == 2 - assert tu.diagnostics[0].location.column == 7 - assert 'incompatible' in tu.diagnostics[0].spelling -# assert tu.diagnostics[1].severity == Diagnostic.Note -# assert tu.diagnostics[1].location.line == 1 -# assert tu.diagnostics[1].location.column == 11 -# assert tu.diagnostics[1].spelling == 'instantiated from' - -def test_diagnostic_fixit(): - index = Index.create() - tu = tu_from_source("""struct { int f0; } x = { f0 : 1 };""") - assert len(tu.diagnostics) == 1 - assert tu.diagnostics[0].severity == Diagnostic.Warning - assert tu.diagnostics[0].location.line == 1 - assert tu.diagnostics[0].location.column == 31 - assert tu.diagnostics[0].spelling.startswith('use of GNU old-style') - assert len(tu.diagnostics[0].fixits) == 1 - assert tu.diagnostics[0].fixits[0].range.start.line == 1 - assert tu.diagnostics[0].fixits[0].range.start.column == 26 - assert tu.diagnostics[0].fixits[0].range.end.line == 1 - assert tu.diagnostics[0].fixits[0].range.end.column == 30 - assert tu.diagnostics[0].fixits[0].value == '.f0 = ' diff --git a/contrib/llvm/tools/clang/bindings/python/tests/cindex/test_index.py b/contrib/llvm/tools/clang/bindings/python/tests/cindex/test_index.py deleted file mode 100644 index dc173f0..0000000 --- a/contrib/llvm/tools/clang/bindings/python/tests/cindex/test_index.py +++ /dev/null @@ -1,15 +0,0 @@ -from clang.cindex import * -import os - -kInputsDir = os.path.join(os.path.dirname(__file__), 'INPUTS') - -def test_create(): - index = Index.create() - -# FIXME: test Index.read - -def test_parse(): - index = Index.create() - assert isinstance(index, Index) - tu = index.parse(os.path.join(kInputsDir, 'hello.cpp')) - assert isinstance(tu, TranslationUnit) diff --git a/contrib/llvm/tools/clang/bindings/python/tests/cindex/test_translation_unit.py b/contrib/llvm/tools/clang/bindings/python/tests/cindex/test_translation_unit.py deleted file mode 100644 index 3c05c3f..0000000 --- a/contrib/llvm/tools/clang/bindings/python/tests/cindex/test_translation_unit.py +++ /dev/null @@ -1,73 +0,0 @@ -from clang.cindex import * -import os - -kInputsDir = os.path.join(os.path.dirname(__file__), 'INPUTS') - -def test_spelling(): - path = os.path.join(kInputsDir, 'hello.cpp') - index = Index.create() - tu = index.parse(path) - assert tu.spelling == path - -def test_cursor(): - path = os.path.join(kInputsDir, 'hello.cpp') - index = Index.create() - tu = index.parse(path) - c = tu.cursor - assert isinstance(c, Cursor) - assert c.kind is CursorKind.TRANSLATION_UNIT - -def test_parse_arguments(): - path = os.path.join(kInputsDir, 'parse_arguments.c') - index = Index.create() - tu = index.parse(path, ['-DDECL_ONE=hello', '-DDECL_TWO=hi']) - spellings = [c.spelling for c in tu.cursor.get_children()] - assert spellings[-2] == 'hello' - assert spellings[-1] == 'hi' - -def test_unsaved_files(): - index = Index.create() - # FIXME: Why can't we just use "fake.h" here (instead of /tmp/fake.h)? - tu = index.parse('fake.c', unsaved_files = [ - ('fake.c', """ -#include "/tmp/fake.h" -int x; -int SOME_DEFINE; -"""), - ('/tmp/fake.h', """ -#define SOME_DEFINE y -""") - ]) - spellings = [c.spelling for c in tu.cursor.get_children()] - assert spellings[-2] == 'x' - assert spellings[-1] == 'y' - -def test_unsaved_files_2(): - import StringIO - index = Index.create() - tu = index.parse('fake.c', unsaved_files = [ - ('fake.c', StringIO.StringIO('int x;'))]) - spellings = [c.spelling for c in tu.cursor.get_children()] - assert spellings[-1] == 'x' - - -def test_includes(): - def eq(expected, actual): - if not actual.is_input_file: - return expected[0] == actual.source.name and \ - expected[1] == actual.include.name - else: - return expected[1] == actual.include.name - - src = os.path.join(kInputsDir, 'include.cpp') - h1 = os.path.join(kInputsDir, "header1.h") - h2 = os.path.join(kInputsDir, "header2.h") - h3 = os.path.join(kInputsDir, "header3.h") - inc = [(None, src), (src, h1), (h1, h3), (src, h2), (h2, h3)] - - index = Index.create() - tu = index.parse(src) - for i in zip(inc, tu.get_includes()): - assert eq(i[0], i[1]) - - diff --git a/contrib/llvm/tools/clang/include/CMakeLists.txt b/contrib/llvm/tools/clang/include/CMakeLists.txt deleted file mode 100644 index 253a09b..0000000 --- a/contrib/llvm/tools/clang/include/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -add_subdirectory(clang) diff --git a/contrib/llvm/tools/clang/include/Makefile b/contrib/llvm/tools/clang/include/Makefile deleted file mode 100644 index 79b9adf..0000000 --- a/contrib/llvm/tools/clang/include/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -CLANG_LEVEL := .. -DIRS := clang clang-c - -include $(CLANG_LEVEL)/Makefile diff --git a/contrib/llvm/tools/clang/include/clang-c/Makefile b/contrib/llvm/tools/clang/include/clang-c/Makefile deleted file mode 100644 index 98ea719..0000000 --- a/contrib/llvm/tools/clang/include/clang-c/Makefile +++ /dev/null @@ -1,31 +0,0 @@ -CLANG_LEVEL := ../.. -DIRS := - -include $(CLANG_LEVEL)/Makefile - -install-local:: - $(Echo) Installing Clang C API include files - $(Verb) $(MKDIR) $(DESTDIR)$(PROJ_includedir) - $(Verb) if test -d "$(PROJ_SRC_ROOT)/tools/clang/include/clang-c" ; then \ - cd $(PROJ_SRC_ROOT)/tools/clang/include && \ - for hdr in `find clang-c -type f '!' '(' -name '*~' \ - -o -name '.#*' -o -name '*.in' -o -name '*.txt' \ - -o -name 'Makefile' -o -name '*.td' ')' -print \ - | grep -v CVS | grep -v .svn | grep -v .dir` ; do \ - instdir=$(DESTDIR)`dirname "$(PROJ_includedir)/$$hdr"` ; \ - if test \! -d "$$instdir" ; then \ - $(EchoCmd) Making install directory $$instdir ; \ - $(MKDIR) $$instdir ;\ - fi ; \ - $(DataInstall) $$hdr $(DESTDIR)$(PROJ_includedir)/$$hdr ; \ - done ; \ - fi -ifneq ($(PROJ_SRC_ROOT),$(PROJ_OBJ_ROOT)) - $(Verb) if test -d "$(PROJ_OBJ_ROOT)/tools/clang/include/clang-c" ; then \ - cd $(PROJ_OBJ_ROOT)/tools/clang/include && \ - for hdr in `find clang-c -type f '!' '(' -name 'Makefile' ')' -print \ - | grep -v CVS | grep -v .tmp | grep -v .dir` ; do \ - $(DataInstall) $$hdr $(DESTDIR)$(PROJ_includedir)/$$hdr ; \ - done ; \ - fi -endif diff --git a/contrib/llvm/tools/clang/include/clang/AST/CMakeLists.txt b/contrib/llvm/tools/clang/include/clang/AST/CMakeLists.txt deleted file mode 100644 index 800c583..0000000 --- a/contrib/llvm/tools/clang/include/clang/AST/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ -set(LLVM_TARGET_DEFINITIONS ../Basic/Attr.td) -tablegen(Attrs.inc - -gen-clang-attr-classes - -I ${CMAKE_CURRENT_SOURCE_DIR}/../../) -add_custom_target(ClangAttrClasses - DEPENDS Attrs.inc) - -tablegen(AttrImpl.inc - -gen-clang-attr-impl - -I ${CMAKE_CURRENT_SOURCE_DIR}/../../) -add_custom_target(ClangAttrImpl - DEPENDS AttrImpl.inc) - -set(LLVM_TARGET_DEFINITIONS ../Basic/StmtNodes.td) -tablegen(StmtNodes.inc - -gen-clang-stmt-nodes) -add_custom_target(ClangStmtNodes - DEPENDS StmtNodes.inc) - -set(LLVM_TARGET_DEFINITIONS ../Basic/DeclNodes.td) -tablegen(DeclNodes.inc - -gen-clang-decl-nodes) -add_custom_target(ClangDeclNodes - DEPENDS DeclNodes.inc) diff --git a/contrib/llvm/tools/clang/include/clang/AST/Makefile b/contrib/llvm/tools/clang/include/clang/AST/Makefile deleted file mode 100644 index 6ba6e89..0000000 --- a/contrib/llvm/tools/clang/include/clang/AST/Makefile +++ /dev/null @@ -1,29 +0,0 @@ -CLANG_LEVEL := ../../.. -TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic -BUILT_SOURCES = Attrs.inc AttrImpl.inc StmtNodes.inc DeclNodes.inc - -TABLEGEN_INC_FILES_COMMON = 1 - -include $(CLANG_LEVEL)/Makefile - -$(ObjDir)/Attrs.inc.tmp : $(TD_SRC_DIR)/Attr.td $(TBLGEN) \ - $(ObjDir)/.dir - $(Echo) "Building Clang attribute classes with tblgen" - $(Verb) $(TableGen) -gen-clang-attr-classes -o $(call SYSPATH, $@) \ - -I $(PROJ_SRC_DIR)/../../ $< - -$(ObjDir)/AttrImpl.inc.tmp : $(TD_SRC_DIR)/Attr.td $(TBLGEN) \ - $(ObjDir)/.dir - $(Echo) "Building Clang attribute implementations with tblgen" - $(Verb) $(TableGen) -gen-clang-attr-impl -o $(call SYSPATH, $@) \ - -I $(PROJ_SRC_DIR)/../../ $< - -$(ObjDir)/StmtNodes.inc.tmp : $(TD_SRC_DIR)/StmtNodes.td $(TBLGEN) \ - $(ObjDir)/.dir - $(Echo) "Building Clang statement node tables with tblgen" - $(Verb) $(TableGen) -gen-clang-stmt-nodes -o $(call SYSPATH, $@) $< - -$(ObjDir)/DeclNodes.inc.tmp : $(TD_SRC_DIR)/DeclNodes.td $(TBLGEN) \ - $(ObjDir)/.dir - $(Echo) "Building Clang declaration node tables with tblgen" - $(Verb) $(TableGen) -gen-clang-decl-nodes -o $(call SYSPATH, $@) $< diff --git a/contrib/llvm/tools/clang/include/clang/Basic/CMakeLists.txt b/contrib/llvm/tools/clang/include/clang/Basic/CMakeLists.txt deleted file mode 100644 index c595236..0000000 --- a/contrib/llvm/tools/clang/include/clang/Basic/CMakeLists.txt +++ /dev/null @@ -1,32 +0,0 @@ -macro(clang_diag_gen component) - tablegen(Diagnostic${component}Kinds.inc - -gen-clang-diags-defs -clang-component=${component}) - add_custom_target(ClangDiagnostic${component} - DEPENDS Diagnostic${component}Kinds.inc) -endmacro(clang_diag_gen) - -set(LLVM_TARGET_DEFINITIONS Diagnostic.td) -clang_diag_gen(Analysis) -clang_diag_gen(AST) -clang_diag_gen(Common) -clang_diag_gen(Driver) -clang_diag_gen(Frontend) -clang_diag_gen(Lex) -clang_diag_gen(Parse) -clang_diag_gen(Sema) -tablegen(DiagnosticGroups.inc - -gen-clang-diag-groups) -add_custom_target(ClangDiagnosticGroups - DEPENDS DiagnosticGroups.inc) - -set(LLVM_TARGET_DEFINITIONS Attr.td) -tablegen(AttrList.inc - -gen-clang-attr-list - -I ${CMAKE_CURRENT_SOURCE_DIR}/../../) -add_custom_target(ClangAttrList - DEPENDS AttrList.inc) - -# ARM NEON -set(LLVM_TARGET_DEFINITIONS arm_neon.td) -tablegen(arm_neon.inc -gen-arm-neon-sema) -add_custom_target(ClangARMNeon DEPENDS arm_neon.inc) diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Makefile b/contrib/llvm/tools/clang/include/clang/Basic/Makefile deleted file mode 100644 index bc64f6aa..0000000 --- a/contrib/llvm/tools/clang/include/clang/Basic/Makefile +++ /dev/null @@ -1,56 +0,0 @@ -CLANG_LEVEL := ../../.. -BUILT_SOURCES = \ - DiagnosticAnalysisKinds.inc DiagnosticASTKinds.inc \ - DiagnosticCommonKinds.inc DiagnosticDriverKinds.inc \ - DiagnosticFrontendKinds.inc DiagnosticLexKinds.inc \ - DiagnosticParseKinds.inc DiagnosticSemaKinds.inc \ - DiagnosticGroups.inc AttrList.inc arm_neon.inc \ - Version.inc - -TABLEGEN_INC_FILES_COMMON = 1 - -include $(CLANG_LEVEL)/Makefile - -INPUT_TDS = $(wildcard $(PROJ_SRC_DIR)/Diagnostic*.td) - -# Compute the Clang version from the LLVM version, unless specified explicitly. -ifndef CLANG_VERSION -CLANG_VERSION := $(subst svn,,$(LLVMVersion)) -CLANG_VERSION := $(subst rc,,$(CLANG_VERSION)) -endif - -CLANG_VERSION_COMPONENTS := $(subst ., ,$(CLANG_VERSION)) -CLANG_VERSION_MAJOR := $(word 1,$(CLANG_VERSION_COMPONENTS)) -CLANG_VERSION_MINOR := $(word 2,$(CLANG_VERSION_COMPONENTS)) -CLANG_VERSION_PATCHLEVEL := $(word 3,$(CLANG_VERSION_COMPONENTS)) -ifeq ($(CLANG_VERSION_PATCHLEVEL),) -CLANG_HAS_VERSION_PATCHLEVEL := 0 -else -CLANG_HAS_VERSION_PATCHLEVEL := 1 -endif - -$(ObjDir)/Diagnostic%Kinds.inc.tmp : Diagnostic.td Diagnostic%Kinds.td $(TBLGEN) $(ObjDir)/.dir - $(Echo) "Building Clang $(patsubst Diagnostic%Kinds.inc.tmp,%,$(@F)) diagnostic tables with tblgen" - $(Verb) $(TableGen) -gen-clang-diags-defs -clang-component=$(patsubst Diagnostic%Kinds.inc.tmp,%,$(@F)) -o $(call SYSPATH, $@) $< - -$(ObjDir)/DiagnosticGroups.inc.tmp : Diagnostic.td DiagnosticGroups.td $(INPUT_TDS) $(TBLGEN) $(ObjDir)/.dir - $(Echo) "Building Clang diagnostic groups with tblgen" - $(Verb) $(TableGen) -gen-clang-diag-groups -o $(call SYSPATH, $@) $< - -$(ObjDir)/AttrList.inc.tmp : Attr.td $(TBLGEN) $(ObjDir)/.dir - $(Echo) "Building Clang attribute list with tblgen" - $(Verb) $(TableGen) -gen-clang-attr-list -o $(call SYSPATH, $@) \ - -I $(PROJ_SRC_DIR)/../.. $< - -$(ObjDir)/arm_neon.inc.tmp : arm_neon.td $(TBLGEN) $(ObjDir)/.dir - $(Echo) "Building Clang arm_neon.inc with tblgen" - $(Verb) $(TableGen) -gen-arm-neon-sema -o $(call SYSPATH, $@) $< - -$(ObjDir)/Version.inc.tmp : Version.inc.in Makefile $(LLVM_OBJ_ROOT)/Makefile.config $(ObjDir)/.dir - $(Echo) "Updating Clang version info." - $(Verb)sed -e "s#@CLANG_VERSION@#$(CLANG_VERSION)#g" \ - -e "s#@CLANG_VERSION_MAJOR@#$(CLANG_VERSION_MAJOR)#g" \ - -e "s#@CLANG_VERSION_MINOR@#$(CLANG_VERSION_MINOR)#g" \ - -e "s#@CLANG_VERSION_PATCHLEVEL@#$(CLANG_VERSION_PATCHLEVEL)#g" \ - -e "s#@CLANG_HAS_VERSION_PATCHLEVEL@#$(CLANG_HAS_VERSION_PATCHLEVEL)#g" \ - $< > $@ diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Version.inc.in b/contrib/llvm/tools/clang/include/clang/Basic/Version.inc.in deleted file mode 100644 index ccf8430..0000000 --- a/contrib/llvm/tools/clang/include/clang/Basic/Version.inc.in +++ /dev/null @@ -1,6 +0,0 @@ -#define CLANG_VERSION @CLANG_VERSION@ -#define CLANG_VERSION_MAJOR @CLANG_VERSION_MAJOR@ -#define CLANG_VERSION_MINOR @CLANG_VERSION_MINOR@ -#if @CLANG_HAS_VERSION_PATCHLEVEL@ -#define CLANG_VERSION_PATCHLEVEL @CLANG_VERSION_PATCHLEVEL@ -#endif diff --git a/contrib/llvm/tools/clang/include/clang/CMakeLists.txt b/contrib/llvm/tools/clang/include/clang/CMakeLists.txt deleted file mode 100644 index e82cf42..0000000 --- a/contrib/llvm/tools/clang/include/clang/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -add_subdirectory(AST) -add_subdirectory(Basic) -add_subdirectory(Driver) -add_subdirectory(Serialization) diff --git a/contrib/llvm/tools/clang/include/clang/Driver/CMakeLists.txt b/contrib/llvm/tools/clang/include/clang/Driver/CMakeLists.txt deleted file mode 100644 index 99be53f..0000000 --- a/contrib/llvm/tools/clang/include/clang/Driver/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -set(LLVM_TARGET_DEFINITIONS Options.td) -tablegen(Options.inc - -gen-opt-parser-defs) -add_custom_target(ClangDriverOptions - DEPENDS Options.inc) - -set(LLVM_TARGET_DEFINITIONS CC1Options.td) -tablegen(CC1Options.inc - -gen-opt-parser-defs) -add_custom_target(ClangCC1Options - DEPENDS CC1Options.inc) - -set(LLVM_TARGET_DEFINITIONS CC1AsOptions.td) -tablegen(CC1AsOptions.inc - -gen-opt-parser-defs) -add_custom_target(ClangCC1AsOptions - DEPENDS CC1AsOptions.inc) diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Makefile b/contrib/llvm/tools/clang/include/clang/Driver/Makefile deleted file mode 100644 index d829166..0000000 --- a/contrib/llvm/tools/clang/include/clang/Driver/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -CLANG_LEVEL := ../../.. -BUILT_SOURCES = Options.inc CC1Options.inc CC1AsOptions.inc - -TABLEGEN_INC_FILES_COMMON = 1 - -include $(CLANG_LEVEL)/Makefile - -$(ObjDir)/Options.inc.tmp : Options.td OptParser.td $(TBLGEN) $(ObjDir)/.dir - $(Echo) "Building Clang Driver Option tables with tblgen" - $(Verb) $(TableGen) -gen-opt-parser-defs -o $(call SYSPATH, $@) $< - -$(ObjDir)/CC1Options.inc.tmp : CC1Options.td OptParser.td $(TBLGEN) $(ObjDir)/.dir - $(Echo) "Building Clang CC1 Option tables with tblgen" - $(Verb) $(TableGen) -gen-opt-parser-defs -o $(call SYSPATH, $@) $< - -$(ObjDir)/CC1AsOptions.inc.tmp : CC1AsOptions.td OptParser.td $(TBLGEN) $(ObjDir)/.dir - $(Echo) "Building Clang CC1 Assembler Option tables with tblgen" - $(Verb) $(TableGen) -gen-opt-parser-defs -o $(call SYSPATH, $@) $< diff --git a/contrib/llvm/tools/clang/include/clang/Makefile b/contrib/llvm/tools/clang/include/clang/Makefile deleted file mode 100644 index 030b072..0000000 --- a/contrib/llvm/tools/clang/include/clang/Makefile +++ /dev/null @@ -1,31 +0,0 @@ -CLANG_LEVEL := ../.. -DIRS := AST Basic Driver Serialization - -include $(CLANG_LEVEL)/Makefile - -install-local:: - $(Echo) Installing Clang include files - $(Verb) $(MKDIR) $(DESTDIR)$(PROJ_includedir) - $(Verb) if test -d "$(PROJ_SRC_ROOT)/tools/clang/include/clang" ; then \ - cd $(PROJ_SRC_ROOT)/tools/clang/include && \ - for hdr in `find clang -type f '!' '(' -name '*~' \ - -o -name '.#*' -o -name '*.in' -o -name '*.txt' \ - -o -name 'Makefile' -o -name '*.td' -o -name '*.orig' ')' -print \ - | grep -v CVS | grep -v .svn | grep -v .dir` ; do \ - instdir=$(DESTDIR)`dirname "$(PROJ_includedir)/$$hdr"` ; \ - if test \! -d "$$instdir" ; then \ - $(EchoCmd) Making install directory $$instdir ; \ - $(MKDIR) $$instdir ;\ - fi ; \ - $(DataInstall) $$hdr $(DESTDIR)$(PROJ_includedir)/$$hdr ; \ - done ; \ - fi -ifneq ($(PROJ_SRC_ROOT),$(PROJ_OBJ_ROOT)) - $(Verb) if test -d "$(PROJ_OBJ_ROOT)/tools/clang/include/clang" ; then \ - cd $(PROJ_OBJ_ROOT)/tools/clang/include && \ - for hdr in `find clang -type f '!' '(' -name 'Makefile' ')' -print \ - | grep -v CVS | grep -v .tmp | grep -v .dir` ; do \ - $(DataInstall) $$hdr $(DESTDIR)$(PROJ_includedir)/$$hdr ; \ - done ; \ - fi -endif diff --git a/contrib/llvm/tools/clang/include/clang/Serialization/CMakeLists.txt b/contrib/llvm/tools/clang/include/clang/Serialization/CMakeLists.txt deleted file mode 100644 index 3712009..0000000 --- a/contrib/llvm/tools/clang/include/clang/Serialization/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -set(LLVM_TARGET_DEFINITIONS ../Basic/Attr.td) -tablegen(AttrPCHRead.inc - -gen-clang-attr-pch-read - -I ${CMAKE_CURRENT_SOURCE_DIR}/../../) -add_custom_target(ClangAttrPCHRead - DEPENDS AttrPCHRead.inc) - -tablegen(AttrPCHWrite.inc - -gen-clang-attr-pch-write - -I ${CMAKE_CURRENT_SOURCE_DIR}/../../) -add_custom_target(ClangAttrPCHWrite - DEPENDS AttrPCHWrite.inc) diff --git a/contrib/llvm/tools/clang/include/clang/Serialization/Makefile b/contrib/llvm/tools/clang/include/clang/Serialization/Makefile deleted file mode 100644 index 79486b1..0000000 --- a/contrib/llvm/tools/clang/include/clang/Serialization/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -CLANG_LEVEL := ../../.. -TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic -BUILT_SOURCES = AttrPCHRead.inc AttrPCHWrite.inc - -TABLEGEN_INC_FILES_COMMON = 1 - -include $(CLANG_LEVEL)/Makefile - -$(ObjDir)/AttrPCHRead.inc.tmp : $(TD_SRC_DIR)/Attr.td $(TBLGEN) \ - $(ObjDir)/.dir - $(Echo) "Building Clang PCH reader with tblgen" - $(Verb) $(TableGen) -gen-clang-attr-pch-read -o $(call SYSPATH, $@) \ - -I $(PROJ_SRC_DIR)/../../ $< - -$(ObjDir)/AttrPCHWrite.inc.tmp : $(TD_SRC_DIR)/Attr.td $(TBLGEN) \ - $(ObjDir)/.dir - $(Echo) "Building Clang PCH writer with tblgen" - $(Verb) $(TableGen) -gen-clang-attr-pch-write -o $(call SYSPATH, $@) \ - -I $(PROJ_SRC_DIR)/../../ $< diff --git a/contrib/llvm/tools/clang/lib/AST/CMakeLists.txt b/contrib/llvm/tools/clang/lib/AST/CMakeLists.txt deleted file mode 100644 index 82a81ec..0000000 --- a/contrib/llvm/tools/clang/lib/AST/CMakeLists.txt +++ /dev/null @@ -1,46 +0,0 @@ -set(LLVM_NO_RTTI 1) - -add_clang_library(clangAST - APValue.cpp - ASTConsumer.cpp - ASTContext.cpp - ASTDiagnostic.cpp - ASTImporter.cpp - AttrImpl.cpp - CXXInheritance.cpp - Decl.cpp - DeclarationName.cpp - DeclBase.cpp - DeclCXX.cpp - DeclFriend.cpp - DeclGroup.cpp - DeclObjC.cpp - DeclPrinter.cpp - DeclTemplate.cpp - Expr.cpp - ExprClassification.cpp - ExprConstant.cpp - ExprCXX.cpp - FullExpr.cpp - InheritViz.cpp - ItaniumCXXABI.cpp - MicrosoftCXXABI.cpp - NestedNameSpecifier.cpp - ParentMap.cpp - RecordLayout.cpp - RecordLayoutBuilder.cpp - Stmt.cpp - StmtDumper.cpp - StmtIterator.cpp - StmtPrinter.cpp - StmtProfile.cpp - StmtViz.cpp - TemplateBase.cpp - TemplateName.cpp - Type.cpp - TypeLoc.cpp - TypePrinter.cpp - ) - -add_dependencies(clangAST ClangARMNeon ClangAttrClasses ClangAttrList - ClangAttrImpl ClangDiagnosticAST ClangDeclNodes ClangStmtNodes) diff --git a/contrib/llvm/tools/clang/lib/AST/Makefile b/contrib/llvm/tools/clang/lib/AST/Makefile deleted file mode 100644 index 65383c5..0000000 --- a/contrib/llvm/tools/clang/lib/AST/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -##===- clang/lib/AST/Makefile ------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -# -# This implements the AST library for the C-Language front-end. -# -##===----------------------------------------------------------------------===## - -CLANG_LEVEL := ../.. -LIBRARYNAME := clangAST - -include $(CLANG_LEVEL)/Makefile - diff --git a/contrib/llvm/tools/clang/lib/Analysis/CMakeLists.txt b/contrib/llvm/tools/clang/lib/Analysis/CMakeLists.txt deleted file mode 100644 index 850e9b4..0000000 --- a/contrib/llvm/tools/clang/lib/Analysis/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -set(LLVM_NO_RTTI 1) - -add_clang_library(clangAnalysis - AnalysisContext.cpp - CFG.cpp - CFGStmtMap.cpp - FormatString.cpp - LiveVariables.cpp - PrintfFormatString.cpp - PseudoConstantAnalysis.cpp - ReachableCode.cpp - ScanfFormatString.cpp - UninitializedValues.cpp - ) - -add_dependencies(clangAnalysis ClangAttrClasses ClangAttrList - ClangDiagnosticAnalysis ClangDeclNodes ClangStmtNodes) diff --git a/contrib/llvm/tools/clang/lib/Analysis/Makefile b/contrib/llvm/tools/clang/lib/Analysis/Makefile deleted file mode 100644 index fbbb83d..0000000 --- a/contrib/llvm/tools/clang/lib/Analysis/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -##===- clang/lib/Analysis/Makefile -------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -# -# This implements analyses built on top of source-level CFGs. -# -##===----------------------------------------------------------------------===## - -CLANG_LEVEL := ../.. -LIBRARYNAME := clangAnalysis - -include $(CLANG_LEVEL)/Makefile - diff --git a/contrib/llvm/tools/clang/lib/Basic/CMakeLists.txt b/contrib/llvm/tools/clang/lib/Basic/CMakeLists.txt deleted file mode 100644 index 87bf834..0000000 --- a/contrib/llvm/tools/clang/lib/Basic/CMakeLists.txt +++ /dev/null @@ -1,39 +0,0 @@ -set(LLVM_NO_RTTI 1) - -add_clang_library(clangBasic - Builtins.cpp - ConvertUTF.c - Diagnostic.cpp - FileManager.cpp - IdentifierTable.cpp - SourceLocation.cpp - SourceManager.cpp - TargetInfo.cpp - Targets.cpp - TokenKinds.cpp - Version.cpp - ) - -# Determine Subversion revision. -# FIXME: This only gets updated when CMake is run, so this revision number -# may be out-of-date! -find_package(Subversion) -if (Subversion_FOUND AND EXISTS "${CLANG_SOURCE_DIR}/.svn") - Subversion_WC_INFO(${CLANG_SOURCE_DIR} CLANG) - set_source_files_properties(Version.cpp - PROPERTIES COMPILE_DEFINITIONS "SVN_REVISION=\"${CLANG_WC_REVISION}\"") -endif() - -add_dependencies(clangBasic - ClangARMNeon - ClangAttrList - ClangDiagnosticAnalysis - ClangDiagnosticAST - ClangDiagnosticCommon - ClangDiagnosticDriver - ClangDiagnosticFrontend - ClangDiagnosticGroups - ClangDiagnosticLex - ClangDiagnosticParse - ClangDiagnosticSema) - diff --git a/contrib/llvm/tools/clang/lib/Basic/Makefile b/contrib/llvm/tools/clang/lib/Basic/Makefile deleted file mode 100644 index c156304..0000000 --- a/contrib/llvm/tools/clang/lib/Basic/Makefile +++ /dev/null @@ -1,29 +0,0 @@ -##===- clang/lib/Basic/Makefile ----------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -# -# This implements the Basic library for the C-Language front-end. -# -##===----------------------------------------------------------------------===## - -CLANG_LEVEL := ../.. -LIBRARYNAME := clangBasic - -include $(CLANG_LEVEL)/Makefile - -SVN_REVISION := $(shell $(LLVM_SRC_ROOT)/utils/GetSourceVersion $(PROJ_SRC_DIR)/../..) - -CPP.Defines += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include \ - -DSVN_REVISION='"$(SVN_REVISION)"' - -$(ObjDir)/.ver-svn .ver: $(ObjDir)/.dir - @if [ '$(SVN_REVISION)' != '$(shell cat $(ObjDir)/.ver-svn 2>/dev/null)' ]; then\ - echo '$(SVN_REVISION)' > $(ObjDir)/.ver-svn; \ - fi -$(ObjDir)/.ver-svn: .ver -$(ObjDir)/Version.o: $(ObjDir)/.ver-svn diff --git a/contrib/llvm/tools/clang/lib/CMakeLists.txt b/contrib/llvm/tools/clang/lib/CMakeLists.txt deleted file mode 100644 index bd5e342..0000000 --- a/contrib/llvm/tools/clang/lib/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -add_subdirectory(Headers) -add_subdirectory(Basic) -add_subdirectory(Lex) -add_subdirectory(Parse) -add_subdirectory(AST) -add_subdirectory(Sema) -add_subdirectory(CodeGen) -add_subdirectory(Analysis) -add_subdirectory(Rewrite) -add_subdirectory(Driver) -add_subdirectory(Serialization) -add_subdirectory(Frontend) -add_subdirectory(FrontendTool) -add_subdirectory(Index) -add_subdirectory(Checker) diff --git a/contrib/llvm/tools/clang/lib/Checker/CMakeLists.txt b/contrib/llvm/tools/clang/lib/Checker/CMakeLists.txt deleted file mode 100644 index 5b54f0d..0000000 --- a/contrib/llvm/tools/clang/lib/Checker/CMakeLists.txt +++ /dev/null @@ -1,84 +0,0 @@ -set(LLVM_NO_RTTI 1) - -add_clang_library(clangChecker - AdjustedReturnValueChecker.cpp - AggExprVisitor.cpp - AnalysisConsumer.cpp - AnalysisManager.cpp - ArrayBoundChecker.cpp - AttrNonNullChecker.cpp - BasicConstraintManager.cpp - BasicObjCFoundationChecks.cpp - BasicStore.cpp - BasicValueFactory.cpp - BugReporter.cpp - BugReporterVisitors.cpp - BuiltinFunctionChecker.cpp - CFRefCount.cpp - CallAndMessageChecker.cpp - CastSizeChecker.cpp - CastToStructChecker.cpp - CheckDeadStores.cpp - CheckObjCDealloc.cpp - CheckObjCInstMethSignature.cpp - CheckSecuritySyntaxOnly.cpp - CheckSizeofPointer.cpp - Checker.cpp - CheckerHelpers.cpp - CocoaConventions.cpp - CStringChecker.cpp - DereferenceChecker.cpp - DivZeroChecker.cpp - Environment.cpp - ExplodedGraph.cpp - FixedAddressChecker.cpp - FlatStore.cpp - FrontendActions.cpp - GRBlockCounter.cpp - GRCXXExprEngine.cpp - GRCoreEngine.cpp - GRExprEngine.cpp - GRExprEngineExperimentalChecks.cpp - GRState.cpp - HTMLDiagnostics.cpp - IdempotentOperationChecker.cpp - LLVMConventionsChecker.cpp - MacOSXAPIChecker.cpp - MallocChecker.cpp - ManagerRegistry.cpp - MemRegion.cpp - NSAutoreleasePoolChecker.cpp - NSErrorChecker.cpp - NoReturnFunctionChecker.cpp - OSAtomicChecker.cpp - ObjCUnusedIVarsChecker.cpp - PathDiagnostic.cpp - PlistDiagnostics.cpp - PointerArithChecker.cpp - PointerSubChecker.cpp - PthreadLockChecker.cpp - RangeConstraintManager.cpp - RegionStore.cpp - ReturnPointerRangeChecker.cpp - ReturnUndefChecker.cpp - SVals.cpp - SValuator.cpp - SimpleConstraintManager.cpp - SimpleSValuator.cpp - StackAddrLeakChecker.cpp - Store.cpp - StreamChecker.cpp - SymbolManager.cpp - UndefBranchChecker.cpp - UndefCapturedBlockVarChecker.cpp - UndefResultChecker.cpp - UndefinedArraySubscriptChecker.cpp - UndefinedAssignmentChecker.cpp - UnixAPIChecker.cpp - UnreachableCodeChecker.cpp - VLASizeChecker.cpp - ValueManager.cpp - ) - -add_dependencies(clangChecker ClangAttrClasses ClangAttrList ClangDeclNodes - ClangStmtNodes) diff --git a/contrib/llvm/tools/clang/lib/Checker/Makefile b/contrib/llvm/tools/clang/lib/Checker/Makefile deleted file mode 100644 index 4ec6f65..0000000 --- a/contrib/llvm/tools/clang/lib/Checker/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -##===- clang/lib/Checker/Makefile --------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -# -# This implements analyses built on top of source-level CFGs. -# -##===----------------------------------------------------------------------===## - -CLANG_LEVEL := ../.. -LIBRARYNAME := clangChecker - -include $(CLANG_LEVEL)/Makefile - diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CMakeLists.txt b/contrib/llvm/tools/clang/lib/CodeGen/CMakeLists.txt deleted file mode 100644 index b5a2329..0000000 --- a/contrib/llvm/tools/clang/lib/CodeGen/CMakeLists.txt +++ /dev/null @@ -1,41 +0,0 @@ -set(LLVM_NO_RTTI 1) - -add_clang_library(clangCodeGen - BackendUtil.cpp - CGBlocks.cpp - CGBuiltin.cpp - CGCall.cpp - CGClass.cpp - CGCXX.cpp - CGDebugInfo.cpp - CGDecl.cpp - CGDeclCXX.cpp - CGException.cpp - CGExpr.cpp - CGExprAgg.cpp - CGExprComplex.cpp - CGExprConstant.cpp - CGExprCXX.cpp - CGExprScalar.cpp - CGObjC.cpp - CGObjCGNU.cpp - CGObjCMac.cpp - CGRecordLayoutBuilder.cpp - CGRTTI.cpp - CGStmt.cpp - CGTemporaries.cpp - CGVTables.cpp - CGVTT.cpp - CodeGenAction.cpp - CodeGenFunction.cpp - CodeGenModule.cpp - CodeGenTypes.cpp - ItaniumCXXABI.cpp - Mangle.cpp - MicrosoftCXXABI.cpp - ModuleBuilder.cpp - TargetInfo.cpp - ) - -add_dependencies(clangCodeGen ClangAttrClasses ClangAttrList ClangDeclNodes - ClangStmtNodes) diff --git a/contrib/llvm/tools/clang/lib/CodeGen/Makefile b/contrib/llvm/tools/clang/lib/CodeGen/Makefile deleted file mode 100644 index 6032dff..0000000 --- a/contrib/llvm/tools/clang/lib/CodeGen/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -##===- clang/lib/CodeGen/Makefile --------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -# -# This implements the AST -> LLVM code generation library for the -# C-Language front-end. -# -##===----------------------------------------------------------------------===## - -CLANG_LEVEL := ../.. -LIBRARYNAME := clangCodeGen - -include $(CLANG_LEVEL)/Makefile - diff --git a/contrib/llvm/tools/clang/lib/CodeGen/README.txt b/contrib/llvm/tools/clang/lib/CodeGen/README.txt deleted file mode 100644 index e6d6109..0000000 --- a/contrib/llvm/tools/clang/lib/CodeGen/README.txt +++ /dev/null @@ -1,47 +0,0 @@ -IRgen optimization opportunities. - -//===---------------------------------------------------------------------===// - -The common pattern of --- -short x; // or char, etc -(x == 10) --- -generates an zext/sext of x which can easily be avoided. - -//===---------------------------------------------------------------------===// - -Bitfields accesses can be shifted to simplify masking and sign -extension. For example, if the bitfield width is 8 and it is -appropriately aligned then is is a lot shorter to just load the char -directly. - -//===---------------------------------------------------------------------===// - -It may be worth avoiding creation of alloca's for formal arguments -for the common situation where the argument is never written to or has -its address taken. The idea would be to begin generating code by using -the argument directly and if its address is taken or it is stored to -then generate the alloca and patch up the existing code. - -In theory, the same optimization could be a win for block local -variables as long as the declaration dominates all statements in the -block. - -NOTE: The main case we care about this for is for -O0 -g compile time -performance, and in that scenario we will need to emit the alloca -anyway currently to emit proper debug info. So this is blocked by -being able to emit debug information which refers to an LLVM -temporary, not an alloca. - -//===---------------------------------------------------------------------===// - -We should try and avoid generating basic blocks which only contain -jumps. At -O0, this penalizes us all the way from IRgen (malloc & -instruction overhead), all the way down through code generation and -assembly time. - -On 176.gcc:expr.ll, it looks like over 12% of basic blocks are just -direct branches! - -//===---------------------------------------------------------------------===// diff --git a/contrib/llvm/tools/clang/lib/Driver/CMakeLists.txt b/contrib/llvm/tools/clang/lib/Driver/CMakeLists.txt deleted file mode 100644 index 00d076b..0000000 --- a/contrib/llvm/tools/clang/lib/Driver/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -set(LLVM_NO_RTTI 1) - -add_clang_library(clangDriver - Action.cpp - Arg.cpp - ArgList.cpp - CC1Options.cpp - CC1AsOptions.cpp - Compilation.cpp - Driver.cpp - DriverOptions.cpp - HostInfo.cpp - Job.cpp - Option.cpp - OptTable.cpp - Phases.cpp - Tool.cpp - ToolChain.cpp - ToolChains.cpp - Tools.cpp - Types.cpp - ) - -add_dependencies(clangDriver ClangAttrList ClangDiagnosticDriver - ClangDriverOptions ClangCC1Options ClangCC1AsOptions) diff --git a/contrib/llvm/tools/clang/lib/Driver/Makefile b/contrib/llvm/tools/clang/lib/Driver/Makefile deleted file mode 100644 index 454ab86..0000000 --- a/contrib/llvm/tools/clang/lib/Driver/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -##===- clang/lib/Driver/Makefile ---------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -CLANG_LEVEL := ../.. -LIBRARYNAME := clangDriver - -include $(CLANG_LEVEL)/Makefile diff --git a/contrib/llvm/tools/clang/lib/Frontend/CMakeLists.txt b/contrib/llvm/tools/clang/lib/Frontend/CMakeLists.txt deleted file mode 100644 index 5a31495..0000000 --- a/contrib/llvm/tools/clang/lib/Frontend/CMakeLists.txt +++ /dev/null @@ -1,45 +0,0 @@ -set(LLVM_NO_RTTI 1) - -add_clang_library(clangFrontend - ASTConsumers.cpp - ASTMerge.cpp - ASTUnit.cpp - BoostConAction.cpp - CacheTokens.cpp - CompilerInstance.cpp - CompilerInvocation.cpp - DeclXML.cpp - DependencyFile.cpp - DiagChecker.cpp - DocumentXML.cpp - FrontendAction.cpp - FrontendActions.cpp - FrontendOptions.cpp - InitHeaderSearch.cpp - InitPreprocessor.cpp - LangStandards.cpp - PrintPreprocessedOutput.cpp - StmtXML.cpp - TextDiagnosticBuffer.cpp - TextDiagnosticPrinter.cpp - TypeXML.cpp - VerifyDiagnosticsClient.cpp - Warnings.cpp - ) - -IF(MSVC) - get_target_property(NON_ANSI_COMPILE_FLAGS clangFrontend COMPILE_FLAGS) - string(REPLACE /Za - "" NON_ANSI_COMPILE_FLAGS - ${NON_ANSI_COMPILE_FLAGS}) - set_target_properties(clangFrontend PROPERTIES COMPILE_FLAGS ${NON_ANSI_COMPILE_FLAGS}) -ENDIF(MSVC) - -add_dependencies(clangFrontend - ClangAttrClasses - ClangAttrList - ClangDiagnosticFrontend - ClangDiagnosticLex - ClangDiagnosticSema - ClangDeclNodes - ClangStmtNodes) diff --git a/contrib/llvm/tools/clang/lib/Frontend/Makefile b/contrib/llvm/tools/clang/lib/Frontend/Makefile deleted file mode 100644 index 3c13ad6..0000000 --- a/contrib/llvm/tools/clang/lib/Frontend/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -##===- clang/lib/Frontend/Makefile -------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -CLANG_LEVEL := ../.. -LIBRARYNAME := clangFrontend - -include $(CLANG_LEVEL)/Makefile - diff --git a/contrib/llvm/tools/clang/lib/FrontendTool/CMakeLists.txt b/contrib/llvm/tools/clang/lib/FrontendTool/CMakeLists.txt deleted file mode 100644 index 26c9fc7..0000000 --- a/contrib/llvm/tools/clang/lib/FrontendTool/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -set(LLVM_NO_RTTI 1) - -add_clang_library(clangFrontendTool - ExecuteCompilerInvocation.cpp - ) diff --git a/contrib/llvm/tools/clang/lib/FrontendTool/Makefile b/contrib/llvm/tools/clang/lib/FrontendTool/Makefile deleted file mode 100644 index c43213f..0000000 --- a/contrib/llvm/tools/clang/lib/FrontendTool/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -##===- clang/lib/FrontendTool/Makefile ---------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -CLANG_LEVEL := ../.. -LIBRARYNAME := clangFrontendTool - -include $(CLANG_LEVEL)/Makefile diff --git a/contrib/llvm/tools/clang/lib/Headers/CMakeLists.txt b/contrib/llvm/tools/clang/lib/Headers/CMakeLists.txt deleted file mode 100644 index a1b5f50..0000000 --- a/contrib/llvm/tools/clang/lib/Headers/CMakeLists.txt +++ /dev/null @@ -1,50 +0,0 @@ -set(files - altivec.h - avxintrin.h - emmintrin.h - float.h - immintrin.h - iso646.h - limits.h - mm_malloc.h - mmintrin.h - pmmintrin.h - smmintrin.h - stdarg.h - stdbool.h - stddef.h - stdint.h - tgmath.h - tmmintrin.h - xmmintrin.h) - -if (MSVC_IDE OR XCODE) - set(output_dir ${LLVM_BINARY_DIR}/bin/lib/clang/${CLANG_VERSION}/include) -else () - set(output_dir ${LLVM_BINARY_DIR}/lib/clang/${CLANG_VERSION}/include) -endif () - -# Generate arm_neon.h -set(LLVM_TARGET_DEFINITIONS ${CLANG_SOURCE_DIR}/include/clang/Basic/arm_neon.td) -tablegen(arm_neon.h.inc -gen-arm-neon) - -add_custom_command(OUTPUT ${output_dir}/arm_neon.h - DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/arm_neon.h.inc - COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_BINARY_DIR}/arm_neon.h.inc ${output_dir}/arm_neon.h - COMMENT "Copying clang's arm_neon.h...") - -foreach( f ${files} ) - set( src ${CMAKE_CURRENT_SOURCE_DIR}/${f} ) - set( dst ${output_dir}/${f} ) - add_custom_command(OUTPUT ${dst} - DEPENDS ${src} - COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst} - COMMENT "Copying clang's ${f}...") -endforeach( f ) - -add_custom_target(clang-headers ALL - DEPENDS ${files} ${output_dir}/arm_neon.h) - -install(FILES ${files} ${output_dir}/arm_neon.h - PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ - DESTINATION lib${LLVM_LIBDIR_SUFFIX}/clang/${CLANG_VERSION}/include) diff --git a/contrib/llvm/tools/clang/lib/Headers/Makefile b/contrib/llvm/tools/clang/lib/Headers/Makefile deleted file mode 100644 index d75b1a2..0000000 --- a/contrib/llvm/tools/clang/lib/Headers/Makefile +++ /dev/null @@ -1,54 +0,0 @@ -##===- clang/lib/Headers/Makefile --------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -CLANG_LEVEL := ../.. - -BUILT_SOURCES = arm_neon.h.inc -TABLEGEN_INC_FILES_COMMON = 1 - -include $(CLANG_LEVEL)/Makefile - -CLANG_VERSION := $(word 3,$(shell grep "CLANG_VERSION " \ - $(PROJ_OBJ_DIR)/$(CLANG_LEVEL)/include/clang/Basic/Version.inc)) - -HeaderDir := $(PROJ_OBJ_ROOT)/$(BuildMode)/lib/clang/$(CLANG_VERSION)/include - -HEADERS := $(notdir $(wildcard $(PROJ_SRC_DIR)/*.h)) - -OBJHEADERS := $(addprefix $(HeaderDir)/, $(HEADERS)) - - -$(OBJHEADERS): $(HeaderDir)/%.h: $(PROJ_SRC_DIR)/%.h $(HeaderDir)/.dir $(HeaderDir)/arm_neon.h - $(Verb) cp $< $@ - $(Echo) Copying $(notdir $<) to build dir - -$(HeaderDir)/arm_neon.h: $(BUILT_SOURCES) $(HeaderDir)/.dir - $(Verb) cp $< $@ - $(Echo) Copying $(notdir $<) to build dir - -# Hook into the standard Makefile rules. -all-local:: $(OBJHEADERS) - -PROJ_headers := $(DESTDIR)$(PROJ_prefix)/lib/clang/$(CLANG_VERSION)/include - -INSTHEADERS := $(addprefix $(PROJ_headers)/, $(HEADERS)) -INSTHEADERS += $(PROJ_headers)/arm_neon.h - -$(PROJ_headers): - $(Verb) $(MKDIR) $@ - -$(INSTHEADERS): $(PROJ_headers)/%.h: $(HeaderDir)/%.h | $(PROJ_headers) - $(Verb) $(DataInstall) $< $(PROJ_headers) - $(Echo) Installing compiler include file: $(notdir $<) - -install-local:: $(INSTHEADERS) - -$(ObjDir)/arm_neon.h.inc.tmp : $(CLANG_LEVEL)/include/clang/Basic/arm_neon.td $(TBLGEN) $(ObjDir)/.dir - $(Echo) "Building Clang arm_neon.h.inc with tblgen" - $(Verb) $(TableGen) -gen-arm-neon -o $(call SYSPATH, $@) $< diff --git a/contrib/llvm/tools/clang/lib/Index/CMakeLists.txt b/contrib/llvm/tools/clang/lib/Index/CMakeLists.txt deleted file mode 100644 index 61f69b2..0000000 --- a/contrib/llvm/tools/clang/lib/Index/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -set(LLVM_NO_RTTI 1) - -add_clang_library(clangIndex - ASTLocation.cpp - Analyzer.cpp - CallGraph.cpp - DeclReferenceMap.cpp - Entity.cpp - GlobalSelector.cpp - Handlers.cpp - IndexProvider.cpp - Indexer.cpp - Program.cpp - SelectorMap.cpp - ) diff --git a/contrib/llvm/tools/clang/lib/Index/Makefile b/contrib/llvm/tools/clang/lib/Index/Makefile deleted file mode 100644 index 8607d78..0000000 --- a/contrib/llvm/tools/clang/lib/Index/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -##===- clang/lib/Index/Makefile ----------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -# -# This implements the Indexer library for the C-Language front-end. -# -##===----------------------------------------------------------------------===## - -CLANG_LEVEL := ../.. -LIBRARYNAME := clangIndex - -include $(CLANG_LEVEL)/Makefile - diff --git a/contrib/llvm/tools/clang/lib/Lex/CMakeLists.txt b/contrib/llvm/tools/clang/lib/Lex/CMakeLists.txt deleted file mode 100644 index 632fbc6..0000000 --- a/contrib/llvm/tools/clang/lib/Lex/CMakeLists.txt +++ /dev/null @@ -1,27 +0,0 @@ -set(LLVM_NO_RTTI 1) - -# TODO: Add -maltivec when ARCH is PowerPC. - -add_clang_library(clangLex - HeaderMap.cpp - HeaderSearch.cpp - Lexer.cpp - LiteralSupport.cpp - MacroArgs.cpp - MacroInfo.cpp - PPCaching.cpp - PPDirectives.cpp - PPExpressions.cpp - PPLexerChange.cpp - PPMacroExpansion.cpp - PTHLexer.cpp - Pragma.cpp - PreprocessingRecord.cpp - Preprocessor.cpp - PreprocessorLexer.cpp - ScratchBuffer.cpp - TokenConcatenation.cpp - TokenLexer.cpp - ) - -add_dependencies(clangLex ClangDiagnosticLex) diff --git a/contrib/llvm/tools/clang/lib/Lex/Makefile b/contrib/llvm/tools/clang/lib/Lex/Makefile deleted file mode 100644 index d80fb55..0000000 --- a/contrib/llvm/tools/clang/lib/Lex/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -##===- clang/lib/Lex/Makefile ------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -# -# This implements the Lexer library for the C-Language front-end. -# -##===----------------------------------------------------------------------===## - -CLANG_LEVEL := ../.. -include $(CLANG_LEVEL)/../../Makefile.config - -LIBRARYNAME := clangLex - -ifeq ($(ARCH),PowerPC) -CXX.Flags += -maltivec -endif - -include $(CLANG_LEVEL)/Makefile - diff --git a/contrib/llvm/tools/clang/lib/Makefile b/contrib/llvm/tools/clang/lib/Makefile deleted file mode 100755 index dbd0eb6..0000000 --- a/contrib/llvm/tools/clang/lib/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -##===- lib/Makefile ----------------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -CLANG_LEVEL := .. - -PARALLEL_DIRS = Headers Basic Lex Parse AST Sema CodeGen Analysis \ - Checker Rewrite Serialization Frontend FrontendTool Index Driver - -include $(CLANG_LEVEL)/Makefile - diff --git a/contrib/llvm/tools/clang/lib/Parse/CMakeLists.txt b/contrib/llvm/tools/clang/lib/Parse/CMakeLists.txt deleted file mode 100644 index 189af3d..0000000 --- a/contrib/llvm/tools/clang/lib/Parse/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -set(LLVM_NO_RTTI 1) - -add_clang_library(clangParse - ParseAST.cpp - ParseCXXInlineMethods.cpp - ParseDecl.cpp - ParseDeclCXX.cpp - ParseExpr.cpp - ParseExprCXX.cpp - ParseInit.cpp - ParseObjc.cpp - ParsePragma.cpp - ParseStmt.cpp - ParseTemplate.cpp - ParseTentative.cpp - Parser.cpp - ) - -add_dependencies(clangParse ClangAttrClasses ClangAttrList ClangDeclNodes ClangDiagnosticParse ClangStmtNodes) diff --git a/contrib/llvm/tools/clang/lib/Parse/Makefile b/contrib/llvm/tools/clang/lib/Parse/Makefile deleted file mode 100644 index 5ec7c333..0000000 --- a/contrib/llvm/tools/clang/lib/Parse/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -##===- clang/lib/Parse/Makefile ----------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -# -# This implements the Parser library for the C-Language front-end. -# -##===----------------------------------------------------------------------===## - -CLANG_LEVEL := ../.. -LIBRARYNAME := clangParse - -include $(CLANG_LEVEL)/Makefile - diff --git a/contrib/llvm/tools/clang/lib/Rewrite/CMakeLists.txt b/contrib/llvm/tools/clang/lib/Rewrite/CMakeLists.txt deleted file mode 100644 index ffeb3e6..0000000 --- a/contrib/llvm/tools/clang/lib/Rewrite/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -set(LLVM_NO_RTTI 1) - -add_clang_library(clangRewrite - DeltaTree.cpp - FixItRewriter.cpp - FrontendActions.cpp - HTMLPrint.cpp - HTMLRewrite.cpp - RewriteMacros.cpp - RewriteObjC.cpp - RewriteRope.cpp - RewriteTest.cpp - Rewriter.cpp - TokenRewriter.cpp - ) - -add_dependencies(clangBasic - ClangAttrClasses - ClangAttrList - ClangDeclNodes - ClangStmtNodes) diff --git a/contrib/llvm/tools/clang/lib/Rewrite/Makefile b/contrib/llvm/tools/clang/lib/Rewrite/Makefile deleted file mode 100644 index 5fef9b2..0000000 --- a/contrib/llvm/tools/clang/lib/Rewrite/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -##===- clang/lib/Rewrite/Makefile --------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -# -# This implements code transformation / rewriting facilities. -# -##===----------------------------------------------------------------------===## - -CLANG_LEVEL := ../.. -LIBRARYNAME := clangRewrite - -include $(CLANG_LEVEL)/Makefile - diff --git a/contrib/llvm/tools/clang/lib/Sema/CMakeLists.txt b/contrib/llvm/tools/clang/lib/Sema/CMakeLists.txt deleted file mode 100644 index e65bb22..0000000 --- a/contrib/llvm/tools/clang/lib/Sema/CMakeLists.txt +++ /dev/null @@ -1,39 +0,0 @@ -set(LLVM_NO_RTTI 1) - -add_clang_library(clangSema - AnalysisBasedWarnings.cpp - AttributeList.cpp - CodeCompleteConsumer.cpp - DeclSpec.cpp - IdentifierResolver.cpp - JumpDiagnostics.cpp - Sema.cpp - SemaAccess.cpp - SemaAttr.cpp - SemaCXXCast.cpp - SemaCXXScopeSpec.cpp - SemaChecking.cpp - SemaCodeComplete.cpp - SemaDecl.cpp - SemaDeclAttr.cpp - SemaDeclCXX.cpp - SemaDeclObjC.cpp - SemaExceptionSpec.cpp - SemaExpr.cpp - SemaExprCXX.cpp - SemaExprObjC.cpp - SemaInit.cpp - SemaLookup.cpp - SemaObjCProperty.cpp - SemaOverload.cpp - SemaStmt.cpp - SemaTemplate.cpp - SemaTemplateDeduction.cpp - SemaTemplateInstantiate.cpp - SemaTemplateInstantiateDecl.cpp - SemaType.cpp - TargetAttributesSema.cpp - ) - -add_dependencies(clangSema ClangARMNeon ClangAttrClasses ClangAttrList - ClangDiagnosticSema ClangDeclNodes ClangStmtNodes) diff --git a/contrib/llvm/tools/clang/lib/Sema/Makefile b/contrib/llvm/tools/clang/lib/Sema/Makefile deleted file mode 100644 index 2c02739..0000000 --- a/contrib/llvm/tools/clang/lib/Sema/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -##===- clang/lib/Sema/Makefile -----------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -# -# This implements the semantic analyzer and AST builder library for the -# C-Language front-end. -# -##===----------------------------------------------------------------------===## - -CLANG_LEVEL := ../.. -LIBRARYNAME := clangSema - -include $(CLANG_LEVEL)/Makefile - diff --git a/contrib/llvm/tools/clang/lib/Serialization/CMakeLists.txt b/contrib/llvm/tools/clang/lib/Serialization/CMakeLists.txt deleted file mode 100644 index d863c17..0000000 --- a/contrib/llvm/tools/clang/lib/Serialization/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ -set(LLVM_NO_RTTI 1) - -add_clang_library(clangSerialization - GeneratePCH.cpp - ASTCommon.cpp - ASTReader.cpp - ASTReaderDecl.cpp - ASTReaderStmt.cpp - ASTWriter.cpp - ASTWriterDecl.cpp - ASTWriterStmt.cpp - ) - -add_dependencies(clangSerialization - ClangAttrClasses - ClangAttrList - ClangAttrPCHRead - ClangAttrPCHWrite - ClangDiagnosticFrontend - ClangDiagnosticLex - ClangDiagnosticSema - ClangDeclNodes - ClangStmtNodes) diff --git a/contrib/llvm/tools/clang/lib/Serialization/Makefile b/contrib/llvm/tools/clang/lib/Serialization/Makefile deleted file mode 100644 index e89ddc3..0000000 --- a/contrib/llvm/tools/clang/lib/Serialization/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -##===- clang/lib/Serialization/Makefile --------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -# -# This implements the semantic analyzer and AST builder library for the -# C-Language front-end. -# -##===----------------------------------------------------------------------===## - -CLANG_LEVEL := ../.. -LIBRARYNAME := clangSerialization - -include $(CLANG_LEVEL)/Makefile - diff --git a/contrib/llvm/tools/clang/runtime/Makefile b/contrib/llvm/tools/clang/runtime/Makefile deleted file mode 100644 index 0e8b359..0000000 --- a/contrib/llvm/tools/clang/runtime/Makefile +++ /dev/null @@ -1,104 +0,0 @@ -##===- clang/runtime/Makefile ------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -# -# This file defines support for building the Clang runtime libraries (which are -# implemented by compiler-rt) and placing them in the proper locations in the -# Clang resources directory (i.e., where the driver expects them). -# -##===----------------------------------------------------------------------===## - -CLANG_LEVEL := .. -include $(CLANG_LEVEL)/Makefile - -CLANG_VERSION := $(word 3,$(shell grep "CLANG_VERSION " \ - $(PROJ_OBJ_DIR)/$(CLANG_LEVEL)/include/clang/Basic/Version.inc)) - -ResourceDir := $(PROJ_OBJ_ROOT)/$(BuildMode)/lib/clang/$(CLANG_VERSION) -PROJ_resources := $(DESTDIR)$(PROJ_prefix)/lib/clang/$(CLANG_VERSION) - -ResourceLibDir := $(ResourceDir)/lib -PROJ_resources_lib := $(PROJ_resources)/lib - -# Expect compiler-rt to be in llvm/projects/compiler-rt -COMPILERRT_SRC_ROOT := $(LLVM_SRC_ROOT)/projects/compiler-rt - -ifndef CLANG_NO_RUNTIME -ifeq ($(shell test -d $(COMPILERRT_SRC_ROOT) && echo OK),OK) - -# Select the compiler-rt configuration to use, and install directory. -# -# FIXME: Eventually, we want some kind of configure support for this. We want to -# build/install runtime libraries for as many targets as clang was configured to -# support. -RuntimeDirs := -ifeq ($(OS),Darwin) -RuntimeDirs += darwin -RuntimeLibrary.darwin.Configs = 10.4 armv6 cc_kext -endif - -# Rule to build the compiler-rt libraries we need. -# -# We build all the libraries in a single shot to avoid recursive make as much as -# possible. -BuildRuntimeLibraries: - $(Verb) $(MAKE) -C $(COMPILERRT_SRC_ROOT) \ - ProjSrcRoot=$(COMPILERRT_SRC_ROOT) \ - ProjObjRoot=$(PROJ_OBJ_DIR) \ - CC="$(ToolDir)/clang -no-integrated-as" \ - $(RuntimeDirs:%=clang_%) -.PHONY: BuildRuntimeLibraries -CleanRuntimeLibraries: - $(Verb) $(MAKE) -C $(COMPILERRT_SRC_ROOT) \ - ProjSrcRoot=$(COMPILERRT_SRC_ROOT) \ - ProjObjRoot=$(PROJ_OBJ_DIR) \ - clean -.PHONY: CleanRuntimeLibraries - -$(PROJ_resources_lib): - $(Verb) $(MKDIR) $@ - -# Expand rules for copying/installing each individual library. We can't use -# implicit rules here because we need to match against multiple things. -define RuntimeLibraryTemplate -$(PROJ_OBJ_DIR)/clang_$1/%/libcompiler_rt.a: BuildRuntimeLibraries - @true -.PRECIOUS: $(PROJ_OBJ_DIR)/clang_$1/%/libcompiler_rt.a - -# Rule to copy the libraries to their resource directory location. -$(ResourceLibDir)/$1/libclang_rt.%.a: \ - $(PROJ_OBJ_DIR)/clang_$1/%/libcompiler_rt.a \ - $(ResourceLibDir)/$1/.dir - $(Echo) Copying runtime library $1/$$* to build dir - $(Verb) cp $(PROJ_OBJ_DIR)/clang_$1/$$*/libcompiler_rt.a $$@ -RuntimeLibrary.$1: \ - $(RuntimeLibrary.$1.Configs:%=$(ResourceLibDir)/$1/libclang_rt.%.a) -.PHONY: RuntimeLibrary.$1 - -$(PROJ_resources_lib)/$1: $(PROJ_resources_lib) - $(Verb) $(MKDIR) $$@ - -$(PROJ_resources_lib)/$1/libclang_rt.%.a: \ - $(ResourceLibDir)/$1/libclang_rt.%.a | $(PROJ_resources_lib)/$1 - $(Echo) Installing compiler runtime library: $1/$$* - $(Verb) $(DataInstall) $$< $(PROJ_resources_lib)/$1 - -# Rule to install runtime libraries. -RuntimeLibraryInstall.$1: \ - $(RuntimeLibrary.$1.Configs:%=$(PROJ_resources_lib)/$1/libclang_rt.%.a) -.PHONY: RuntimeLibraryInstall.$1 -endef -$(foreach lib,$(RuntimeDirs), $(eval $(call RuntimeLibraryTemplate,$(lib)))) - -# Hook into the standard Makefile rules. -all-local:: $(RuntimeDirs:%=RuntimeLibrary.%) -install-local:: $(RuntimeDirs:%=RuntimeLibraryInstall.%) -clean-local:: CleanRuntimeLibraries - -endif -endif diff --git a/contrib/llvm/tools/clang/tools/CMakeLists.txt b/contrib/llvm/tools/clang/tools/CMakeLists.txt deleted file mode 100644 index ae33b78..0000000 --- a/contrib/llvm/tools/clang/tools/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -add_subdirectory(libclang) -add_subdirectory(c-index-test) -add_subdirectory(driver) diff --git a/contrib/llvm/tools/clang/tools/Makefile b/contrib/llvm/tools/clang/tools/Makefile deleted file mode 100644 index 0202cc5..0000000 --- a/contrib/llvm/tools/clang/tools/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -##===- tools/Makefile --------------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -CLANG_LEVEL := .. -DIRS := driver libclang c-index-test - -include $(CLANG_LEVEL)/../../Makefile.config - -ifeq ($(OS), $(filter $(OS), Cygwin MingW Minix)) -DIRS := $(filter-out libclang c-index-test, $(DIRS)) -endif - -include $(CLANG_LEVEL)/Makefile diff --git a/contrib/llvm/tools/clang/tools/c-index-test/CMakeLists.txt b/contrib/llvm/tools/clang/tools/c-index-test/CMakeLists.txt deleted file mode 100644 index 5cf2cd6..0000000 --- a/contrib/llvm/tools/clang/tools/c-index-test/CMakeLists.txt +++ /dev/null @@ -1,30 +0,0 @@ -set(LLVM_NO_RTTI 1) - -set( LLVM_USED_LIBS - libclang - clangIndex - clangFrontend - clangDriver - clangSerialization - clangParse - clangSema - clangAnalysis - clangAST - clangLex - clangBasic - ) - -set( LLVM_LINK_COMPONENTS - bitreader - mc - core - ) - -add_clang_executable(c-index-test - c-index-test.c - ) - -set_target_properties(c-index-test - PROPERTIES - LINKER_LANGUAGE CXX) - diff --git a/contrib/llvm/tools/clang/tools/c-index-test/Makefile b/contrib/llvm/tools/clang/tools/c-index-test/Makefile deleted file mode 100644 index f41aa80..0000000 --- a/contrib/llvm/tools/clang/tools/c-index-test/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -##===- tools/index-test/Makefile ---------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -CLANG_LEVEL := ../.. - -TOOLNAME = c-index-test - -# No plugins, optimize startup time. -TOOL_NO_EXPORTS = 1 - -LINK_COMPONENTS := bitreader mc core -USEDLIBS = clang.a clangIndex.a clangFrontend.a clangDriver.a \ - clangSerialization.a clangParse.a clangSema.a clangAnalysis.a \ - clangAST.a clangLex.a clangBasic.a - -include $(CLANG_LEVEL)/Makefile diff --git a/contrib/llvm/tools/clang/tools/c-index-test/c-index-test.c b/contrib/llvm/tools/clang/tools/c-index-test/c-index-test.c deleted file mode 100644 index 58eff97..0000000 --- a/contrib/llvm/tools/clang/tools/c-index-test/c-index-test.c +++ /dev/null @@ -1,1524 +0,0 @@ -/* c-index-test.c */ - -#include "clang-c/Index.h" -#include <ctype.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <assert.h> - -/******************************************************************************/ -/* Utility functions. */ -/******************************************************************************/ - -#ifdef _MSC_VER -char *basename(const char* path) -{ - char* base1 = (char*)strrchr(path, '/'); - char* base2 = (char*)strrchr(path, '\\'); - if (base1 && base2) - return((base1 > base2) ? base1 + 1 : base2 + 1); - else if (base1) - return(base1 + 1); - else if (base2) - return(base2 + 1); - - return((char*)path); -} -#else -extern char *basename(const char *); -#endif - -/** \brief Return the default parsing options. */ -static unsigned getDefaultParsingOptions() { - unsigned options = CXTranslationUnit_DetailedPreprocessingRecord; - - if (getenv("CINDEXTEST_EDITING")) - options |= clang_defaultEditingTranslationUnitOptions(); - if (getenv("CINDEXTEST_COMPLETION_CACHING")) - options |= CXTranslationUnit_CacheCompletionResults; - - return options; -} - -static void PrintExtent(FILE *out, unsigned begin_line, unsigned begin_column, - unsigned end_line, unsigned end_column) { - fprintf(out, "[%d:%d - %d:%d]", begin_line, begin_column, - end_line, end_column); -} - -static unsigned CreateTranslationUnit(CXIndex Idx, const char *file, - CXTranslationUnit *TU) { - - *TU = clang_createTranslationUnit(Idx, file); - if (!*TU) { - fprintf(stderr, "Unable to load translation unit from '%s'!\n", file); - return 0; - } - return 1; -} - -void free_remapped_files(struct CXUnsavedFile *unsaved_files, - int num_unsaved_files) { - int i; - for (i = 0; i != num_unsaved_files; ++i) { - free((char *)unsaved_files[i].Filename); - free((char *)unsaved_files[i].Contents); - } - free(unsaved_files); -} - -int parse_remapped_files(int argc, const char **argv, int start_arg, - struct CXUnsavedFile **unsaved_files, - int *num_unsaved_files) { - int i; - int arg; - int prefix_len = strlen("-remap-file="); - *unsaved_files = 0; - *num_unsaved_files = 0; - - /* Count the number of remapped files. */ - for (arg = start_arg; arg < argc; ++arg) { - if (strncmp(argv[arg], "-remap-file=", prefix_len)) - break; - - ++*num_unsaved_files; - } - - if (*num_unsaved_files == 0) - return 0; - - *unsaved_files - = (struct CXUnsavedFile *)malloc(sizeof(struct CXUnsavedFile) * - *num_unsaved_files); - for (arg = start_arg, i = 0; i != *num_unsaved_files; ++i, ++arg) { - struct CXUnsavedFile *unsaved = *unsaved_files + i; - const char *arg_string = argv[arg] + prefix_len; - int filename_len; - char *filename; - char *contents; - FILE *to_file; - const char *semi = strchr(arg_string, ';'); - if (!semi) { - fprintf(stderr, - "error: -remap-file=from;to argument is missing semicolon\n"); - free_remapped_files(*unsaved_files, i); - *unsaved_files = 0; - *num_unsaved_files = 0; - return -1; - } - - /* Open the file that we're remapping to. */ - to_file = fopen(semi + 1, "r"); - if (!to_file) { - fprintf(stderr, "error: cannot open file %s that we are remapping to\n", - semi + 1); - free_remapped_files(*unsaved_files, i); - *unsaved_files = 0; - *num_unsaved_files = 0; - return -1; - } - - /* Determine the length of the file we're remapping to. */ - fseek(to_file, 0, SEEK_END); - unsaved->Length = ftell(to_file); - fseek(to_file, 0, SEEK_SET); - - /* Read the contents of the file we're remapping to. */ - contents = (char *)malloc(unsaved->Length + 1); - if (fread(contents, 1, unsaved->Length, to_file) != unsaved->Length) { - fprintf(stderr, "error: unexpected %s reading 'to' file %s\n", - (feof(to_file) ? "EOF" : "error"), semi + 1); - fclose(to_file); - free_remapped_files(*unsaved_files, i); - *unsaved_files = 0; - *num_unsaved_files = 0; - return -1; - } - contents[unsaved->Length] = 0; - unsaved->Contents = contents; - - /* Close the file. */ - fclose(to_file); - - /* Copy the file name that we're remapping from. */ - filename_len = semi - arg_string; - filename = (char *)malloc(filename_len + 1); - memcpy(filename, arg_string, filename_len); - filename[filename_len] = 0; - unsaved->Filename = filename; - } - - return 0; -} - -/******************************************************************************/ -/* Pretty-printing. */ -/******************************************************************************/ - -static void PrintCursor(CXCursor Cursor) { - if (clang_isInvalid(Cursor.kind)) { - CXString ks = clang_getCursorKindSpelling(Cursor.kind); - printf("Invalid Cursor => %s", clang_getCString(ks)); - clang_disposeString(ks); - } - else { - CXString string, ks; - CXCursor Referenced; - unsigned line, column; - CXCursor SpecializationOf; - - ks = clang_getCursorKindSpelling(Cursor.kind); - string = clang_getCursorSpelling(Cursor); - printf("%s=%s", clang_getCString(ks), - clang_getCString(string)); - clang_disposeString(ks); - clang_disposeString(string); - - Referenced = clang_getCursorReferenced(Cursor); - if (!clang_equalCursors(Referenced, clang_getNullCursor())) { - CXSourceLocation Loc = clang_getCursorLocation(Referenced); - clang_getInstantiationLocation(Loc, 0, &line, &column, 0); - printf(":%d:%d", line, column); - } - - if (clang_isCursorDefinition(Cursor)) - printf(" (Definition)"); - - switch (clang_getCursorAvailability(Cursor)) { - case CXAvailability_Available: - break; - - case CXAvailability_Deprecated: - printf(" (deprecated)"); - break; - - case CXAvailability_NotAvailable: - printf(" (unavailable)"); - break; - } - - if (Cursor.kind == CXCursor_IBOutletCollectionAttr) { - CXType T = - clang_getCanonicalType(clang_getIBOutletCollectionType(Cursor)); - CXString S = clang_getTypeKindSpelling(T.kind); - printf(" [IBOutletCollection=%s]", clang_getCString(S)); - clang_disposeString(S); - } - - if (Cursor.kind == CXCursor_CXXBaseSpecifier) { - enum CX_CXXAccessSpecifier access = clang_getCXXAccessSpecifier(Cursor); - unsigned isVirtual = clang_isVirtualBase(Cursor); - const char *accessStr = 0; - - switch (access) { - case CX_CXXInvalidAccessSpecifier: - accessStr = "invalid"; break; - case CX_CXXPublic: - accessStr = "public"; break; - case CX_CXXProtected: - accessStr = "protected"; break; - case CX_CXXPrivate: - accessStr = "private"; break; - } - - printf(" [access=%s isVirtual=%s]", accessStr, - isVirtual ? "true" : "false"); - } - - SpecializationOf = clang_getSpecializedCursorTemplate(Cursor); - if (!clang_equalCursors(SpecializationOf, clang_getNullCursor())) { - CXSourceLocation Loc = clang_getCursorLocation(SpecializationOf); - CXString Name = clang_getCursorSpelling(SpecializationOf); - clang_getInstantiationLocation(Loc, 0, &line, &column, 0); - printf(" [Specialization of %s:%d:%d]", - clang_getCString(Name), line, column); - clang_disposeString(Name); - } - } -} - -static const char* GetCursorSource(CXCursor Cursor) { - CXSourceLocation Loc = clang_getCursorLocation(Cursor); - CXString source; - CXFile file; - clang_getInstantiationLocation(Loc, &file, 0, 0, 0); - source = clang_getFileName(file); - if (!clang_getCString(source)) { - clang_disposeString(source); - return "<invalid loc>"; - } - else { - const char *b = basename(clang_getCString(source)); - clang_disposeString(source); - return b; - } -} - -/******************************************************************************/ -/* Callbacks. */ -/******************************************************************************/ - -typedef void (*PostVisitTU)(CXTranslationUnit); - -void PrintDiagnostic(CXDiagnostic Diagnostic) { - FILE *out = stderr; - CXFile file; - CXString Msg; - unsigned display_opts = CXDiagnostic_DisplaySourceLocation - | CXDiagnostic_DisplayColumn | CXDiagnostic_DisplaySourceRanges; - unsigned i, num_fixits; - - if (clang_getDiagnosticSeverity(Diagnostic) == CXDiagnostic_Ignored) - return; - - Msg = clang_formatDiagnostic(Diagnostic, display_opts); - fprintf(stderr, "%s\n", clang_getCString(Msg)); - clang_disposeString(Msg); - - clang_getInstantiationLocation(clang_getDiagnosticLocation(Diagnostic), - &file, 0, 0, 0); - if (!file) - return; - - num_fixits = clang_getDiagnosticNumFixIts(Diagnostic); - for (i = 0; i != num_fixits; ++i) { - CXSourceRange range; - CXString insertion_text = clang_getDiagnosticFixIt(Diagnostic, i, &range); - CXSourceLocation start = clang_getRangeStart(range); - CXSourceLocation end = clang_getRangeEnd(range); - unsigned start_line, start_column, end_line, end_column; - CXFile start_file, end_file; - clang_getInstantiationLocation(start, &start_file, &start_line, - &start_column, 0); - clang_getInstantiationLocation(end, &end_file, &end_line, &end_column, 0); - if (clang_equalLocations(start, end)) { - /* Insertion. */ - if (start_file == file) - fprintf(out, "FIX-IT: Insert \"%s\" at %d:%d\n", - clang_getCString(insertion_text), start_line, start_column); - } else if (strcmp(clang_getCString(insertion_text), "") == 0) { - /* Removal. */ - if (start_file == file && end_file == file) { - fprintf(out, "FIX-IT: Remove "); - PrintExtent(out, start_line, start_column, end_line, end_column); - fprintf(out, "\n"); - } - } else { - /* Replacement. */ - if (start_file == end_file) { - fprintf(out, "FIX-IT: Replace "); - PrintExtent(out, start_line, start_column, end_line, end_column); - fprintf(out, " with \"%s\"\n", clang_getCString(insertion_text)); - } - break; - } - clang_disposeString(insertion_text); - } -} - -void PrintDiagnostics(CXTranslationUnit TU) { - int i, n = clang_getNumDiagnostics(TU); - for (i = 0; i != n; ++i) { - CXDiagnostic Diag = clang_getDiagnostic(TU, i); - PrintDiagnostic(Diag); - clang_disposeDiagnostic(Diag); - } -} - -/******************************************************************************/ -/* Logic for testing traversal. */ -/******************************************************************************/ - -static const char *FileCheckPrefix = "CHECK"; - -static void PrintCursorExtent(CXCursor C) { - CXSourceRange extent = clang_getCursorExtent(C); - CXFile begin_file, end_file; - unsigned begin_line, begin_column, end_line, end_column; - - clang_getInstantiationLocation(clang_getRangeStart(extent), - &begin_file, &begin_line, &begin_column, 0); - clang_getInstantiationLocation(clang_getRangeEnd(extent), - &end_file, &end_line, &end_column, 0); - if (!begin_file || !end_file) - return; - - printf(" Extent="); - PrintExtent(stdout, begin_line, begin_column, end_line, end_column); -} - -/* Data used by all of the visitors. */ -typedef struct { - CXTranslationUnit TU; - enum CXCursorKind *Filter; -} VisitorData; - - -enum CXChildVisitResult FilteredPrintingVisitor(CXCursor Cursor, - CXCursor Parent, - CXClientData ClientData) { - VisitorData *Data = (VisitorData *)ClientData; - if (!Data->Filter || (Cursor.kind == *(enum CXCursorKind *)Data->Filter)) { - CXSourceLocation Loc = clang_getCursorLocation(Cursor); - unsigned line, column; - clang_getInstantiationLocation(Loc, 0, &line, &column, 0); - printf("// %s: %s:%d:%d: ", FileCheckPrefix, - GetCursorSource(Cursor), line, column); - PrintCursor(Cursor); - PrintCursorExtent(Cursor); - printf("\n"); - return CXChildVisit_Recurse; - } - - return CXChildVisit_Continue; -} - -static enum CXChildVisitResult FunctionScanVisitor(CXCursor Cursor, - CXCursor Parent, - CXClientData ClientData) { - const char *startBuf, *endBuf; - unsigned startLine, startColumn, endLine, endColumn, curLine, curColumn; - CXCursor Ref; - VisitorData *Data = (VisitorData *)ClientData; - - if (Cursor.kind != CXCursor_FunctionDecl || - !clang_isCursorDefinition(Cursor)) - return CXChildVisit_Continue; - - clang_getDefinitionSpellingAndExtent(Cursor, &startBuf, &endBuf, - &startLine, &startColumn, - &endLine, &endColumn); - /* Probe the entire body, looking for both decls and refs. */ - curLine = startLine; - curColumn = startColumn; - - while (startBuf < endBuf) { - CXSourceLocation Loc; - CXFile file; - CXString source; - - if (*startBuf == '\n') { - startBuf++; - curLine++; - curColumn = 1; - } else if (*startBuf != '\t') - curColumn++; - - Loc = clang_getCursorLocation(Cursor); - clang_getInstantiationLocation(Loc, &file, 0, 0, 0); - - source = clang_getFileName(file); - if (clang_getCString(source)) { - CXSourceLocation RefLoc - = clang_getLocation(Data->TU, file, curLine, curColumn); - Ref = clang_getCursor(Data->TU, RefLoc); - if (Ref.kind == CXCursor_NoDeclFound) { - /* Nothing found here; that's fine. */ - } else if (Ref.kind != CXCursor_FunctionDecl) { - printf("// %s: %s:%d:%d: ", FileCheckPrefix, GetCursorSource(Ref), - curLine, curColumn); - PrintCursor(Ref); - printf("\n"); - } - } - clang_disposeString(source); - startBuf++; - } - - return CXChildVisit_Continue; -} - -/******************************************************************************/ -/* USR testing. */ -/******************************************************************************/ - -enum CXChildVisitResult USRVisitor(CXCursor C, CXCursor parent, - CXClientData ClientData) { - VisitorData *Data = (VisitorData *)ClientData; - if (!Data->Filter || (C.kind == *(enum CXCursorKind *)Data->Filter)) { - CXString USR = clang_getCursorUSR(C); - const char *cstr = clang_getCString(USR); - if (!cstr || cstr[0] == '\0') { - clang_disposeString(USR); - return CXChildVisit_Recurse; - } - printf("// %s: %s %s", FileCheckPrefix, GetCursorSource(C), cstr); - - PrintCursorExtent(C); - printf("\n"); - clang_disposeString(USR); - - return CXChildVisit_Recurse; - } - - return CXChildVisit_Continue; -} - -/******************************************************************************/ -/* Inclusion stack testing. */ -/******************************************************************************/ - -void InclusionVisitor(CXFile includedFile, CXSourceLocation *includeStack, - unsigned includeStackLen, CXClientData data) { - - unsigned i; - CXString fname; - - fname = clang_getFileName(includedFile); - printf("file: %s\nincluded by:\n", clang_getCString(fname)); - clang_disposeString(fname); - - for (i = 0; i < includeStackLen; ++i) { - CXFile includingFile; - unsigned line, column; - clang_getInstantiationLocation(includeStack[i], &includingFile, &line, - &column, 0); - fname = clang_getFileName(includingFile); - printf(" %s:%d:%d\n", clang_getCString(fname), line, column); - clang_disposeString(fname); - } - printf("\n"); -} - -void PrintInclusionStack(CXTranslationUnit TU) { - clang_getInclusions(TU, InclusionVisitor, NULL); -} - -/******************************************************************************/ -/* Linkage testing. */ -/******************************************************************************/ - -static enum CXChildVisitResult PrintLinkage(CXCursor cursor, CXCursor p, - CXClientData d) { - const char *linkage = 0; - - if (clang_isInvalid(clang_getCursorKind(cursor))) - return CXChildVisit_Recurse; - - switch (clang_getCursorLinkage(cursor)) { - case CXLinkage_Invalid: break; - case CXLinkage_NoLinkage: linkage = "NoLinkage"; break; - case CXLinkage_Internal: linkage = "Internal"; break; - case CXLinkage_UniqueExternal: linkage = "UniqueExternal"; break; - case CXLinkage_External: linkage = "External"; break; - } - - if (linkage) { - PrintCursor(cursor); - printf("linkage=%s\n", linkage); - } - - return CXChildVisit_Recurse; -} - -/******************************************************************************/ -/* Typekind testing. */ -/******************************************************************************/ - -static enum CXChildVisitResult PrintTypeKind(CXCursor cursor, CXCursor p, - CXClientData d) { - - if (!clang_isInvalid(clang_getCursorKind(cursor))) { - CXType T = clang_getCursorType(cursor); - CXString S = clang_getTypeKindSpelling(T.kind); - PrintCursor(cursor); - printf(" typekind=%s", clang_getCString(S)); - clang_disposeString(S); - /* Print the canonical type if it is different. */ - { - CXType CT = clang_getCanonicalType(T); - if (!clang_equalTypes(T, CT)) { - CXString CS = clang_getTypeKindSpelling(CT.kind); - printf(" [canonical=%s]", clang_getCString(CS)); - clang_disposeString(CS); - } - } - /* Print the return type if it exists. */ - { - CXType RT = clang_getCursorResultType(cursor); - if (RT.kind != CXType_Invalid) { - CXString RS = clang_getTypeKindSpelling(RT.kind); - printf(" [result=%s]", clang_getCString(RS)); - clang_disposeString(RS); - } - } - /* Print if this is a non-POD type. */ - printf(" [isPOD=%d]", clang_isPODType(T)); - - printf("\n"); - } - return CXChildVisit_Recurse; -} - - -/******************************************************************************/ -/* Loading ASTs/source. */ -/******************************************************************************/ - -static int perform_test_load(CXIndex Idx, CXTranslationUnit TU, - const char *filter, const char *prefix, - CXCursorVisitor Visitor, - PostVisitTU PV) { - - if (prefix) - FileCheckPrefix = prefix; - - if (Visitor) { - enum CXCursorKind K = CXCursor_NotImplemented; - enum CXCursorKind *ck = &K; - VisitorData Data; - - /* Perform some simple filtering. */ - if (!strcmp(filter, "all") || !strcmp(filter, "local")) ck = NULL; - else if (!strcmp(filter, "none")) K = (enum CXCursorKind) ~0; - else if (!strcmp(filter, "category")) K = CXCursor_ObjCCategoryDecl; - else if (!strcmp(filter, "interface")) K = CXCursor_ObjCInterfaceDecl; - else if (!strcmp(filter, "protocol")) K = CXCursor_ObjCProtocolDecl; - else if (!strcmp(filter, "function")) K = CXCursor_FunctionDecl; - else if (!strcmp(filter, "typedef")) K = CXCursor_TypedefDecl; - else if (!strcmp(filter, "scan-function")) Visitor = FunctionScanVisitor; - else { - fprintf(stderr, "Unknown filter for -test-load-tu: %s\n", filter); - return 1; - } - - Data.TU = TU; - Data.Filter = ck; - clang_visitChildren(clang_getTranslationUnitCursor(TU), Visitor, &Data); - } - - if (PV) - PV(TU); - - PrintDiagnostics(TU); - clang_disposeTranslationUnit(TU); - return 0; -} - -int perform_test_load_tu(const char *file, const char *filter, - const char *prefix, CXCursorVisitor Visitor, - PostVisitTU PV) { - CXIndex Idx; - CXTranslationUnit TU; - int result; - Idx = clang_createIndex(/* excludeDeclsFromPCH */ - !strcmp(filter, "local") ? 1 : 0, - /* displayDiagnosics=*/1); - - if (!CreateTranslationUnit(Idx, file, &TU)) { - clang_disposeIndex(Idx); - return 1; - } - - result = perform_test_load(Idx, TU, filter, prefix, Visitor, PV); - clang_disposeIndex(Idx); - return result; -} - -int perform_test_load_source(int argc, const char **argv, - const char *filter, CXCursorVisitor Visitor, - PostVisitTU PV) { - const char *UseExternalASTs = - getenv("CINDEXTEST_USE_EXTERNAL_AST_GENERATION"); - CXIndex Idx; - CXTranslationUnit TU; - struct CXUnsavedFile *unsaved_files = 0; - int num_unsaved_files = 0; - int result; - - Idx = clang_createIndex(/* excludeDeclsFromPCH */ - !strcmp(filter, "local") ? 1 : 0, - /* displayDiagnosics=*/1); - - if (UseExternalASTs && strlen(UseExternalASTs)) - clang_setUseExternalASTGeneration(Idx, 1); - - if (parse_remapped_files(argc, argv, 0, &unsaved_files, &num_unsaved_files)) { - clang_disposeIndex(Idx); - return -1; - } - - TU = clang_createTranslationUnitFromSourceFile(Idx, 0, - argc - num_unsaved_files, - argv + num_unsaved_files, - num_unsaved_files, - unsaved_files); - if (!TU) { - fprintf(stderr, "Unable to load translation unit!\n"); - free_remapped_files(unsaved_files, num_unsaved_files); - clang_disposeIndex(Idx); - return 1; - } - - result = perform_test_load(Idx, TU, filter, NULL, Visitor, PV); - free_remapped_files(unsaved_files, num_unsaved_files); - clang_disposeIndex(Idx); - return result; -} - -int perform_test_reparse_source(int argc, const char **argv, int trials, - const char *filter, CXCursorVisitor Visitor, - PostVisitTU PV) { - const char *UseExternalASTs = - getenv("CINDEXTEST_USE_EXTERNAL_AST_GENERATION"); - CXIndex Idx; - CXTranslationUnit TU; - struct CXUnsavedFile *unsaved_files = 0; - int num_unsaved_files = 0; - int result; - int trial; - - Idx = clang_createIndex(/* excludeDeclsFromPCH */ - !strcmp(filter, "local") ? 1 : 0, - /* displayDiagnosics=*/1); - - if (UseExternalASTs && strlen(UseExternalASTs)) - clang_setUseExternalASTGeneration(Idx, 1); - - if (parse_remapped_files(argc, argv, 0, &unsaved_files, &num_unsaved_files)) { - clang_disposeIndex(Idx); - return -1; - } - - /* Load the initial translation unit -- we do this without honoring remapped - * files, so that we have a way to test results after changing the source. */ - TU = clang_parseTranslationUnit(Idx, 0, - argv + num_unsaved_files, - argc - num_unsaved_files, - 0, 0, getDefaultParsingOptions()); - if (!TU) { - fprintf(stderr, "Unable to load translation unit!\n"); - free_remapped_files(unsaved_files, num_unsaved_files); - clang_disposeIndex(Idx); - return 1; - } - - for (trial = 0; trial < trials; ++trial) { - if (clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files, - clang_defaultReparseOptions(TU))) { - fprintf(stderr, "Unable to reparse translation unit!\n"); - clang_disposeTranslationUnit(TU); - free_remapped_files(unsaved_files, num_unsaved_files); - clang_disposeIndex(Idx); - return -1; - } - } - - result = perform_test_load(Idx, TU, filter, NULL, Visitor, PV); - free_remapped_files(unsaved_files, num_unsaved_files); - clang_disposeIndex(Idx); - return result; -} - -/******************************************************************************/ -/* Logic for testing clang_getCursor(). */ -/******************************************************************************/ - -static void print_cursor_file_scan(CXCursor cursor, - unsigned start_line, unsigned start_col, - unsigned end_line, unsigned end_col, - const char *prefix) { - printf("// %s: ", FileCheckPrefix); - if (prefix) - printf("-%s", prefix); - PrintExtent(stdout, start_line, start_col, end_line, end_col); - printf(" "); - PrintCursor(cursor); - printf("\n"); -} - -static int perform_file_scan(const char *ast_file, const char *source_file, - const char *prefix) { - CXIndex Idx; - CXTranslationUnit TU; - FILE *fp; - CXCursor prevCursor = clang_getNullCursor(); - CXFile file; - unsigned line = 1, col = 1; - unsigned start_line = 1, start_col = 1; - - if (!(Idx = clang_createIndex(/* excludeDeclsFromPCH */ 1, - /* displayDiagnosics=*/1))) { - fprintf(stderr, "Could not create Index\n"); - return 1; - } - - if (!CreateTranslationUnit(Idx, ast_file, &TU)) - return 1; - - if ((fp = fopen(source_file, "r")) == NULL) { - fprintf(stderr, "Could not open '%s'\n", source_file); - return 1; - } - - file = clang_getFile(TU, source_file); - for (;;) { - CXCursor cursor; - int c = fgetc(fp); - - if (c == '\n') { - ++line; - col = 1; - } else - ++col; - - /* Check the cursor at this position, and dump the previous one if we have - * found something new. - */ - cursor = clang_getCursor(TU, clang_getLocation(TU, file, line, col)); - if ((c == EOF || !clang_equalCursors(cursor, prevCursor)) && - prevCursor.kind != CXCursor_InvalidFile) { - print_cursor_file_scan(prevCursor, start_line, start_col, - line, col, prefix); - start_line = line; - start_col = col; - } - if (c == EOF) - break; - - prevCursor = cursor; - } - - fclose(fp); - return 0; -} - -/******************************************************************************/ -/* Logic for testing clang_codeComplete(). */ -/******************************************************************************/ - -/* Parse file:line:column from the input string. Returns 0 on success, non-zero - on failure. If successful, the pointer *filename will contain newly-allocated - memory (that will be owned by the caller) to store the file name. */ -int parse_file_line_column(const char *input, char **filename, unsigned *line, - unsigned *column, unsigned *second_line, - unsigned *second_column) { - /* Find the second colon. */ - const char *last_colon = strrchr(input, ':'); - unsigned values[4], i; - unsigned num_values = (second_line && second_column)? 4 : 2; - - char *endptr = 0; - if (!last_colon || last_colon == input) { - if (num_values == 4) - fprintf(stderr, "could not parse filename:line:column:line:column in " - "'%s'\n", input); - else - fprintf(stderr, "could not parse filename:line:column in '%s'\n", input); - return 1; - } - - for (i = 0; i != num_values; ++i) { - const char *prev_colon; - - /* Parse the next line or column. */ - values[num_values - i - 1] = strtol(last_colon + 1, &endptr, 10); - if (*endptr != 0 && *endptr != ':') { - fprintf(stderr, "could not parse %s in '%s'\n", - (i % 2 ? "column" : "line"), input); - return 1; - } - - if (i + 1 == num_values) - break; - - /* Find the previous colon. */ - prev_colon = last_colon - 1; - while (prev_colon != input && *prev_colon != ':') - --prev_colon; - if (prev_colon == input) { - fprintf(stderr, "could not parse %s in '%s'\n", - (i % 2 == 0? "column" : "line"), input); - return 1; - } - - last_colon = prev_colon; - } - - *line = values[0]; - *column = values[1]; - - if (second_line && second_column) { - *second_line = values[2]; - *second_column = values[3]; - } - - /* Copy the file name. */ - *filename = (char*)malloc(last_colon - input + 1); - memcpy(*filename, input, last_colon - input); - (*filename)[last_colon - input] = 0; - return 0; -} - -const char * -clang_getCompletionChunkKindSpelling(enum CXCompletionChunkKind Kind) { - switch (Kind) { - case CXCompletionChunk_Optional: return "Optional"; - case CXCompletionChunk_TypedText: return "TypedText"; - case CXCompletionChunk_Text: return "Text"; - case CXCompletionChunk_Placeholder: return "Placeholder"; - case CXCompletionChunk_Informative: return "Informative"; - case CXCompletionChunk_CurrentParameter: return "CurrentParameter"; - case CXCompletionChunk_LeftParen: return "LeftParen"; - case CXCompletionChunk_RightParen: return "RightParen"; - case CXCompletionChunk_LeftBracket: return "LeftBracket"; - case CXCompletionChunk_RightBracket: return "RightBracket"; - case CXCompletionChunk_LeftBrace: return "LeftBrace"; - case CXCompletionChunk_RightBrace: return "RightBrace"; - case CXCompletionChunk_LeftAngle: return "LeftAngle"; - case CXCompletionChunk_RightAngle: return "RightAngle"; - case CXCompletionChunk_Comma: return "Comma"; - case CXCompletionChunk_ResultType: return "ResultType"; - case CXCompletionChunk_Colon: return "Colon"; - case CXCompletionChunk_SemiColon: return "SemiColon"; - case CXCompletionChunk_Equal: return "Equal"; - case CXCompletionChunk_HorizontalSpace: return "HorizontalSpace"; - case CXCompletionChunk_VerticalSpace: return "VerticalSpace"; - } - - return "Unknown"; -} - -void print_completion_string(CXCompletionString completion_string, FILE *file) { - int I, N; - - N = clang_getNumCompletionChunks(completion_string); - for (I = 0; I != N; ++I) { - CXString text; - const char *cstr; - enum CXCompletionChunkKind Kind - = clang_getCompletionChunkKind(completion_string, I); - - if (Kind == CXCompletionChunk_Optional) { - fprintf(file, "{Optional "); - print_completion_string( - clang_getCompletionChunkCompletionString(completion_string, I), - file); - fprintf(file, "}"); - continue; - } - - text = clang_getCompletionChunkText(completion_string, I); - cstr = clang_getCString(text); - fprintf(file, "{%s %s}", - clang_getCompletionChunkKindSpelling(Kind), - cstr ? cstr : ""); - clang_disposeString(text); - } - -} - -void print_completion_result(CXCompletionResult *completion_result, - CXClientData client_data) { - FILE *file = (FILE *)client_data; - CXString ks = clang_getCursorKindSpelling(completion_result->CursorKind); - - fprintf(file, "%s:", clang_getCString(ks)); - clang_disposeString(ks); - - print_completion_string(completion_result->CompletionString, file); - fprintf(file, " (%u)", - clang_getCompletionPriority(completion_result->CompletionString)); - switch (clang_getCompletionAvailability(completion_result->CompletionString)){ - case CXAvailability_Available: - break; - - case CXAvailability_Deprecated: - fprintf(file, " (deprecated)"); - break; - - case CXAvailability_NotAvailable: - fprintf(file, " (unavailable)"); - break; - } - fprintf(file, "\n"); -} - -int my_stricmp(const char *s1, const char *s2) { - while (*s1 && *s2) { - int c1 = tolower(*s1), c2 = tolower(*s2); - if (c1 < c2) - return -1; - else if (c1 > c2) - return 1; - - ++s1; - ++s2; - } - - if (*s1) - return 1; - else if (*s2) - return -1; - return 0; -} - -int perform_code_completion(int argc, const char **argv, int timing_only) { - const char *input = argv[1]; - char *filename = 0; - unsigned line; - unsigned column; - CXIndex CIdx; - int errorCode; - struct CXUnsavedFile *unsaved_files = 0; - int num_unsaved_files = 0; - CXCodeCompleteResults *results = 0; - CXTranslationUnit *TU = 0; - - if (timing_only) - input += strlen("-code-completion-timing="); - else - input += strlen("-code-completion-at="); - - if ((errorCode = parse_file_line_column(input, &filename, &line, &column, - 0, 0))) - return errorCode; - - if (parse_remapped_files(argc, argv, 2, &unsaved_files, &num_unsaved_files)) - return -1; - - CIdx = clang_createIndex(0, 1); - if (getenv("CINDEXTEST_EDITING")) { - unsigned I, Repeats = 5; - TU = clang_parseTranslationUnit(CIdx, 0, - argv + num_unsaved_files + 2, - argc - num_unsaved_files - 2, - 0, 0, getDefaultParsingOptions()); - if (!TU) { - fprintf(stderr, "Unable to load translation unit!\n"); - return 1; - } - for (I = 0; I != Repeats; ++I) { - results = clang_codeCompleteAt(TU, filename, line, column, - unsaved_files, num_unsaved_files, - clang_defaultCodeCompleteOptions()); - if (!results) { - fprintf(stderr, "Unable to perform code completion!\n"); - return 1; - } - if (I != Repeats-1) - clang_disposeCodeCompleteResults(results); - } - } else - results = clang_codeComplete(CIdx, - argv[argc - 1], argc - num_unsaved_files - 3, - argv + num_unsaved_files + 2, - num_unsaved_files, unsaved_files, - filename, line, column); - - if (results) { - unsigned i, n = results->NumResults; - if (!timing_only) { - /* Sort the code-completion results based on the typed text. */ - clang_sortCodeCompletionResults(results->Results, results->NumResults); - - for (i = 0; i != n; ++i) - print_completion_result(results->Results + i, stdout); - } - n = clang_codeCompleteGetNumDiagnostics(results); - for (i = 0; i != n; ++i) { - CXDiagnostic diag = clang_codeCompleteGetDiagnostic(results, i); - PrintDiagnostic(diag); - clang_disposeDiagnostic(diag); - } - clang_disposeCodeCompleteResults(results); - } - clang_disposeTranslationUnit(TU); - clang_disposeIndex(CIdx); - free(filename); - - free_remapped_files(unsaved_files, num_unsaved_files); - - return 0; -} - -typedef struct { - char *filename; - unsigned line; - unsigned column; -} CursorSourceLocation; - -int inspect_cursor_at(int argc, const char **argv) { - CXIndex CIdx; - int errorCode; - struct CXUnsavedFile *unsaved_files = 0; - int num_unsaved_files = 0; - CXTranslationUnit TU; - CXCursor Cursor; - CursorSourceLocation *Locations = 0; - unsigned NumLocations = 0, Loc; - - /* Count the number of locations. */ - while (strstr(argv[NumLocations+1], "-cursor-at=") == argv[NumLocations+1]) - ++NumLocations; - - /* Parse the locations. */ - assert(NumLocations > 0 && "Unable to count locations?"); - Locations = (CursorSourceLocation *)malloc( - NumLocations * sizeof(CursorSourceLocation)); - for (Loc = 0; Loc < NumLocations; ++Loc) { - const char *input = argv[Loc + 1] + strlen("-cursor-at="); - if ((errorCode = parse_file_line_column(input, &Locations[Loc].filename, - &Locations[Loc].line, - &Locations[Loc].column, 0, 0))) - return errorCode; - } - - if (parse_remapped_files(argc, argv, NumLocations + 1, &unsaved_files, - &num_unsaved_files)) - return -1; - - CIdx = clang_createIndex(0, 1); - TU = clang_createTranslationUnitFromSourceFile(CIdx, argv[argc - 1], - argc - num_unsaved_files - 2 - NumLocations, - argv + num_unsaved_files + 1 + NumLocations, - num_unsaved_files, - unsaved_files); - if (!TU) { - fprintf(stderr, "unable to parse input\n"); - return -1; - } - - for (Loc = 0; Loc < NumLocations; ++Loc) { - CXFile file = clang_getFile(TU, Locations[Loc].filename); - if (!file) - continue; - - Cursor = clang_getCursor(TU, - clang_getLocation(TU, file, Locations[Loc].line, - Locations[Loc].column)); - PrintCursor(Cursor); - printf("\n"); - free(Locations[Loc].filename); - } - - PrintDiagnostics(TU); - clang_disposeTranslationUnit(TU); - clang_disposeIndex(CIdx); - free(Locations); - free_remapped_files(unsaved_files, num_unsaved_files); - return 0; -} - -int perform_token_annotation(int argc, const char **argv) { - const char *input = argv[1]; - char *filename = 0; - unsigned line, second_line; - unsigned column, second_column; - CXIndex CIdx; - CXTranslationUnit TU = 0; - int errorCode; - struct CXUnsavedFile *unsaved_files = 0; - int num_unsaved_files = 0; - CXToken *tokens; - unsigned num_tokens; - CXSourceRange range; - CXSourceLocation startLoc, endLoc; - CXFile file = 0; - CXCursor *cursors = 0; - unsigned i; - - input += strlen("-test-annotate-tokens="); - if ((errorCode = parse_file_line_column(input, &filename, &line, &column, - &second_line, &second_column))) - return errorCode; - - if (parse_remapped_files(argc, argv, 2, &unsaved_files, &num_unsaved_files)) - return -1; - - CIdx = clang_createIndex(0, 1); - TU = clang_createTranslationUnitFromSourceFile(CIdx, argv[argc - 1], - argc - num_unsaved_files - 3, - argv + num_unsaved_files + 2, - num_unsaved_files, - unsaved_files); - if (!TU) { - fprintf(stderr, "unable to parse input\n"); - clang_disposeIndex(CIdx); - free(filename); - free_remapped_files(unsaved_files, num_unsaved_files); - return -1; - } - errorCode = 0; - - file = clang_getFile(TU, filename); - if (!file) { - fprintf(stderr, "file %s is not in this translation unit\n", filename); - errorCode = -1; - goto teardown; - } - - startLoc = clang_getLocation(TU, file, line, column); - if (clang_equalLocations(clang_getNullLocation(), startLoc)) { - fprintf(stderr, "invalid source location %s:%d:%d\n", filename, line, - column); - errorCode = -1; - goto teardown; - } - - endLoc = clang_getLocation(TU, file, second_line, second_column); - if (clang_equalLocations(clang_getNullLocation(), endLoc)) { - fprintf(stderr, "invalid source location %s:%d:%d\n", filename, - second_line, second_column); - errorCode = -1; - goto teardown; - } - - range = clang_getRange(startLoc, endLoc); - clang_tokenize(TU, range, &tokens, &num_tokens); - cursors = (CXCursor *)malloc(num_tokens * sizeof(CXCursor)); - clang_annotateTokens(TU, tokens, num_tokens, cursors); - for (i = 0; i != num_tokens; ++i) { - const char *kind = "<unknown>"; - CXString spelling = clang_getTokenSpelling(TU, tokens[i]); - CXSourceRange extent = clang_getTokenExtent(TU, tokens[i]); - unsigned start_line, start_column, end_line, end_column; - - switch (clang_getTokenKind(tokens[i])) { - case CXToken_Punctuation: kind = "Punctuation"; break; - case CXToken_Keyword: kind = "Keyword"; break; - case CXToken_Identifier: kind = "Identifier"; break; - case CXToken_Literal: kind = "Literal"; break; - case CXToken_Comment: kind = "Comment"; break; - } - clang_getInstantiationLocation(clang_getRangeStart(extent), - 0, &start_line, &start_column, 0); - clang_getInstantiationLocation(clang_getRangeEnd(extent), - 0, &end_line, &end_column, 0); - printf("%s: \"%s\" ", kind, clang_getCString(spelling)); - PrintExtent(stdout, start_line, start_column, end_line, end_column); - if (!clang_isInvalid(cursors[i].kind)) { - printf(" "); - PrintCursor(cursors[i]); - } - printf("\n"); - } - free(cursors); - - teardown: - PrintDiagnostics(TU); - clang_disposeTranslationUnit(TU); - clang_disposeIndex(CIdx); - free(filename); - free_remapped_files(unsaved_files, num_unsaved_files); - return errorCode; -} - -/******************************************************************************/ -/* USR printing. */ -/******************************************************************************/ - -static int insufficient_usr(const char *kind, const char *usage) { - fprintf(stderr, "USR for '%s' requires: %s\n", kind, usage); - return 1; -} - -static unsigned isUSR(const char *s) { - return s[0] == 'c' && s[1] == ':'; -} - -static int not_usr(const char *s, const char *arg) { - fprintf(stderr, "'%s' argument ('%s') is not a USR\n", s, arg); - return 1; -} - -static void print_usr(CXString usr) { - const char *s = clang_getCString(usr); - printf("%s\n", s); - clang_disposeString(usr); -} - -static void display_usrs() { - fprintf(stderr, "-print-usrs options:\n" - " ObjCCategory <class name> <category name>\n" - " ObjCClass <class name>\n" - " ObjCIvar <ivar name> <class USR>\n" - " ObjCMethod <selector> [0=class method|1=instance method] " - "<class USR>\n" - " ObjCProperty <property name> <class USR>\n" - " ObjCProtocol <protocol name>\n"); -} - -int print_usrs(const char **I, const char **E) { - while (I != E) { - const char *kind = *I; - unsigned len = strlen(kind); - switch (len) { - case 8: - if (memcmp(kind, "ObjCIvar", 8) == 0) { - if (I + 2 >= E) - return insufficient_usr(kind, "<ivar name> <class USR>"); - if (!isUSR(I[2])) - return not_usr("<class USR>", I[2]); - else { - CXString x; - x.Spelling = I[2]; - x.MustFreeString = 0; - print_usr(clang_constructUSR_ObjCIvar(I[1], x)); - } - - I += 3; - continue; - } - break; - case 9: - if (memcmp(kind, "ObjCClass", 9) == 0) { - if (I + 1 >= E) - return insufficient_usr(kind, "<class name>"); - print_usr(clang_constructUSR_ObjCClass(I[1])); - I += 2; - continue; - } - break; - case 10: - if (memcmp(kind, "ObjCMethod", 10) == 0) { - if (I + 3 >= E) - return insufficient_usr(kind, "<method selector> " - "[0=class method|1=instance method] <class USR>"); - if (!isUSR(I[3])) - return not_usr("<class USR>", I[3]); - else { - CXString x; - x.Spelling = I[3]; - x.MustFreeString = 0; - print_usr(clang_constructUSR_ObjCMethod(I[1], atoi(I[2]), x)); - } - I += 4; - continue; - } - break; - case 12: - if (memcmp(kind, "ObjCCategory", 12) == 0) { - if (I + 2 >= E) - return insufficient_usr(kind, "<class name> <category name>"); - print_usr(clang_constructUSR_ObjCCategory(I[1], I[2])); - I += 3; - continue; - } - if (memcmp(kind, "ObjCProtocol", 12) == 0) { - if (I + 1 >= E) - return insufficient_usr(kind, "<protocol name>"); - print_usr(clang_constructUSR_ObjCProtocol(I[1])); - I += 2; - continue; - } - if (memcmp(kind, "ObjCProperty", 12) == 0) { - if (I + 2 >= E) - return insufficient_usr(kind, "<property name> <class USR>"); - if (!isUSR(I[2])) - return not_usr("<class USR>", I[2]); - else { - CXString x; - x.Spelling = I[2]; - x.MustFreeString = 0; - print_usr(clang_constructUSR_ObjCProperty(I[1], x)); - } - I += 3; - continue; - } - break; - default: - break; - } - break; - } - - if (I != E) { - fprintf(stderr, "Invalid USR kind: %s\n", *I); - display_usrs(); - return 1; - } - return 0; -} - -int print_usrs_file(const char *file_name) { - char line[2048]; - const char *args[128]; - unsigned numChars = 0; - - FILE *fp = fopen(file_name, "r"); - if (!fp) { - fprintf(stderr, "error: cannot open '%s'\n", file_name); - return 1; - } - - /* This code is not really all that safe, but it works fine for testing. */ - while (!feof(fp)) { - char c = fgetc(fp); - if (c == '\n') { - unsigned i = 0; - const char *s = 0; - - if (numChars == 0) - continue; - - line[numChars] = '\0'; - numChars = 0; - - if (line[0] == '/' && line[1] == '/') - continue; - - s = strtok(line, " "); - while (s) { - args[i] = s; - ++i; - s = strtok(0, " "); - } - if (print_usrs(&args[0], &args[i])) - return 1; - } - else - line[numChars++] = c; - } - - fclose(fp); - return 0; -} - -/******************************************************************************/ -/* Command line processing. */ -/******************************************************************************/ -int write_pch_file(const char *filename, int argc, const char *argv[]) { - CXIndex Idx; - CXTranslationUnit TU; - struct CXUnsavedFile *unsaved_files = 0; - int num_unsaved_files = 0; - - Idx = clang_createIndex(/* excludeDeclsFromPCH */1, /* displayDiagnosics=*/1); - - if (parse_remapped_files(argc, argv, 0, &unsaved_files, &num_unsaved_files)) { - clang_disposeIndex(Idx); - return -1; - } - - TU = clang_parseTranslationUnit(Idx, 0, - argv + num_unsaved_files, - argc - num_unsaved_files, - unsaved_files, - num_unsaved_files, - CXTranslationUnit_Incomplete); - if (!TU) { - fprintf(stderr, "Unable to load translation unit!\n"); - free_remapped_files(unsaved_files, num_unsaved_files); - clang_disposeIndex(Idx); - return 1; - } - - if (clang_saveTranslationUnit(TU, filename, clang_defaultSaveOptions(TU))) - fprintf(stderr, "Unable to write PCH file %s\n", filename); - clang_disposeTranslationUnit(TU); - free_remapped_files(unsaved_files, num_unsaved_files); - clang_disposeIndex(Idx); - return 0; -} - -/******************************************************************************/ -/* Command line processing. */ -/******************************************************************************/ - -static CXCursorVisitor GetVisitor(const char *s) { - if (s[0] == '\0') - return FilteredPrintingVisitor; - if (strcmp(s, "-usrs") == 0) - return USRVisitor; - return NULL; -} - -static void print_usage(void) { - fprintf(stderr, - "usage: c-index-test -code-completion-at=<site> <compiler arguments>\n" - " c-index-test -code-completion-timing=<site> <compiler arguments>\n" - " c-index-test -cursor-at=<site> <compiler arguments>\n" - " c-index-test -test-file-scan <AST file> <source file> " - "[FileCheck prefix]\n" - " c-index-test -test-load-tu <AST file> <symbol filter> " - "[FileCheck prefix]\n" - " c-index-test -test-load-tu-usrs <AST file> <symbol filter> " - "[FileCheck prefix]\n" - " c-index-test -test-load-source <symbol filter> {<args>}*\n"); - fprintf(stderr, - " c-index-test -test-load-source-reparse <trials> <symbol filter> " - " {<args>}*\n" - " c-index-test -test-load-source-usrs <symbol filter> {<args>}*\n" - " c-index-test -test-annotate-tokens=<range> {<args>}*\n" - " c-index-test -test-inclusion-stack-source {<args>}*\n" - " c-index-test -test-inclusion-stack-tu <AST file>\n" - " c-index-test -test-print-linkage-source {<args>}*\n" - " c-index-test -test-print-typekind {<args>}*\n" - " c-index-test -print-usr [<CursorKind> {<args>}]*\n"); - fprintf(stderr, - " c-index-test -print-usr-file <file>\n" - " c-index-test -write-pch <file> <compiler arguments>\n\n"); - fprintf(stderr, - " <symbol filter> values:\n%s", - " all - load all symbols, including those from PCH\n" - " local - load all symbols except those in PCH\n" - " category - only load ObjC categories (non-PCH)\n" - " interface - only load ObjC interfaces (non-PCH)\n" - " protocol - only load ObjC protocols (non-PCH)\n" - " function - only load functions (non-PCH)\n" - " typedef - only load typdefs (non-PCH)\n" - " scan-function - scan function bodies (non-PCH)\n\n"); -} - -int main(int argc, const char **argv) { - clang_enableStackTraces(); - if (argc > 2 && strstr(argv[1], "-code-completion-at=") == argv[1]) - return perform_code_completion(argc, argv, 0); - if (argc > 2 && strstr(argv[1], "-code-completion-timing=") == argv[1]) - return perform_code_completion(argc, argv, 1); - if (argc > 2 && strstr(argv[1], "-cursor-at=") == argv[1]) - return inspect_cursor_at(argc, argv); - else if (argc >= 4 && strncmp(argv[1], "-test-load-tu", 13) == 0) { - CXCursorVisitor I = GetVisitor(argv[1] + 13); - if (I) - return perform_test_load_tu(argv[2], argv[3], argc >= 5 ? argv[4] : 0, I, - NULL); - } - else if (argc >= 5 && strncmp(argv[1], "-test-load-source-reparse", 25) == 0){ - CXCursorVisitor I = GetVisitor(argv[1] + 25); - if (I) { - int trials = atoi(argv[2]); - return perform_test_reparse_source(argc - 4, argv + 4, trials, argv[3], I, - NULL); - } - } - else if (argc >= 4 && strncmp(argv[1], "-test-load-source", 17) == 0) { - CXCursorVisitor I = GetVisitor(argv[1] + 17); - if (I) - return perform_test_load_source(argc - 3, argv + 3, argv[2], I, NULL); - } - else if (argc >= 4 && strcmp(argv[1], "-test-file-scan") == 0) - return perform_file_scan(argv[2], argv[3], - argc >= 5 ? argv[4] : 0); - else if (argc > 2 && strstr(argv[1], "-test-annotate-tokens=") == argv[1]) - return perform_token_annotation(argc, argv); - else if (argc > 2 && strcmp(argv[1], "-test-inclusion-stack-source") == 0) - return perform_test_load_source(argc - 2, argv + 2, "all", NULL, - PrintInclusionStack); - else if (argc > 2 && strcmp(argv[1], "-test-inclusion-stack-tu") == 0) - return perform_test_load_tu(argv[2], "all", NULL, NULL, - PrintInclusionStack); - else if (argc > 2 && strcmp(argv[1], "-test-print-linkage-source") == 0) - return perform_test_load_source(argc - 2, argv + 2, "all", PrintLinkage, - NULL); - else if (argc > 2 && strcmp(argv[1], "-test-print-typekind") == 0) - return perform_test_load_source(argc - 2, argv + 2, "all", - PrintTypeKind, 0); - else if (argc > 1 && strcmp(argv[1], "-print-usr") == 0) { - if (argc > 2) - return print_usrs(argv + 2, argv + argc); - else { - display_usrs(); - return 1; - } - } - else if (argc > 2 && strcmp(argv[1], "-print-usr-file") == 0) - return print_usrs_file(argv[2]); - else if (argc > 2 && strcmp(argv[1], "-write-pch") == 0) - return write_pch_file(argv[2], argc - 3, argv + 3); - - print_usage(); - return 1; -} diff --git a/contrib/llvm/tools/clang/tools/driver/CMakeLists.txt b/contrib/llvm/tools/clang/tools/driver/CMakeLists.txt deleted file mode 100644 index ec6e9c6..0000000 --- a/contrib/llvm/tools/clang/tools/driver/CMakeLists.txt +++ /dev/null @@ -1,54 +0,0 @@ -set(LLVM_NO_RTTI 1) - -set( LLVM_USED_LIBS - clangFrontendTool - clangFrontend - clangDriver - clangSerialization - clangCodeGen - clangParse - clangSema - clangChecker - clangAnalysis - clangIndex - clangRewrite - clangAST - clangLex - clangBasic - ) - -set( LLVM_LINK_COMPONENTS - ${LLVM_TARGETS_TO_BUILD} - asmparser - bitreader - bitwriter - codegen - ipo - selectiondag - ) - -add_clang_executable(clang - driver.cpp - cc1_main.cpp - cc1as_main.cpp - ) - -if(UNIX) - set(CLANGXX_LINK_OR_COPY create_symlink) - set(CLANGXX_DESTDIR $ENV{DESTDIR}/) -else() - set(CLANGXX_LINK_OR_COPY copy) -endif() - -# Create the clang++ symlink in the build directory. -add_custom_target(clang++ ALL - ${CMAKE_COMMAND} -E ${CLANGXX_LINK_OR_COPY} - "${LLVM_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/clang${CMAKE_EXECUTABLE_SUFFIX}" - "${LLVM_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/clang++${CMAKE_EXECUTABLE_SUFFIX}" - DEPENDS clang) - -install(TARGETS clang - RUNTIME DESTINATION bin) - -# Create the clang++ symlink at installation time. -install(CODE "execute_process(COMMAND \"${CMAKE_COMMAND}\" -E ${CLANGXX_LINK_OR_COPY} \"${CMAKE_INSTALL_PREFIX}/bin/clang${CMAKE_EXECUTABLE_SUFFIX}\" \"${CLANGXX_DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/clang++${CMAKE_EXECUTABLE_SUFFIX}\")") diff --git a/contrib/llvm/tools/clang/tools/driver/Info.plist.in b/contrib/llvm/tools/clang/tools/driver/Info.plist.in deleted file mode 100644 index c938fb0..0000000 --- a/contrib/llvm/tools/clang/tools/driver/Info.plist.in +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>CFBundleIdentifier</key> - <string>@TOOL_INFO_UTI@</string> - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string> - <key>CFBundleName</key> - <string>@TOOL_INFO_NAME</string> - <key>CFBundleShortVersionString</key> - <string>@TOOL_INFO_VERSION@</string> - <key>CFBundleVersion</key> - <string>@TOOL_INFO_BUILD_VERSION@</string> - <key>CFBundleSignature</key> - <string>????</string> -</dict> -</plist> diff --git a/contrib/llvm/tools/clang/tools/driver/Makefile b/contrib/llvm/tools/clang/tools/driver/Makefile deleted file mode 100644 index 447f0e4..0000000 --- a/contrib/llvm/tools/clang/tools/driver/Makefile +++ /dev/null @@ -1,66 +0,0 @@ -##===- tools/driver/Makefile -------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -CLANG_LEVEL := ../.. - -TOOLNAME = clang -ifndef CLANG_IS_PRODUCTION -TOOLALIAS = clang++ -else - ifdef CLANGXX_IS_PRODUCTION - TOOLALIAS = clang++ - endif -endif - -# Include tool version information on OS X. -TOOL_INFO_PLIST := Info.plist - -# 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 $(CLANG_LEVEL)/../../Makefile.config - -LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader bitwriter codegen \ - ipo selectiondag -USEDLIBS = clangFrontendTool.a clangFrontend.a clangDriver.a \ - clangSerialization.a clangCodeGen.a clangParse.a clangSema.a \ - clangChecker.a clangAnalysis.a clangIndex.a clangRewrite.a \ - clangAST.a clangLex.a clangBasic.a - -include $(CLANG_LEVEL)/Makefile - -# Set the tool version information values. -ifeq ($(HOST_OS),Darwin) -ifdef CLANG_VENDOR -TOOL_INFO_NAME := $(CLANG_VENDOR) clang -else -TOOL_INFO_NAME := clang -endif - -ifdef CLANG_VENDOR_UTI -TOOL_INFO_UTI := $(CLANG_VENDOR_UTI) -else -TOOL_INFO_UTI := org.llvm.clang -endif - -TOOL_INFO_VERSION := $(word 3,$(shell grep "CLANG_VERSION " \ - $(PROJ_OBJ_DIR)/$(CLANG_LEVEL)/include/clang/Basic/Version.inc)) -ifdef LLVM_SUBMIT_VERSION -TOOL_INFO_BUILD_VERSION := $(LLVM_SUBMIT_VERSION).$(LLVM_SUBMIT_SUBVERSION) -else -TOOL_INFO_BUILD_VERSION := -endif -endif - -# Translate make variable to define when building a "production" clang. -ifdef CLANG_IS_PRODUCTION -CPP.Defines += -DCLANG_IS_PRODUCTION -endif -ifdef CLANGXX_IS_PRODUCTION -CPP.Defines += -DCLANGXX_IS_PRODUCTION -endif diff --git a/contrib/llvm/tools/clang/tools/libclang/CIndex.cpp b/contrib/llvm/tools/clang/tools/libclang/CIndex.cpp deleted file mode 100644 index 5117f2c..0000000 --- a/contrib/llvm/tools/clang/tools/libclang/CIndex.cpp +++ /dev/null @@ -1,3795 +0,0 @@ -//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the main API hooks in the Clang-C Source Indexing -// library. -// -//===----------------------------------------------------------------------===// - -#include "CIndexer.h" -#include "CXCursor.h" -#include "CXType.h" -#include "CXSourceLocation.h" -#include "CIndexDiagnostic.h" - -#include "clang/Basic/Version.h" - -#include "clang/AST/DeclVisitor.h" -#include "clang/AST/StmtVisitor.h" -#include "clang/AST/TypeLocVisitor.h" -#include "clang/Basic/Diagnostic.h" -#include "clang/Frontend/ASTUnit.h" -#include "clang/Frontend/CompilerInstance.h" -#include "clang/Frontend/FrontendDiagnostic.h" -#include "clang/Lex/Lexer.h" -#include "clang/Lex/PreprocessingRecord.h" -#include "clang/Lex/Preprocessor.h" -#include "llvm/Support/CrashRecoveryContext.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/Timer.h" -#include "llvm/System/Program.h" -#include "llvm/System/Signals.h" - -// Needed to define L_TMPNAM on some systems. -#include <cstdio> - -using namespace clang; -using namespace clang::cxcursor; -using namespace clang::cxstring; - -//===----------------------------------------------------------------------===// -// Crash Reporting. -//===----------------------------------------------------------------------===// - -#ifdef USE_CRASHTRACER -#include "clang/Analysis/Support/SaveAndRestore.h" -// Integrate with crash reporter. -static const char *__crashreporter_info__ = 0; -asm(".desc ___crashreporter_info__, 0x10"); -#define NUM_CRASH_STRINGS 32 -static unsigned crashtracer_counter = 0; -static unsigned crashtracer_counter_id[NUM_CRASH_STRINGS] = { 0 }; -static const char *crashtracer_strings[NUM_CRASH_STRINGS] = { 0 }; -static const char *agg_crashtracer_strings[NUM_CRASH_STRINGS] = { 0 }; - -static unsigned SetCrashTracerInfo(const char *str, - llvm::SmallString<1024> &AggStr) { - - unsigned slot = 0; - while (crashtracer_strings[slot]) { - if (++slot == NUM_CRASH_STRINGS) - slot = 0; - } - crashtracer_strings[slot] = str; - crashtracer_counter_id[slot] = ++crashtracer_counter; - - // We need to create an aggregate string because multiple threads - // may be in this method at one time. The crash reporter string - // will attempt to overapproximate the set of in-flight invocations - // of this function. Race conditions can still cause this goal - // to not be achieved. - { - llvm::raw_svector_ostream Out(AggStr); - for (unsigned i = 0; i < NUM_CRASH_STRINGS; ++i) - if (crashtracer_strings[i]) Out << crashtracer_strings[i] << '\n'; - } - __crashreporter_info__ = agg_crashtracer_strings[slot] = AggStr.c_str(); - return slot; -} - -static void ResetCrashTracerInfo(unsigned slot) { - unsigned max_slot = 0; - unsigned max_value = 0; - - crashtracer_strings[slot] = agg_crashtracer_strings[slot] = 0; - - for (unsigned i = 0 ; i < NUM_CRASH_STRINGS; ++i) - if (agg_crashtracer_strings[i] && - crashtracer_counter_id[i] > max_value) { - max_slot = i; - max_value = crashtracer_counter_id[i]; - } - - __crashreporter_info__ = agg_crashtracer_strings[max_slot]; -} - -namespace { -class ArgsCrashTracerInfo { - llvm::SmallString<1024> CrashString; - llvm::SmallString<1024> AggregateString; - unsigned crashtracerSlot; -public: - ArgsCrashTracerInfo(llvm::SmallVectorImpl<const char*> &Args) - : crashtracerSlot(0) - { - { - llvm::raw_svector_ostream Out(CrashString); - Out << "ClangCIndex [" << getClangFullVersion() << "]" - << "[createTranslationUnitFromSourceFile]: clang"; - for (llvm::SmallVectorImpl<const char*>::iterator I=Args.begin(), - E=Args.end(); I!=E; ++I) - Out << ' ' << *I; - } - crashtracerSlot = SetCrashTracerInfo(CrashString.c_str(), - AggregateString); - } - - ~ArgsCrashTracerInfo() { - ResetCrashTracerInfo(crashtracerSlot); - } -}; -} -#endif - -/// \brief The result of comparing two source ranges. -enum RangeComparisonResult { - /// \brief Either the ranges overlap or one of the ranges is invalid. - RangeOverlap, - - /// \brief The first range ends before the second range starts. - RangeBefore, - - /// \brief The first range starts after the second range ends. - RangeAfter -}; - -/// \brief Compare two source ranges to determine their relative position in -/// the translation unit. -static RangeComparisonResult RangeCompare(SourceManager &SM, - SourceRange R1, - SourceRange R2) { - assert(R1.isValid() && "First range is invalid?"); - assert(R2.isValid() && "Second range is invalid?"); - if (R1.getEnd() != R2.getBegin() && - SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin())) - return RangeBefore; - if (R2.getEnd() != R1.getBegin() && - SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin())) - return RangeAfter; - return RangeOverlap; -} - -/// \brief Determine if a source location falls within, before, or after a -/// a given source range. -static RangeComparisonResult LocationCompare(SourceManager &SM, - SourceLocation L, SourceRange R) { - assert(R.isValid() && "First range is invalid?"); - assert(L.isValid() && "Second range is invalid?"); - if (L == R.getBegin() || L == R.getEnd()) - return RangeOverlap; - if (SM.isBeforeInTranslationUnit(L, R.getBegin())) - return RangeBefore; - if (SM.isBeforeInTranslationUnit(R.getEnd(), L)) - return RangeAfter; - return RangeOverlap; -} - -/// \brief Translate a Clang source range into a CIndex source range. -/// -/// Clang internally represents ranges where the end location points to the -/// start of the token at the end. However, for external clients it is more -/// useful to have a CXSourceRange be a proper half-open interval. This routine -/// does the appropriate translation. -CXSourceRange cxloc::translateSourceRange(const SourceManager &SM, - const LangOptions &LangOpts, - const CharSourceRange &R) { - // We want the last character in this location, so we will adjust the - // location accordingly. - // FIXME: How do do this with a macro instantiation location? - SourceLocation EndLoc = R.getEnd(); - if (R.isTokenRange() && !EndLoc.isInvalid() && EndLoc.isFileID()) { - unsigned Length = Lexer::MeasureTokenLength(EndLoc, SM, LangOpts); - EndLoc = EndLoc.getFileLocWithOffset(Length); - } - - CXSourceRange Result = { { (void *)&SM, (void *)&LangOpts }, - R.getBegin().getRawEncoding(), - EndLoc.getRawEncoding() }; - return Result; -} - -//===----------------------------------------------------------------------===// -// Cursor visitor. -//===----------------------------------------------------------------------===// - -namespace { - -// Cursor visitor. -class CursorVisitor : public DeclVisitor<CursorVisitor, bool>, - public TypeLocVisitor<CursorVisitor, bool>, - public StmtVisitor<CursorVisitor, bool> -{ - /// \brief The translation unit we are traversing. - ASTUnit *TU; - - /// \brief The parent cursor whose children we are traversing. - CXCursor Parent; - - /// \brief The declaration that serves at the parent of any statement or - /// expression nodes. - Decl *StmtParent; - - /// \brief The visitor function. - CXCursorVisitor Visitor; - - /// \brief The opaque client data, to be passed along to the visitor. - CXClientData ClientData; - - // MaxPCHLevel - the maximum PCH level of declarations that we will pass on - // to the visitor. Declarations with a PCH level greater than this value will - // be suppressed. - unsigned MaxPCHLevel; - - /// \brief When valid, a source range to which the cursor should restrict - /// its search. - SourceRange RegionOfInterest; - - using DeclVisitor<CursorVisitor, bool>::Visit; - using TypeLocVisitor<CursorVisitor, bool>::Visit; - using StmtVisitor<CursorVisitor, bool>::Visit; - - /// \brief Determine whether this particular source range comes before, comes - /// after, or overlaps the region of interest. - /// - /// \param R a half-open source range retrieved from the abstract syntax tree. - RangeComparisonResult CompareRegionOfInterest(SourceRange R); - - class SetParentRAII { - CXCursor &Parent; - Decl *&StmtParent; - CXCursor OldParent; - - public: - SetParentRAII(CXCursor &Parent, Decl *&StmtParent, CXCursor NewParent) - : Parent(Parent), StmtParent(StmtParent), OldParent(Parent) - { - Parent = NewParent; - if (clang_isDeclaration(Parent.kind)) - StmtParent = getCursorDecl(Parent); - } - - ~SetParentRAII() { - Parent = OldParent; - if (clang_isDeclaration(Parent.kind)) - StmtParent = getCursorDecl(Parent); - } - }; - -public: - CursorVisitor(ASTUnit *TU, CXCursorVisitor Visitor, CXClientData ClientData, - unsigned MaxPCHLevel, - SourceRange RegionOfInterest = SourceRange()) - : TU(TU), Visitor(Visitor), ClientData(ClientData), - MaxPCHLevel(MaxPCHLevel), RegionOfInterest(RegionOfInterest) - { - Parent.kind = CXCursor_NoDeclFound; - Parent.data[0] = 0; - Parent.data[1] = 0; - Parent.data[2] = 0; - StmtParent = 0; - } - - bool Visit(CXCursor Cursor, bool CheckedRegionOfInterest = false); - - std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator> - getPreprocessedEntities(); - - bool VisitChildren(CXCursor Parent); - - // Declaration visitors - bool VisitAttributes(Decl *D); - bool VisitBlockDecl(BlockDecl *B); - bool VisitCXXRecordDecl(CXXRecordDecl *D); - bool VisitDeclContext(DeclContext *DC); - bool VisitTranslationUnitDecl(TranslationUnitDecl *D); - bool VisitTypedefDecl(TypedefDecl *D); - bool VisitTagDecl(TagDecl *D); - bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *D); - bool VisitClassTemplatePartialSpecializationDecl( - ClassTemplatePartialSpecializationDecl *D); - bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D); - bool VisitEnumConstantDecl(EnumConstantDecl *D); - bool VisitDeclaratorDecl(DeclaratorDecl *DD); - bool VisitFunctionDecl(FunctionDecl *ND); - bool VisitFieldDecl(FieldDecl *D); - bool VisitVarDecl(VarDecl *); - bool VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D); - bool VisitFunctionTemplateDecl(FunctionTemplateDecl *D); - bool VisitClassTemplateDecl(ClassTemplateDecl *D); - bool VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D); - bool VisitObjCMethodDecl(ObjCMethodDecl *ND); - bool VisitObjCContainerDecl(ObjCContainerDecl *D); - bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND); - bool VisitObjCProtocolDecl(ObjCProtocolDecl *PID); - bool VisitObjCPropertyDecl(ObjCPropertyDecl *PD); - bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D); - bool VisitObjCImplDecl(ObjCImplDecl *D); - bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D); - bool VisitObjCImplementationDecl(ObjCImplementationDecl *D); - // FIXME: ObjCPropertyDecl requires TypeSourceInfo, getter/setter locations, - // etc. - // FIXME: ObjCCompatibleAliasDecl requires aliased-class locations. - bool VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D); - bool VisitObjCClassDecl(ObjCClassDecl *D); - bool VisitLinkageSpecDecl(LinkageSpecDecl *D); - bool VisitNamespaceDecl(NamespaceDecl *D); - bool VisitNamespaceAliasDecl(NamespaceAliasDecl *D); - bool VisitUsingDirectiveDecl(UsingDirectiveDecl *D); - bool VisitUsingDecl(UsingDecl *D); - bool VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D); - bool VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D); - - // Name visitor - bool VisitDeclarationNameInfo(DeclarationNameInfo Name); - bool VisitNestedNameSpecifier(NestedNameSpecifier *NNS, SourceRange Range); - - // Template visitors - bool VisitTemplateParameters(const TemplateParameterList *Params); - bool VisitTemplateName(TemplateName Name, SourceLocation Loc); - bool VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL); - - // Type visitors - bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL); - bool VisitBuiltinTypeLoc(BuiltinTypeLoc TL); - bool VisitTypedefTypeLoc(TypedefTypeLoc TL); - bool VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL); - bool VisitTagTypeLoc(TagTypeLoc TL); - bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL); - bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL); - bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL); - bool VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL); - bool VisitPointerTypeLoc(PointerTypeLoc TL); - bool VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL); - bool VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL); - bool VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL); - bool VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL); - bool VisitFunctionTypeLoc(FunctionTypeLoc TL, bool SkipResultType = false); - bool VisitArrayTypeLoc(ArrayTypeLoc TL); - bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL); - // FIXME: Implement visitors here when the unimplemented TypeLocs get - // implemented - bool VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL); - bool VisitTypeOfTypeLoc(TypeOfTypeLoc TL); - - // Statement visitors - bool VisitStmt(Stmt *S); - bool VisitDeclStmt(DeclStmt *S); - // FIXME: LabelStmt label? - bool VisitIfStmt(IfStmt *S); - bool VisitSwitchStmt(SwitchStmt *S); - bool VisitCaseStmt(CaseStmt *S); - bool VisitWhileStmt(WhileStmt *S); - bool VisitForStmt(ForStmt *S); -// bool VisitSwitchCase(SwitchCase *S); - - // Expression visitors - bool VisitDeclRefExpr(DeclRefExpr *E); - bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E); - bool VisitBlockExpr(BlockExpr *B); - bool VisitCompoundLiteralExpr(CompoundLiteralExpr *E); - bool VisitExplicitCastExpr(ExplicitCastExpr *E); - bool VisitObjCMessageExpr(ObjCMessageExpr *E); - bool VisitObjCEncodeExpr(ObjCEncodeExpr *E); - bool VisitOffsetOfExpr(OffsetOfExpr *E); - bool VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E); - bool VisitMemberExpr(MemberExpr *E); - // FIXME: AddrLabelExpr (once we have cursors for labels) - bool VisitTypesCompatibleExpr(TypesCompatibleExpr *E); - bool VisitVAArgExpr(VAArgExpr *E); - // FIXME: InitListExpr (for the designators) - // FIXME: DesignatedInitExpr - bool VisitCXXTypeidExpr(CXXTypeidExpr *E); - bool VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { return false; } - // FIXME: CXXTemporaryObjectExpr has poor source-location information. - // FIXME: CXXScalarValueInitExpr has poor source-location information. - // FIXME: CXXNewExpr has poor source-location information - bool VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E); - // FIXME: UnaryTypeTraitExpr has poor source-location information. - bool VisitOverloadExpr(OverloadExpr *E); - bool VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E); - // FIXME: CXXUnresolvedConstructExpr has poor source-location information. - bool VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E); - bool VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E); -}; - -} // end anonymous namespace - -static SourceRange getRawCursorExtent(CXCursor C); - -RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) { - return RangeCompare(TU->getSourceManager(), R, RegionOfInterest); -} - -/// \brief Visit the given cursor and, if requested by the visitor, -/// its children. -/// -/// \param Cursor the cursor to visit. -/// -/// \param CheckRegionOfInterest if true, then the caller already checked that -/// this cursor is within the region of interest. -/// -/// \returns true if the visitation should be aborted, false if it -/// should continue. -bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) { - if (clang_isInvalid(Cursor.kind)) - return false; - - if (clang_isDeclaration(Cursor.kind)) { - Decl *D = getCursorDecl(Cursor); - assert(D && "Invalid declaration cursor"); - if (D->getPCHLevel() > MaxPCHLevel) - return false; - - if (D->isImplicit()) - return false; - } - - // If we have a range of interest, and this cursor doesn't intersect with it, - // we're done. - if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) { - SourceRange Range = getRawCursorExtent(Cursor); - if (Range.isInvalid() || CompareRegionOfInterest(Range)) - return false; - } - - switch (Visitor(Cursor, Parent, ClientData)) { - case CXChildVisit_Break: - return true; - - case CXChildVisit_Continue: - return false; - - case CXChildVisit_Recurse: - return VisitChildren(Cursor); - } - - return false; -} - -std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator> -CursorVisitor::getPreprocessedEntities() { - PreprocessingRecord &PPRec - = *TU->getPreprocessor().getPreprocessingRecord(); - - bool OnlyLocalDecls - = !TU->isMainFileAST() && TU->getOnlyLocalDecls(); - - // There is no region of interest; we have to walk everything. - if (RegionOfInterest.isInvalid()) - return std::make_pair(PPRec.begin(OnlyLocalDecls), - PPRec.end(OnlyLocalDecls)); - - // Find the file in which the region of interest lands. - SourceManager &SM = TU->getSourceManager(); - std::pair<FileID, unsigned> Begin - = SM.getDecomposedInstantiationLoc(RegionOfInterest.getBegin()); - std::pair<FileID, unsigned> End - = SM.getDecomposedInstantiationLoc(RegionOfInterest.getEnd()); - - // The region of interest spans files; we have to walk everything. - if (Begin.first != End.first) - return std::make_pair(PPRec.begin(OnlyLocalDecls), - PPRec.end(OnlyLocalDecls)); - - ASTUnit::PreprocessedEntitiesByFileMap &ByFileMap - = TU->getPreprocessedEntitiesByFile(); - if (ByFileMap.empty()) { - // Build the mapping from files to sets of preprocessed entities. - for (PreprocessingRecord::iterator E = PPRec.begin(OnlyLocalDecls), - EEnd = PPRec.end(OnlyLocalDecls); - E != EEnd; ++E) { - std::pair<FileID, unsigned> P - = SM.getDecomposedInstantiationLoc((*E)->getSourceRange().getBegin()); - ByFileMap[P.first].push_back(*E); - } - } - - return std::make_pair(ByFileMap[Begin.first].begin(), - ByFileMap[Begin.first].end()); -} - -/// \brief Visit the children of the given cursor. -/// -/// \returns true if the visitation should be aborted, false if it -/// should continue. -bool CursorVisitor::VisitChildren(CXCursor Cursor) { - if (clang_isReference(Cursor.kind)) { - // By definition, references have no children. - return false; - } - - // Set the Parent field to Cursor, then back to its old value once we're - // done. - SetParentRAII SetParent(Parent, StmtParent, Cursor); - - if (clang_isDeclaration(Cursor.kind)) { - Decl *D = getCursorDecl(Cursor); - assert(D && "Invalid declaration cursor"); - return VisitAttributes(D) || Visit(D); - } - - if (clang_isStatement(Cursor.kind)) - return Visit(getCursorStmt(Cursor)); - if (clang_isExpression(Cursor.kind)) - return Visit(getCursorExpr(Cursor)); - - if (clang_isTranslationUnit(Cursor.kind)) { - ASTUnit *CXXUnit = getCursorASTUnit(Cursor); - if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() && - RegionOfInterest.isInvalid()) { - for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(), - TLEnd = CXXUnit->top_level_end(); - TL != TLEnd; ++TL) { - if (Visit(MakeCXCursor(*TL, CXXUnit), true)) - return true; - } - } else if (VisitDeclContext( - CXXUnit->getASTContext().getTranslationUnitDecl())) - return true; - - // Walk the preprocessing record. - if (CXXUnit->getPreprocessor().getPreprocessingRecord()) { - // FIXME: Once we have the ability to deserialize a preprocessing record, - // do so. - PreprocessingRecord::iterator E, EEnd; - for (llvm::tie(E, EEnd) = getPreprocessedEntities(); E != EEnd; ++E) { - if (MacroInstantiation *MI = dyn_cast<MacroInstantiation>(*E)) { - if (Visit(MakeMacroInstantiationCursor(MI, CXXUnit))) - return true; - - continue; - } - - if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) { - if (Visit(MakeMacroDefinitionCursor(MD, CXXUnit))) - return true; - - continue; - } - } - } - return false; - } - - // Nothing to visit at the moment. - return false; -} - -bool CursorVisitor::VisitBlockDecl(BlockDecl *B) { - if (Visit(B->getSignatureAsWritten()->getTypeLoc())) - return true; - - if (Stmt *Body = B->getBody()) - return Visit(MakeCXCursor(Body, StmtParent, TU)); - - return false; -} - -bool CursorVisitor::VisitDeclContext(DeclContext *DC) { - for (DeclContext::decl_iterator - I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) { - - Decl *D = *I; - if (D->getLexicalDeclContext() != DC) - continue; - - CXCursor Cursor = MakeCXCursor(D, TU); - - if (RegionOfInterest.isValid()) { - SourceRange Range = getRawCursorExtent(Cursor); - if (Range.isInvalid()) - continue; - - switch (CompareRegionOfInterest(Range)) { - case RangeBefore: - // This declaration comes before the region of interest; skip it. - continue; - - case RangeAfter: - // This declaration comes after the region of interest; we're done. - return false; - - case RangeOverlap: - // This declaration overlaps the region of interest; visit it. - break; - } - } - - if (Visit(Cursor, true)) - return true; - } - - return false; -} - -bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) { - llvm_unreachable("Translation units are visited directly by Visit()"); - return false; -} - -bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) { - if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo()) - return Visit(TSInfo->getTypeLoc()); - - return false; -} - -bool CursorVisitor::VisitTagDecl(TagDecl *D) { - return VisitDeclContext(D); -} - -bool CursorVisitor::VisitClassTemplateSpecializationDecl( - ClassTemplateSpecializationDecl *D) { - bool ShouldVisitBody = false; - switch (D->getSpecializationKind()) { - case TSK_Undeclared: - case TSK_ImplicitInstantiation: - // Nothing to visit - return false; - - case TSK_ExplicitInstantiationDeclaration: - case TSK_ExplicitInstantiationDefinition: - break; - - case TSK_ExplicitSpecialization: - ShouldVisitBody = true; - break; - } - - // Visit the template arguments used in the specialization. - if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) { - TypeLoc TL = SpecType->getTypeLoc(); - if (TemplateSpecializationTypeLoc *TSTLoc - = dyn_cast<TemplateSpecializationTypeLoc>(&TL)) { - for (unsigned I = 0, N = TSTLoc->getNumArgs(); I != N; ++I) - if (VisitTemplateArgumentLoc(TSTLoc->getArgLoc(I))) - return true; - } - } - - if (ShouldVisitBody && VisitCXXRecordDecl(D)) - return true; - - return false; -} - -bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl( - ClassTemplatePartialSpecializationDecl *D) { - // FIXME: Visit the "outer" template parameter lists on the TagDecl - // before visiting these template parameters. - if (VisitTemplateParameters(D->getTemplateParameters())) - return true; - - // Visit the partial specialization arguments. - const TemplateArgumentLoc *TemplateArgs = D->getTemplateArgsAsWritten(); - for (unsigned I = 0, N = D->getNumTemplateArgsAsWritten(); I != N; ++I) - if (VisitTemplateArgumentLoc(TemplateArgs[I])) - return true; - - return VisitCXXRecordDecl(D); -} - -bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { - // Visit the default argument. - if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) - if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo()) - if (Visit(DefArg->getTypeLoc())) - return true; - - return false; -} - -bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) { - if (Expr *Init = D->getInitExpr()) - return Visit(MakeCXCursor(Init, StmtParent, TU)); - return false; -} - -bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) { - if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo()) - if (Visit(TSInfo->getTypeLoc())) - return true; - - return false; -} - -bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) { - if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) { - // Visit the function declaration's syntactic components in the order - // written. This requires a bit of work. - TypeLoc TL = TSInfo->getTypeLoc(); - FunctionTypeLoc *FTL = dyn_cast<FunctionTypeLoc>(&TL); - - // If we have a function declared directly (without the use of a typedef), - // visit just the return type. Otherwise, just visit the function's type - // now. - if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL->getResultLoc())) || - (!FTL && Visit(TL))) - return true; - - // Visit the nested-name-specifier, if present. - if (NestedNameSpecifier *Qualifier = ND->getQualifier()) - if (VisitNestedNameSpecifier(Qualifier, ND->getQualifierRange())) - return true; - - // Visit the declaration name. - if (VisitDeclarationNameInfo(ND->getNameInfo())) - return true; - - // FIXME: Visit explicitly-specified template arguments! - - // Visit the function parameters, if we have a function type. - if (FTL && VisitFunctionTypeLoc(*FTL, true)) - return true; - - // FIXME: Attributes? - } - - if (ND->isThisDeclarationADefinition() && - Visit(MakeCXCursor(ND->getBody(), StmtParent, TU))) - return true; - - return false; -} - -bool CursorVisitor::VisitFieldDecl(FieldDecl *D) { - if (VisitDeclaratorDecl(D)) - return true; - - if (Expr *BitWidth = D->getBitWidth()) - return Visit(MakeCXCursor(BitWidth, StmtParent, TU)); - - return false; -} - -bool CursorVisitor::VisitVarDecl(VarDecl *D) { - if (VisitDeclaratorDecl(D)) - return true; - - if (Expr *Init = D->getInit()) - return Visit(MakeCXCursor(Init, StmtParent, TU)); - - return false; -} - -bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) { - if (VisitDeclaratorDecl(D)) - return true; - - if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) - if (Expr *DefArg = D->getDefaultArgument()) - return Visit(MakeCXCursor(DefArg, StmtParent, TU)); - - return false; -} - -bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { - // FIXME: Visit the "outer" template parameter lists on the FunctionDecl - // before visiting these template parameters. - if (VisitTemplateParameters(D->getTemplateParameters())) - return true; - - return VisitFunctionDecl(D->getTemplatedDecl()); -} - -bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) { - // FIXME: Visit the "outer" template parameter lists on the TagDecl - // before visiting these template parameters. - if (VisitTemplateParameters(D->getTemplateParameters())) - return true; - - return VisitCXXRecordDecl(D->getTemplatedDecl()); -} - -bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) { - if (VisitTemplateParameters(D->getTemplateParameters())) - return true; - - if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() && - VisitTemplateArgumentLoc(D->getDefaultArgument())) - return true; - - return false; -} - -bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) { - if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo()) - if (Visit(TSInfo->getTypeLoc())) - return true; - - for (ObjCMethodDecl::param_iterator P = ND->param_begin(), - PEnd = ND->param_end(); - P != PEnd; ++P) { - if (Visit(MakeCXCursor(*P, TU))) - return true; - } - - if (ND->isThisDeclarationADefinition() && - Visit(MakeCXCursor(ND->getBody(), StmtParent, TU))) - return true; - - return false; -} - -bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) { - return VisitDeclContext(D); -} - -bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) { - if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(), - TU))) - return true; - - ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin(); - for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(), - E = ND->protocol_end(); I != E; ++I, ++PL) - if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU))) - return true; - - return VisitObjCContainerDecl(ND); -} - -bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) { - ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin(); - for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(), - E = PID->protocol_end(); I != E; ++I, ++PL) - if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU))) - return true; - - return VisitObjCContainerDecl(PID); -} - -bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) { - if (Visit(PD->getTypeSourceInfo()->getTypeLoc())) - return true; - - // FIXME: This implements a workaround with @property declarations also being - // installed in the DeclContext for the @interface. Eventually this code - // should be removed. - ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext()); - if (!CDecl || !CDecl->IsClassExtension()) - return false; - - ObjCInterfaceDecl *ID = CDecl->getClassInterface(); - if (!ID) - return false; - - IdentifierInfo *PropertyId = PD->getIdentifier(); - ObjCPropertyDecl *prevDecl = - ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId); - - if (!prevDecl) - return false; - - // Visit synthesized methods since they will be skipped when visiting - // the @interface. - if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl()) - if (MD->isSynthesized()) - if (Visit(MakeCXCursor(MD, TU))) - return true; - - if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl()) - if (MD->isSynthesized()) - if (Visit(MakeCXCursor(MD, TU))) - return true; - - return false; -} - -bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) { - // Issue callbacks for super class. - if (D->getSuperClass() && - Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(), - D->getSuperClassLoc(), - TU))) - return true; - - ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin(); - for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(), - E = D->protocol_end(); I != E; ++I, ++PL) - if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU))) - return true; - - return VisitObjCContainerDecl(D); -} - -bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) { - return VisitObjCContainerDecl(D); -} - -bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) { - // 'ID' could be null when dealing with invalid code. - if (ObjCInterfaceDecl *ID = D->getClassInterface()) - if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU))) - return true; - - return VisitObjCImplDecl(D); -} - -bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) { -#if 0 - // Issue callbacks for super class. - // FIXME: No source location information! - if (D->getSuperClass() && - Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(), - D->getSuperClassLoc(), - TU))) - return true; -#endif - - return VisitObjCImplDecl(D); -} - -bool CursorVisitor::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) { - ObjCForwardProtocolDecl::protocol_loc_iterator PL = D->protocol_loc_begin(); - for (ObjCForwardProtocolDecl::protocol_iterator I = D->protocol_begin(), - E = D->protocol_end(); - I != E; ++I, ++PL) - if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU))) - return true; - - return false; -} - -bool CursorVisitor::VisitObjCClassDecl(ObjCClassDecl *D) { - for (ObjCClassDecl::iterator C = D->begin(), CEnd = D->end(); C != CEnd; ++C) - if (Visit(MakeCursorObjCClassRef(C->getInterface(), C->getLocation(), TU))) - return true; - - return false; -} - -bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) { - return VisitDeclContext(D); -} - -bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) { - // Visit nested-name-specifier. - if (NestedNameSpecifier *Qualifier = D->getQualifier()) - if (VisitNestedNameSpecifier(Qualifier, D->getQualifierRange())) - return true; - - return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(), - D->getTargetNameLoc(), TU)); -} - -bool CursorVisitor::VisitUsingDecl(UsingDecl *D) { - // Visit nested-name-specifier. - if (NestedNameSpecifier *Qualifier = D->getTargetNestedNameDecl()) - if (VisitNestedNameSpecifier(Qualifier, D->getNestedNameRange())) - return true; - - // FIXME: Provide a multi-reference of some kind for all of the declarations - // that the using declaration refers to. We don't have this kind of cursor - // yet. - - return VisitDeclarationNameInfo(D->getNameInfo()); -} - -bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) { - // Visit nested-name-specifier. - if (NestedNameSpecifier *Qualifier = D->getQualifier()) - if (VisitNestedNameSpecifier(Qualifier, D->getQualifierRange())) - return true; - - return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(), - D->getIdentLocation(), TU)); -} - -bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) { - // Visit nested-name-specifier. - if (NestedNameSpecifier *Qualifier = D->getTargetNestedNameSpecifier()) - if (VisitNestedNameSpecifier(Qualifier, D->getTargetNestedNameRange())) - return true; - - return VisitDeclarationNameInfo(D->getNameInfo()); -} - -bool CursorVisitor::VisitUnresolvedUsingTypenameDecl( - UnresolvedUsingTypenameDecl *D) { - // Visit nested-name-specifier. - if (NestedNameSpecifier *Qualifier = D->getTargetNestedNameSpecifier()) - if (VisitNestedNameSpecifier(Qualifier, D->getTargetNestedNameRange())) - return true; - - return false; -} - -bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) { - switch (Name.getName().getNameKind()) { - case clang::DeclarationName::Identifier: - case clang::DeclarationName::CXXLiteralOperatorName: - case clang::DeclarationName::CXXOperatorName: - case clang::DeclarationName::CXXUsingDirective: - return false; - - case clang::DeclarationName::CXXConstructorName: - case clang::DeclarationName::CXXDestructorName: - case clang::DeclarationName::CXXConversionFunctionName: - if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo()) - return Visit(TSInfo->getTypeLoc()); - return false; - - case clang::DeclarationName::ObjCZeroArgSelector: - case clang::DeclarationName::ObjCOneArgSelector: - case clang::DeclarationName::ObjCMultiArgSelector: - // FIXME: Per-identifier location info? - return false; - } - - return false; -} - -bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS, - SourceRange Range) { - // FIXME: This whole routine is a hack to work around the lack of proper - // source information in nested-name-specifiers (PR5791). Since we do have - // a beginning source location, we can visit the first component of the - // nested-name-specifier, if it's a single-token component. - if (!NNS) - return false; - - // Get the first component in the nested-name-specifier. - while (NestedNameSpecifier *Prefix = NNS->getPrefix()) - NNS = Prefix; - - switch (NNS->getKind()) { - case NestedNameSpecifier::Namespace: - // FIXME: The token at this source location might actually have been a - // namespace alias, but we don't model that. Lame! - return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(), - TU)); - - case NestedNameSpecifier::TypeSpec: { - // If the type has a form where we know that the beginning of the source - // range matches up with a reference cursor. Visit the appropriate reference - // cursor. - Type *T = NNS->getAsType(); - if (const TypedefType *Typedef = dyn_cast<TypedefType>(T)) - return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU)); - if (const TagType *Tag = dyn_cast<TagType>(T)) - return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU)); - if (const TemplateSpecializationType *TST - = dyn_cast<TemplateSpecializationType>(T)) - return VisitTemplateName(TST->getTemplateName(), Range.getBegin()); - break; - } - - case NestedNameSpecifier::TypeSpecWithTemplate: - case NestedNameSpecifier::Global: - case NestedNameSpecifier::Identifier: - break; - } - - return false; -} - -bool CursorVisitor::VisitTemplateParameters( - const TemplateParameterList *Params) { - if (!Params) - return false; - - for (TemplateParameterList::const_iterator P = Params->begin(), - PEnd = Params->end(); - P != PEnd; ++P) { - if (Visit(MakeCXCursor(*P, TU))) - return true; - } - - return false; -} - -bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) { - switch (Name.getKind()) { - case TemplateName::Template: - return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU)); - - case TemplateName::OverloadedTemplate: - // FIXME: We need a way to return multiple lookup results in a single - // cursor. - return false; - - case TemplateName::DependentTemplate: - // FIXME: Visit nested-name-specifier. - return false; - - case TemplateName::QualifiedTemplate: - // FIXME: Visit nested-name-specifier. - return Visit(MakeCursorTemplateRef( - Name.getAsQualifiedTemplateName()->getDecl(), - Loc, TU)); - } - - return false; -} - -bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) { - switch (TAL.getArgument().getKind()) { - case TemplateArgument::Null: - case TemplateArgument::Integral: - return false; - - case TemplateArgument::Pack: - // FIXME: Implement when variadic templates come along. - return false; - - case TemplateArgument::Type: - if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo()) - return Visit(TSInfo->getTypeLoc()); - return false; - - case TemplateArgument::Declaration: - if (Expr *E = TAL.getSourceDeclExpression()) - return Visit(MakeCXCursor(E, StmtParent, TU)); - return false; - - case TemplateArgument::Expression: - if (Expr *E = TAL.getSourceExpression()) - return Visit(MakeCXCursor(E, StmtParent, TU)); - return false; - - case TemplateArgument::Template: - return VisitTemplateName(TAL.getArgument().getAsTemplate(), - TAL.getTemplateNameLoc()); - } - - return false; -} - -bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) { - return VisitDeclContext(D); -} - -bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { - return Visit(TL.getUnqualifiedLoc()); -} - -bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) { - ASTContext &Context = TU->getASTContext(); - - // Some builtin types (such as Objective-C's "id", "sel", and - // "Class") have associated declarations. Create cursors for those. - QualType VisitType; - switch (TL.getType()->getAs<BuiltinType>()->getKind()) { - case BuiltinType::Void: - case BuiltinType::Bool: - case BuiltinType::Char_U: - case BuiltinType::UChar: - case BuiltinType::Char16: - case BuiltinType::Char32: - case BuiltinType::UShort: - case BuiltinType::UInt: - case BuiltinType::ULong: - case BuiltinType::ULongLong: - case BuiltinType::UInt128: - case BuiltinType::Char_S: - case BuiltinType::SChar: - case BuiltinType::WChar: - case BuiltinType::Short: - case BuiltinType::Int: - case BuiltinType::Long: - case BuiltinType::LongLong: - case BuiltinType::Int128: - case BuiltinType::Float: - case BuiltinType::Double: - case BuiltinType::LongDouble: - case BuiltinType::NullPtr: - case BuiltinType::Overload: - case BuiltinType::Dependent: - break; - - case BuiltinType::UndeducedAuto: // FIXME: Deserves a cursor? - break; - - case BuiltinType::ObjCId: - VisitType = Context.getObjCIdType(); - break; - - case BuiltinType::ObjCClass: - VisitType = Context.getObjCClassType(); - break; - - case BuiltinType::ObjCSel: - VisitType = Context.getObjCSelType(); - break; - } - - if (!VisitType.isNull()) { - if (const TypedefType *Typedef = VisitType->getAs<TypedefType>()) - return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(), - TU)); - } - - return false; -} - -bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) { - return Visit(MakeCursorTypeRef(TL.getTypedefDecl(), TL.getNameLoc(), TU)); -} - -bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) { - return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU)); -} - -bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) { - return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU)); -} - -bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) { - // FIXME: We can't visit the template template parameter, but there's - // no context information with which we can match up the depth/index in the - // type to the appropriate - return false; -} - -bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { - if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU))) - return true; - - return false; -} - -bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) { - if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc())) - return true; - - for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) { - if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I), - TU))) - return true; - } - - return false; -} - -bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) { - return Visit(TL.getPointeeLoc()); -} - -bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) { - return Visit(TL.getPointeeLoc()); -} - -bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) { - return Visit(TL.getPointeeLoc()); -} - -bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) { - return Visit(TL.getPointeeLoc()); -} - -bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) { - return Visit(TL.getPointeeLoc()); -} - -bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) { - return Visit(TL.getPointeeLoc()); -} - -bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL, - bool SkipResultType) { - if (!SkipResultType && Visit(TL.getResultLoc())) - return true; - - for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I) - if (Decl *D = TL.getArg(I)) - if (Visit(MakeCXCursor(D, TU))) - return true; - - return false; -} - -bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) { - if (Visit(TL.getElementLoc())) - return true; - - if (Expr *Size = TL.getSizeExpr()) - return Visit(MakeCXCursor(Size, StmtParent, TU)); - - return false; -} - -bool CursorVisitor::VisitTemplateSpecializationTypeLoc( - TemplateSpecializationTypeLoc TL) { - // Visit the template name. - if (VisitTemplateName(TL.getTypePtr()->getTemplateName(), - TL.getTemplateNameLoc())) - return true; - - // Visit the template arguments. - for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I) - if (VisitTemplateArgumentLoc(TL.getArgLoc(I))) - return true; - - return false; -} - -bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) { - return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU)); -} - -bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) { - if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo()) - return Visit(TSInfo->getTypeLoc()); - - return false; -} - -bool CursorVisitor::VisitStmt(Stmt *S) { - for (Stmt::child_iterator Child = S->child_begin(), ChildEnd = S->child_end(); - Child != ChildEnd; ++Child) { - if (Stmt *C = *Child) - if (Visit(MakeCXCursor(C, StmtParent, TU))) - return true; - } - - return false; -} - -bool CursorVisitor::VisitCaseStmt(CaseStmt *S) { - // Specially handle CaseStmts because they can be nested, e.g.: - // - // case 1: - // case 2: - // - // In this case the second CaseStmt is the child of the first. Walking - // these recursively can blow out the stack. - CXCursor Cursor = MakeCXCursor(S, StmtParent, TU); - while (true) { - // Set the Parent field to Cursor, then back to its old value once we're - // done. - SetParentRAII SetParent(Parent, StmtParent, Cursor); - - if (Stmt *LHS = S->getLHS()) - if (Visit(MakeCXCursor(LHS, StmtParent, TU))) - return true; - if (Stmt *RHS = S->getRHS()) - if (Visit(MakeCXCursor(RHS, StmtParent, TU))) - return true; - if (Stmt *SubStmt = S->getSubStmt()) { - if (!isa<CaseStmt>(SubStmt)) - return Visit(MakeCXCursor(SubStmt, StmtParent, TU)); - - // Specially handle 'CaseStmt' so that we don't blow out the stack. - CaseStmt *CS = cast<CaseStmt>(SubStmt); - Cursor = MakeCXCursor(CS, StmtParent, TU); - if (RegionOfInterest.isValid()) { - SourceRange Range = CS->getSourceRange(); - if (Range.isInvalid() || CompareRegionOfInterest(Range)) - return false; - } - - switch (Visitor(Cursor, Parent, ClientData)) { - case CXChildVisit_Break: return true; - case CXChildVisit_Continue: return false; - case CXChildVisit_Recurse: - // Perform tail-recursion manually. - S = CS; - continue; - } - } - return false; - } -} - -bool CursorVisitor::VisitDeclStmt(DeclStmt *S) { - for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end(); - D != DEnd; ++D) { - if (*D && Visit(MakeCXCursor(*D, TU))) - return true; - } - - return false; -} - -bool CursorVisitor::VisitIfStmt(IfStmt *S) { - if (VarDecl *Var = S->getConditionVariable()) { - if (Visit(MakeCXCursor(Var, TU))) - return true; - } - - if (S->getCond() && Visit(MakeCXCursor(S->getCond(), StmtParent, TU))) - return true; - if (S->getThen() && Visit(MakeCXCursor(S->getThen(), StmtParent, TU))) - return true; - if (S->getElse() && Visit(MakeCXCursor(S->getElse(), StmtParent, TU))) - return true; - - return false; -} - -bool CursorVisitor::VisitSwitchStmt(SwitchStmt *S) { - if (VarDecl *Var = S->getConditionVariable()) { - if (Visit(MakeCXCursor(Var, TU))) - return true; - } - - if (S->getCond() && Visit(MakeCXCursor(S->getCond(), StmtParent, TU))) - return true; - if (S->getBody() && Visit(MakeCXCursor(S->getBody(), StmtParent, TU))) - return true; - - return false; -} - -bool CursorVisitor::VisitWhileStmt(WhileStmt *S) { - if (VarDecl *Var = S->getConditionVariable()) { - if (Visit(MakeCXCursor(Var, TU))) - return true; - } - - if (S->getCond() && Visit(MakeCXCursor(S->getCond(), StmtParent, TU))) - return true; - if (S->getBody() && Visit(MakeCXCursor(S->getBody(), StmtParent, TU))) - return true; - - return false; -} - -bool CursorVisitor::VisitForStmt(ForStmt *S) { - if (S->getInit() && Visit(MakeCXCursor(S->getInit(), StmtParent, TU))) - return true; - if (VarDecl *Var = S->getConditionVariable()) { - if (Visit(MakeCXCursor(Var, TU))) - return true; - } - - if (S->getCond() && Visit(MakeCXCursor(S->getCond(), StmtParent, TU))) - return true; - if (S->getInc() && Visit(MakeCXCursor(S->getInc(), StmtParent, TU))) - return true; - if (S->getBody() && Visit(MakeCXCursor(S->getBody(), StmtParent, TU))) - return true; - - return false; -} - -bool CursorVisitor::VisitDeclRefExpr(DeclRefExpr *E) { - // Visit nested-name-specifier, if present. - if (NestedNameSpecifier *Qualifier = E->getQualifier()) - if (VisitNestedNameSpecifier(Qualifier, E->getQualifierRange())) - return true; - - // Visit declaration name. - if (VisitDeclarationNameInfo(E->getNameInfo())) - return true; - - // Visit explicitly-specified template arguments. - if (E->hasExplicitTemplateArgs()) { - ExplicitTemplateArgumentList &Args = E->getExplicitTemplateArgs(); - for (TemplateArgumentLoc *Arg = Args.getTemplateArgs(), - *ArgEnd = Arg + Args.NumTemplateArgs; - Arg != ArgEnd; ++Arg) - if (VisitTemplateArgumentLoc(*Arg)) - return true; - } - - return false; -} - -bool CursorVisitor::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) { - if (Visit(MakeCXCursor(E->getArg(0), StmtParent, TU))) - return true; - - if (Visit(MakeCXCursor(E->getCallee(), StmtParent, TU))) - return true; - - for (unsigned I = 1, N = E->getNumArgs(); I != N; ++I) - if (Visit(MakeCXCursor(E->getArg(I), StmtParent, TU))) - return true; - - return false; -} - -bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) { - if (D->isDefinition()) { - for (CXXRecordDecl::base_class_iterator I = D->bases_begin(), - E = D->bases_end(); I != E; ++I) { - if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU))) - return true; - } - } - - return VisitTagDecl(D); -} - - -bool CursorVisitor::VisitBlockExpr(BlockExpr *B) { - return Visit(B->getBlockDecl()); -} - -bool CursorVisitor::VisitOffsetOfExpr(OffsetOfExpr *E) { - // FIXME: Visit fields as well? - if (Visit(E->getTypeSourceInfo()->getTypeLoc())) - return true; - - return VisitExpr(E); -} - -bool CursorVisitor::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) { - if (E->isArgumentType()) { - if (TypeSourceInfo *TSInfo = E->getArgumentTypeInfo()) - return Visit(TSInfo->getTypeLoc()); - - return false; - } - - return VisitExpr(E); -} - -bool CursorVisitor::VisitMemberExpr(MemberExpr *E) { - // Visit the base expression. - if (Visit(MakeCXCursor(E->getBase(), StmtParent, TU))) - return true; - - // Visit the nested-name-specifier - if (NestedNameSpecifier *Qualifier = E->getQualifier()) - if (VisitNestedNameSpecifier(Qualifier, E->getQualifierRange())) - return true; - - // Visit the declaration name. - if (VisitDeclarationNameInfo(E->getMemberNameInfo())) - return true; - - // Visit the explicitly-specified template arguments, if any. - if (E->hasExplicitTemplateArgs()) { - for (const TemplateArgumentLoc *Arg = E->getTemplateArgs(), - *ArgEnd = Arg + E->getNumTemplateArgs(); - Arg != ArgEnd; - ++Arg) { - if (VisitTemplateArgumentLoc(*Arg)) - return true; - } - } - - return false; -} - -bool CursorVisitor::VisitExplicitCastExpr(ExplicitCastExpr *E) { - if (TypeSourceInfo *TSInfo = E->getTypeInfoAsWritten()) - if (Visit(TSInfo->getTypeLoc())) - return true; - - return VisitCastExpr(E); -} - -bool CursorVisitor::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) { - if (TypeSourceInfo *TSInfo = E->getTypeSourceInfo()) - if (Visit(TSInfo->getTypeLoc())) - return true; - - return VisitExpr(E); -} - -bool CursorVisitor::VisitTypesCompatibleExpr(TypesCompatibleExpr *E) { - return Visit(E->getArgTInfo1()->getTypeLoc()) || - Visit(E->getArgTInfo2()->getTypeLoc()); -} - -bool CursorVisitor::VisitVAArgExpr(VAArgExpr *E) { - if (Visit(E->getWrittenTypeInfo()->getTypeLoc())) - return true; - - return Visit(MakeCXCursor(E->getSubExpr(), StmtParent, TU)); -} - -bool CursorVisitor::VisitCXXTypeidExpr(CXXTypeidExpr *E) { - if (E->isTypeOperand()) { - if (TypeSourceInfo *TSInfo = E->getTypeOperandSourceInfo()) - return Visit(TSInfo->getTypeLoc()); - - return false; - } - - return VisitExpr(E); -} - -bool CursorVisitor::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) { - // Visit base expression. - if (Visit(MakeCXCursor(E->getBase(), StmtParent, TU))) - return true; - - // Visit the nested-name-specifier. - if (NestedNameSpecifier *Qualifier = E->getQualifier()) - if (VisitNestedNameSpecifier(Qualifier, E->getQualifierRange())) - return true; - - // Visit the scope type that looks disturbingly like the nested-name-specifier - // but isn't. - if (TypeSourceInfo *TSInfo = E->getScopeTypeInfo()) - if (Visit(TSInfo->getTypeLoc())) - return true; - - // Visit the name of the type being destroyed. - if (TypeSourceInfo *TSInfo = E->getDestroyedTypeInfo()) - if (Visit(TSInfo->getTypeLoc())) - return true; - - return false; -} - -bool CursorVisitor::VisitOverloadExpr(OverloadExpr *E) { - // Visit the nested-name-specifier. - if (NestedNameSpecifier *Qualifier = E->getQualifier()) - if (VisitNestedNameSpecifier(Qualifier, E->getQualifierRange())) - return true; - - // Visit the declaration name. - if (VisitDeclarationNameInfo(E->getNameInfo())) - return true; - - // Visit the explicitly-specified template arguments. - if (const ExplicitTemplateArgumentList *ArgList - = E->getOptionalExplicitTemplateArgs()) { - for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(), - *ArgEnd = Arg + ArgList->NumTemplateArgs; - Arg != ArgEnd; ++Arg) { - if (VisitTemplateArgumentLoc(*Arg)) - return true; - } - } - - // FIXME: We don't have a way to visit all of the declarations referenced - // here. - return false; -} - -bool CursorVisitor::VisitDependentScopeDeclRefExpr( - DependentScopeDeclRefExpr *E) { - // Visit the nested-name-specifier. - if (NestedNameSpecifier *Qualifier = E->getQualifier()) - if (VisitNestedNameSpecifier(Qualifier, E->getQualifierRange())) - return true; - - // Visit the declaration name. - if (VisitDeclarationNameInfo(E->getNameInfo())) - return true; - - // Visit the explicitly-specified template arguments. - if (const ExplicitTemplateArgumentList *ArgList - = E->getOptionalExplicitTemplateArgs()) { - for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(), - *ArgEnd = Arg + ArgList->NumTemplateArgs; - Arg != ArgEnd; ++Arg) { - if (VisitTemplateArgumentLoc(*Arg)) - return true; - } - } - - return false; -} - -bool CursorVisitor::VisitCXXDependentScopeMemberExpr( - CXXDependentScopeMemberExpr *E) { - // Visit the base expression, if there is one. - if (!E->isImplicitAccess() && - Visit(MakeCXCursor(E->getBase(), StmtParent, TU))) - return true; - - // Visit the nested-name-specifier. - if (NestedNameSpecifier *Qualifier = E->getQualifier()) - if (VisitNestedNameSpecifier(Qualifier, E->getQualifierRange())) - return true; - - // Visit the declaration name. - if (VisitDeclarationNameInfo(E->getMemberNameInfo())) - return true; - - // Visit the explicitly-specified template arguments. - if (const ExplicitTemplateArgumentList *ArgList - = E->getOptionalExplicitTemplateArgs()) { - for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(), - *ArgEnd = Arg + ArgList->NumTemplateArgs; - Arg != ArgEnd; ++Arg) { - if (VisitTemplateArgumentLoc(*Arg)) - return true; - } - } - - return false; -} - -bool CursorVisitor::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) { - // Visit the base expression, if there is one. - if (!E->isImplicitAccess() && - Visit(MakeCXCursor(E->getBase(), StmtParent, TU))) - return true; - - return VisitOverloadExpr(E); -} - -bool CursorVisitor::VisitObjCMessageExpr(ObjCMessageExpr *E) { - if (TypeSourceInfo *TSInfo = E->getClassReceiverTypeInfo()) - if (Visit(TSInfo->getTypeLoc())) - return true; - - return VisitExpr(E); -} - -bool CursorVisitor::VisitObjCEncodeExpr(ObjCEncodeExpr *E) { - return Visit(E->getEncodedTypeSourceInfo()->getTypeLoc()); -} - - -bool CursorVisitor::VisitAttributes(Decl *D) { - for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end(); - i != e; ++i) - if (Visit(MakeCXCursor(*i, D, TU))) - return true; - - return false; -} - -extern "C" { -CXIndex clang_createIndex(int excludeDeclarationsFromPCH, - int displayDiagnostics) { - // We use crash recovery to make some of our APIs more reliable, implicitly - // enable it. - llvm::CrashRecoveryContext::Enable(); - - CIndexer *CIdxr = new CIndexer(); - if (excludeDeclarationsFromPCH) - CIdxr->setOnlyLocalDecls(); - if (displayDiagnostics) - CIdxr->setDisplayDiagnostics(); - return CIdxr; -} - -void clang_disposeIndex(CXIndex CIdx) { - if (CIdx) - delete static_cast<CIndexer *>(CIdx); - if (getenv("LIBCLANG_TIMING")) - llvm::TimerGroup::printAll(llvm::errs()); -} - -void clang_setUseExternalASTGeneration(CXIndex CIdx, int value) { - if (CIdx) { - CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx); - CXXIdx->setUseExternalASTGeneration(value); - } -} - -CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx, - const char *ast_filename) { - if (!CIdx) - return 0; - - CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx); - - llvm::IntrusiveRefCntPtr<Diagnostic> Diags; - return ASTUnit::LoadFromASTFile(ast_filename, Diags, - CXXIdx->getOnlyLocalDecls(), - 0, 0, true); -} - -unsigned clang_defaultEditingTranslationUnitOptions() { - return CXTranslationUnit_PrecompiledPreamble; -} - -CXTranslationUnit -clang_createTranslationUnitFromSourceFile(CXIndex CIdx, - const char *source_filename, - int num_command_line_args, - const char * const *command_line_args, - unsigned num_unsaved_files, - struct CXUnsavedFile *unsaved_files) { - return clang_parseTranslationUnit(CIdx, source_filename, - command_line_args, num_command_line_args, - unsaved_files, num_unsaved_files, - CXTranslationUnit_DetailedPreprocessingRecord); -} - -struct ParseTranslationUnitInfo { - CXIndex CIdx; - const char *source_filename; - const char *const *command_line_args; - int num_command_line_args; - struct CXUnsavedFile *unsaved_files; - unsigned num_unsaved_files; - unsigned options; - CXTranslationUnit result; -}; -static void clang_parseTranslationUnit_Impl(void *UserData) { - ParseTranslationUnitInfo *PTUI = - static_cast<ParseTranslationUnitInfo*>(UserData); - CXIndex CIdx = PTUI->CIdx; - const char *source_filename = PTUI->source_filename; - const char * const *command_line_args = PTUI->command_line_args; - int num_command_line_args = PTUI->num_command_line_args; - struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files; - unsigned num_unsaved_files = PTUI->num_unsaved_files; - unsigned options = PTUI->options; - PTUI->result = 0; - - if (!CIdx) - return; - - CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx); - - bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble; - bool CompleteTranslationUnit - = ((options & CXTranslationUnit_Incomplete) == 0); - bool CacheCodeCompetionResults - = options & CXTranslationUnit_CacheCompletionResults; - - // Configure the diagnostics. - DiagnosticOptions DiagOpts; - llvm::IntrusiveRefCntPtr<Diagnostic> Diags; - Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0); - - llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles; - for (unsigned I = 0; I != num_unsaved_files; ++I) { - llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length); - const llvm::MemoryBuffer *Buffer - = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename); - RemappedFiles.push_back(std::make_pair(unsaved_files[I].Filename, - Buffer)); - } - - if (!CXXIdx->getUseExternalASTGeneration()) { - llvm::SmallVector<const char *, 16> Args; - - // The 'source_filename' argument is optional. If the caller does not - // specify it then it is assumed that the source file is specified - // in the actual argument list. - if (source_filename) - Args.push_back(source_filename); - - // Since the Clang C library is primarily used by batch tools dealing with - // (often very broken) source code, where spell-checking can have a - // significant negative impact on performance (particularly when - // precompiled headers are involved), we disable it by default. - // Note that we place this argument early in the list, so that it can be - // overridden by the caller with "-fspell-checking". - Args.push_back("-fno-spell-checking"); - - Args.insert(Args.end(), command_line_args, - command_line_args + num_command_line_args); - - // Do we need the detailed preprocessing record? - if (options & CXTranslationUnit_DetailedPreprocessingRecord) { - Args.push_back("-Xclang"); - Args.push_back("-detailed-preprocessing-record"); - } - - unsigned NumErrors = Diags->getNumErrors(); - -#ifdef USE_CRASHTRACER - ArgsCrashTracerInfo ACTI(Args); -#endif - - llvm::OwningPtr<ASTUnit> Unit( - ASTUnit::LoadFromCommandLine(Args.data(), Args.data() + Args.size(), - Diags, - CXXIdx->getClangResourcesPath(), - CXXIdx->getOnlyLocalDecls(), - RemappedFiles.data(), - RemappedFiles.size(), - /*CaptureDiagnostics=*/true, - PrecompilePreamble, - CompleteTranslationUnit, - CacheCodeCompetionResults)); - - if (NumErrors != Diags->getNumErrors()) { - // Make sure to check that 'Unit' is non-NULL. - if (CXXIdx->getDisplayDiagnostics() && Unit.get()) { - for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(), - DEnd = Unit->stored_diag_end(); - D != DEnd; ++D) { - CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOptions()); - CXString Msg = clang_formatDiagnostic(&Diag, - clang_defaultDiagnosticDisplayOptions()); - fprintf(stderr, "%s\n", clang_getCString(Msg)); - clang_disposeString(Msg); - } -#ifdef LLVM_ON_WIN32 - // On Windows, force a flush, since there may be multiple copies of - // stderr and stdout in the file system, all with different buffers - // but writing to the same device. - fflush(stderr); -#endif - } - } - - PTUI->result = Unit.take(); - return; - } - - // Build up the arguments for invoking 'clang'. - std::vector<const char *> argv; - - // First add the complete path to the 'clang' executable. - llvm::sys::Path ClangPath = static_cast<CIndexer *>(CIdx)->getClangPath(); - argv.push_back(ClangPath.c_str()); - - // Add the '-emit-ast' option as our execution mode for 'clang'. - argv.push_back("-emit-ast"); - - // The 'source_filename' argument is optional. If the caller does not - // specify it then it is assumed that the source file is specified - // in the actual argument list. - if (source_filename) - argv.push_back(source_filename); - - // Generate a temporary name for the AST file. - argv.push_back("-o"); - char astTmpFile[L_tmpnam]; - argv.push_back(tmpnam(astTmpFile)); - - // Since the Clang C library is primarily used by batch tools dealing with - // (often very broken) source code, where spell-checking can have a - // significant negative impact on performance (particularly when - // precompiled headers are involved), we disable it by default. - // Note that we place this argument early in the list, so that it can be - // overridden by the caller with "-fspell-checking". - argv.push_back("-fno-spell-checking"); - - // Remap any unsaved files to temporary files. - std::vector<llvm::sys::Path> TemporaryFiles; - std::vector<std::string> RemapArgs; - if (RemapFiles(num_unsaved_files, unsaved_files, RemapArgs, TemporaryFiles)) - return; - - // The pointers into the elements of RemapArgs are stable because we - // won't be adding anything to RemapArgs after this point. - for (unsigned i = 0, e = RemapArgs.size(); i != e; ++i) - argv.push_back(RemapArgs[i].c_str()); - - // Process the compiler options, stripping off '-o', '-c', '-fsyntax-only'. - for (int i = 0; i < num_command_line_args; ++i) - if (const char *arg = command_line_args[i]) { - if (strcmp(arg, "-o") == 0) { - ++i; // Also skip the matching argument. - continue; - } - if (strcmp(arg, "-emit-ast") == 0 || - strcmp(arg, "-c") == 0 || - strcmp(arg, "-fsyntax-only") == 0) { - continue; - } - - // Keep the argument. - argv.push_back(arg); - } - - // Generate a temporary name for the diagnostics file. - char tmpFileResults[L_tmpnam]; - char *tmpResultsFileName = tmpnam(tmpFileResults); - llvm::sys::Path DiagnosticsFile(tmpResultsFileName); - TemporaryFiles.push_back(DiagnosticsFile); - argv.push_back("-fdiagnostics-binary"); - - // Do we need the detailed preprocessing record? - if (options & CXTranslationUnit_DetailedPreprocessingRecord) { - argv.push_back("-Xclang"); - argv.push_back("-detailed-preprocessing-record"); - } - - // Add the null terminator. - argv.push_back(NULL); - - // Invoke 'clang'. - llvm::sys::Path DevNull; // leave empty, causes redirection to /dev/null - // on Unix or NUL (Windows). - std::string ErrMsg; - const llvm::sys::Path *Redirects[] = { &DevNull, &DevNull, &DiagnosticsFile, - NULL }; - llvm::sys::Program::ExecuteAndWait(ClangPath, &argv[0], /* env */ NULL, - /* redirects */ &Redirects[0], - /* secondsToWait */ 0, /* memoryLimits */ 0, &ErrMsg); - - if (!ErrMsg.empty()) { - std::string AllArgs; - for (std::vector<const char*>::iterator I = argv.begin(), E = argv.end(); - I != E; ++I) { - AllArgs += ' '; - if (*I) - AllArgs += *I; - } - - Diags->Report(diag::err_fe_invoking) << AllArgs << ErrMsg; - } - - ASTUnit *ATU = ASTUnit::LoadFromASTFile(astTmpFile, Diags, - CXXIdx->getOnlyLocalDecls(), - RemappedFiles.data(), - RemappedFiles.size(), - /*CaptureDiagnostics=*/true); - if (ATU) { - LoadSerializedDiagnostics(DiagnosticsFile, - num_unsaved_files, unsaved_files, - ATU->getFileManager(), - ATU->getSourceManager(), - ATU->getStoredDiagnostics()); - } else if (CXXIdx->getDisplayDiagnostics()) { - // We failed to load the ASTUnit, but we can still deserialize the - // diagnostics and emit them. - FileManager FileMgr; - Diagnostic Diag; - SourceManager SourceMgr(Diag); - // FIXME: Faked LangOpts! - LangOptions LangOpts; - llvm::SmallVector<StoredDiagnostic, 4> Diags; - LoadSerializedDiagnostics(DiagnosticsFile, - num_unsaved_files, unsaved_files, - FileMgr, SourceMgr, Diags); - for (llvm::SmallVector<StoredDiagnostic, 4>::iterator D = Diags.begin(), - DEnd = Diags.end(); - D != DEnd; ++D) { - CXStoredDiagnostic Diag(*D, LangOpts); - CXString Msg = clang_formatDiagnostic(&Diag, - clang_defaultDiagnosticDisplayOptions()); - fprintf(stderr, "%s\n", clang_getCString(Msg)); - clang_disposeString(Msg); - } - -#ifdef LLVM_ON_WIN32 - // On Windows, force a flush, since there may be multiple copies of - // stderr and stdout in the file system, all with different buffers - // but writing to the same device. - fflush(stderr); -#endif - } - - if (ATU) { - // Make the translation unit responsible for destroying all temporary files. - for (unsigned i = 0, e = TemporaryFiles.size(); i != e; ++i) - ATU->addTemporaryFile(TemporaryFiles[i]); - ATU->addTemporaryFile(llvm::sys::Path(ATU->getASTFileName())); - } else { - // Destroy all of the temporary files now; they can't be referenced any - // longer. - llvm::sys::Path(astTmpFile).eraseFromDisk(); - for (unsigned i = 0, e = TemporaryFiles.size(); i != e; ++i) - TemporaryFiles[i].eraseFromDisk(); - } - - PTUI->result = ATU; -} -CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx, - const char *source_filename, - const char * const *command_line_args, - int num_command_line_args, - struct CXUnsavedFile *unsaved_files, - unsigned num_unsaved_files, - unsigned options) { - ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args, - num_command_line_args, unsaved_files, num_unsaved_files, - options, 0 }; - llvm::CrashRecoveryContext CRC; - - if (!CRC.RunSafely(clang_parseTranslationUnit_Impl, &PTUI)) { - fprintf(stderr, "libclang: crash detected during parsing: {\n"); - fprintf(stderr, " 'source_filename' : '%s'\n", source_filename); - fprintf(stderr, " 'command_line_args' : ["); - for (int i = 0; i != num_command_line_args; ++i) { - if (i) - fprintf(stderr, ", "); - fprintf(stderr, "'%s'", command_line_args[i]); - } - fprintf(stderr, "],\n"); - fprintf(stderr, " 'unsaved_files' : ["); - for (unsigned i = 0; i != num_unsaved_files; ++i) { - if (i) - fprintf(stderr, ", "); - fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename, - unsaved_files[i].Length); - } - fprintf(stderr, "],\n"); - fprintf(stderr, " 'options' : %d,\n", options); - fprintf(stderr, "}\n"); - - return 0; - } - - return PTUI.result; -} - -unsigned clang_defaultSaveOptions(CXTranslationUnit TU) { - return CXSaveTranslationUnit_None; -} - -int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName, - unsigned options) { - if (!TU) - return 1; - - return static_cast<ASTUnit *>(TU)->Save(FileName); -} - -void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) { - if (CTUnit) { - // If the translation unit has been marked as unsafe to free, just discard - // it. - if (static_cast<ASTUnit *>(CTUnit)->isUnsafeToFree()) - return; - - delete static_cast<ASTUnit *>(CTUnit); - } -} - -unsigned clang_defaultReparseOptions(CXTranslationUnit TU) { - return CXReparse_None; -} - -struct ReparseTranslationUnitInfo { - CXTranslationUnit TU; - unsigned num_unsaved_files; - struct CXUnsavedFile *unsaved_files; - unsigned options; - int result; -}; -static void clang_reparseTranslationUnit_Impl(void *UserData) { - ReparseTranslationUnitInfo *RTUI = - static_cast<ReparseTranslationUnitInfo*>(UserData); - CXTranslationUnit TU = RTUI->TU; - unsigned num_unsaved_files = RTUI->num_unsaved_files; - struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files; - unsigned options = RTUI->options; - (void) options; - RTUI->result = 1; - - if (!TU) - return; - - llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles; - for (unsigned I = 0; I != num_unsaved_files; ++I) { - llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length); - const llvm::MemoryBuffer *Buffer - = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename); - RemappedFiles.push_back(std::make_pair(unsaved_files[I].Filename, - Buffer)); - } - - if (!static_cast<ASTUnit *>(TU)->Reparse(RemappedFiles.data(), - RemappedFiles.size())) - RTUI->result = 0; -} -int clang_reparseTranslationUnit(CXTranslationUnit TU, - unsigned num_unsaved_files, - struct CXUnsavedFile *unsaved_files, - unsigned options) { - ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files, - options, 0 }; - llvm::CrashRecoveryContext CRC; - - if (!CRC.RunSafely(clang_reparseTranslationUnit_Impl, &RTUI)) { - fprintf(stderr, "libclang: crash detected during reparsing\n"); - static_cast<ASTUnit *>(TU)->setUnsafeToFree(true); - return 1; - } - - return RTUI.result; -} - - -CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) { - if (!CTUnit) - return createCXString(""); - - ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit); - return createCXString(CXXUnit->getOriginalSourceFileName(), true); -} - -CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) { - CXCursor Result = { CXCursor_TranslationUnit, { 0, 0, TU } }; - return Result; -} - -} // end: extern "C" - -//===----------------------------------------------------------------------===// -// CXSourceLocation and CXSourceRange Operations. -//===----------------------------------------------------------------------===// - -extern "C" { -CXSourceLocation clang_getNullLocation() { - CXSourceLocation Result = { { 0, 0 }, 0 }; - return Result; -} - -unsigned clang_equalLocations(CXSourceLocation loc1, CXSourceLocation loc2) { - return (loc1.ptr_data[0] == loc2.ptr_data[0] && - loc1.ptr_data[1] == loc2.ptr_data[1] && - loc1.int_data == loc2.int_data); -} - -CXSourceLocation clang_getLocation(CXTranslationUnit tu, - CXFile file, - unsigned line, - unsigned column) { - if (!tu || !file) - return clang_getNullLocation(); - - ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu); - SourceLocation SLoc - = CXXUnit->getSourceManager().getLocation( - static_cast<const FileEntry *>(file), - line, column); - - return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc); -} - -CXSourceRange clang_getNullRange() { - CXSourceRange Result = { { 0, 0 }, 0, 0 }; - return Result; -} - -CXSourceRange clang_getRange(CXSourceLocation begin, CXSourceLocation end) { - if (begin.ptr_data[0] != end.ptr_data[0] || - begin.ptr_data[1] != end.ptr_data[1]) - return clang_getNullRange(); - - CXSourceRange Result = { { begin.ptr_data[0], begin.ptr_data[1] }, - begin.int_data, end.int_data }; - return Result; -} - -void clang_getInstantiationLocation(CXSourceLocation location, - CXFile *file, - unsigned *line, - unsigned *column, - unsigned *offset) { - SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data); - - if (!location.ptr_data[0] || Loc.isInvalid()) { - if (file) - *file = 0; - if (line) - *line = 0; - if (column) - *column = 0; - if (offset) - *offset = 0; - return; - } - - const SourceManager &SM = - *static_cast<const SourceManager*>(location.ptr_data[0]); - SourceLocation InstLoc = SM.getInstantiationLoc(Loc); - - if (file) - *file = (void *)SM.getFileEntryForID(SM.getFileID(InstLoc)); - if (line) - *line = SM.getInstantiationLineNumber(InstLoc); - if (column) - *column = SM.getInstantiationColumnNumber(InstLoc); - if (offset) - *offset = SM.getDecomposedLoc(InstLoc).second; -} - -CXSourceLocation clang_getRangeStart(CXSourceRange range) { - CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] }, - range.begin_int_data }; - return Result; -} - -CXSourceLocation clang_getRangeEnd(CXSourceRange range) { - CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] }, - range.end_int_data }; - return Result; -} - -} // end: extern "C" - -//===----------------------------------------------------------------------===// -// CXFile Operations. -//===----------------------------------------------------------------------===// - -extern "C" { -CXString clang_getFileName(CXFile SFile) { - if (!SFile) - return createCXString(NULL); - - FileEntry *FEnt = static_cast<FileEntry *>(SFile); - return createCXString(FEnt->getName()); -} - -time_t clang_getFileTime(CXFile SFile) { - if (!SFile) - return 0; - - FileEntry *FEnt = static_cast<FileEntry *>(SFile); - return FEnt->getModificationTime(); -} - -CXFile clang_getFile(CXTranslationUnit tu, const char *file_name) { - if (!tu) - return 0; - - ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu); - - FileManager &FMgr = CXXUnit->getFileManager(); - const FileEntry *File = FMgr.getFile(file_name, file_name+strlen(file_name)); - return const_cast<FileEntry *>(File); -} - -} // end: extern "C" - -//===----------------------------------------------------------------------===// -// CXCursor Operations. -//===----------------------------------------------------------------------===// - -static Decl *getDeclFromExpr(Stmt *E) { - if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E)) - return RefExpr->getDecl(); - if (MemberExpr *ME = dyn_cast<MemberExpr>(E)) - return ME->getMemberDecl(); - if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E)) - return RE->getDecl(); - - if (CallExpr *CE = dyn_cast<CallExpr>(E)) - return getDeclFromExpr(CE->getCallee()); - if (CastExpr *CE = dyn_cast<CastExpr>(E)) - return getDeclFromExpr(CE->getSubExpr()); - if (ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E)) - return OME->getMethodDecl(); - - return 0; -} - -static SourceLocation getLocationFromExpr(Expr *E) { - if (ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E)) - return /*FIXME:*/Msg->getLeftLoc(); - if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) - return DRE->getLocation(); - if (MemberExpr *Member = dyn_cast<MemberExpr>(E)) - return Member->getMemberLoc(); - if (ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E)) - return Ivar->getLocation(); - return E->getLocStart(); -} - -extern "C" { - -unsigned clang_visitChildren(CXCursor parent, - CXCursorVisitor visitor, - CXClientData client_data) { - ASTUnit *CXXUnit = getCursorASTUnit(parent); - - CursorVisitor CursorVis(CXXUnit, visitor, client_data, - CXXUnit->getMaxPCHLevel()); - return CursorVis.VisitChildren(parent); -} - -static CXString getDeclSpelling(Decl *D) { - NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D); - if (!ND) - return createCXString(""); - - if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND)) - return createCXString(OMD->getSelector().getAsString()); - - if (ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND)) - // No, this isn't the same as the code below. getIdentifier() is non-virtual - // and returns different names. NamedDecl returns the class name and - // ObjCCategoryImplDecl returns the category name. - return createCXString(CIMP->getIdentifier()->getNameStart()); - - if (isa<UsingDirectiveDecl>(D)) - return createCXString(""); - - llvm::SmallString<1024> S; - llvm::raw_svector_ostream os(S); - ND->printName(os); - - return createCXString(os.str()); -} - -CXString clang_getCursorSpelling(CXCursor C) { - if (clang_isTranslationUnit(C.kind)) - return clang_getTranslationUnitSpelling(C.data[2]); - - if (clang_isReference(C.kind)) { - switch (C.kind) { - case CXCursor_ObjCSuperClassRef: { - ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first; - return createCXString(Super->getIdentifier()->getNameStart()); - } - case CXCursor_ObjCClassRef: { - ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first; - return createCXString(Class->getIdentifier()->getNameStart()); - } - case CXCursor_ObjCProtocolRef: { - ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first; - assert(OID && "getCursorSpelling(): Missing protocol decl"); - return createCXString(OID->getIdentifier()->getNameStart()); - } - case CXCursor_CXXBaseSpecifier: { - CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C); - return createCXString(B->getType().getAsString()); - } - case CXCursor_TypeRef: { - TypeDecl *Type = getCursorTypeRef(C).first; - assert(Type && "Missing type decl"); - - return createCXString(getCursorContext(C).getTypeDeclType(Type). - getAsString()); - } - case CXCursor_TemplateRef: { - TemplateDecl *Template = getCursorTemplateRef(C).first; - assert(Template && "Missing template decl"); - - return createCXString(Template->getNameAsString()); - } - - case CXCursor_NamespaceRef: { - NamedDecl *NS = getCursorNamespaceRef(C).first; - assert(NS && "Missing namespace decl"); - - return createCXString(NS->getNameAsString()); - } - - default: - return createCXString("<not implemented>"); - } - } - - if (clang_isExpression(C.kind)) { - Decl *D = getDeclFromExpr(getCursorExpr(C)); - if (D) - return getDeclSpelling(D); - return createCXString(""); - } - - if (C.kind == CXCursor_MacroInstantiation) - return createCXString(getCursorMacroInstantiation(C)->getName() - ->getNameStart()); - - if (C.kind == CXCursor_MacroDefinition) - return createCXString(getCursorMacroDefinition(C)->getName() - ->getNameStart()); - - if (clang_isDeclaration(C.kind)) - return getDeclSpelling(getCursorDecl(C)); - - return createCXString(""); -} - -CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) { - switch (Kind) { - case CXCursor_FunctionDecl: - return createCXString("FunctionDecl"); - case CXCursor_TypedefDecl: - return createCXString("TypedefDecl"); - case CXCursor_EnumDecl: - return createCXString("EnumDecl"); - case CXCursor_EnumConstantDecl: - return createCXString("EnumConstantDecl"); - case CXCursor_StructDecl: - return createCXString("StructDecl"); - case CXCursor_UnionDecl: - return createCXString("UnionDecl"); - case CXCursor_ClassDecl: - return createCXString("ClassDecl"); - case CXCursor_FieldDecl: - return createCXString("FieldDecl"); - case CXCursor_VarDecl: - return createCXString("VarDecl"); - case CXCursor_ParmDecl: - return createCXString("ParmDecl"); - case CXCursor_ObjCInterfaceDecl: - return createCXString("ObjCInterfaceDecl"); - case CXCursor_ObjCCategoryDecl: - return createCXString("ObjCCategoryDecl"); - case CXCursor_ObjCProtocolDecl: - return createCXString("ObjCProtocolDecl"); - case CXCursor_ObjCPropertyDecl: - return createCXString("ObjCPropertyDecl"); - case CXCursor_ObjCIvarDecl: - return createCXString("ObjCIvarDecl"); - case CXCursor_ObjCInstanceMethodDecl: - return createCXString("ObjCInstanceMethodDecl"); - case CXCursor_ObjCClassMethodDecl: - return createCXString("ObjCClassMethodDecl"); - case CXCursor_ObjCImplementationDecl: - return createCXString("ObjCImplementationDecl"); - case CXCursor_ObjCCategoryImplDecl: - return createCXString("ObjCCategoryImplDecl"); - case CXCursor_CXXMethod: - return createCXString("CXXMethod"); - case CXCursor_UnexposedDecl: - return createCXString("UnexposedDecl"); - case CXCursor_ObjCSuperClassRef: - return createCXString("ObjCSuperClassRef"); - case CXCursor_ObjCProtocolRef: - return createCXString("ObjCProtocolRef"); - case CXCursor_ObjCClassRef: - return createCXString("ObjCClassRef"); - case CXCursor_TypeRef: - return createCXString("TypeRef"); - case CXCursor_TemplateRef: - return createCXString("TemplateRef"); - case CXCursor_NamespaceRef: - return createCXString("NamespaceRef"); - case CXCursor_UnexposedExpr: - return createCXString("UnexposedExpr"); - case CXCursor_BlockExpr: - return createCXString("BlockExpr"); - case CXCursor_DeclRefExpr: - return createCXString("DeclRefExpr"); - case CXCursor_MemberRefExpr: - return createCXString("MemberRefExpr"); - case CXCursor_CallExpr: - return createCXString("CallExpr"); - case CXCursor_ObjCMessageExpr: - return createCXString("ObjCMessageExpr"); - case CXCursor_UnexposedStmt: - return createCXString("UnexposedStmt"); - case CXCursor_InvalidFile: - return createCXString("InvalidFile"); - case CXCursor_InvalidCode: - return createCXString("InvalidCode"); - case CXCursor_NoDeclFound: - return createCXString("NoDeclFound"); - case CXCursor_NotImplemented: - return createCXString("NotImplemented"); - case CXCursor_TranslationUnit: - return createCXString("TranslationUnit"); - case CXCursor_UnexposedAttr: - return createCXString("UnexposedAttr"); - case CXCursor_IBActionAttr: - return createCXString("attribute(ibaction)"); - case CXCursor_IBOutletAttr: - return createCXString("attribute(iboutlet)"); - case CXCursor_IBOutletCollectionAttr: - return createCXString("attribute(iboutletcollection)"); - case CXCursor_PreprocessingDirective: - return createCXString("preprocessing directive"); - case CXCursor_MacroDefinition: - return createCXString("macro definition"); - case CXCursor_MacroInstantiation: - return createCXString("macro instantiation"); - case CXCursor_Namespace: - return createCXString("Namespace"); - case CXCursor_LinkageSpec: - return createCXString("LinkageSpec"); - case CXCursor_CXXBaseSpecifier: - return createCXString("C++ base class specifier"); - case CXCursor_Constructor: - return createCXString("CXXConstructor"); - case CXCursor_Destructor: - return createCXString("CXXDestructor"); - case CXCursor_ConversionFunction: - return createCXString("CXXConversion"); - case CXCursor_TemplateTypeParameter: - return createCXString("TemplateTypeParameter"); - case CXCursor_NonTypeTemplateParameter: - return createCXString("NonTypeTemplateParameter"); - case CXCursor_TemplateTemplateParameter: - return createCXString("TemplateTemplateParameter"); - case CXCursor_FunctionTemplate: - return createCXString("FunctionTemplate"); - case CXCursor_ClassTemplate: - return createCXString("ClassTemplate"); - case CXCursor_ClassTemplatePartialSpecialization: - return createCXString("ClassTemplatePartialSpecialization"); - case CXCursor_NamespaceAlias: - return createCXString("NamespaceAlias"); - case CXCursor_UsingDirective: - return createCXString("UsingDirective"); - case CXCursor_UsingDeclaration: - return createCXString("UsingDeclaration"); - } - - llvm_unreachable("Unhandled CXCursorKind"); - return createCXString(NULL); -} - -enum CXChildVisitResult GetCursorVisitor(CXCursor cursor, - CXCursor parent, - CXClientData client_data) { - CXCursor *BestCursor = static_cast<CXCursor *>(client_data); - *BestCursor = cursor; - return CXChildVisit_Recurse; -} - -CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) { - if (!TU) - return clang_getNullCursor(); - - ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU); - ASTUnit::ConcurrencyCheck Check(*CXXUnit); - - // Translate the given source location to make it point at the beginning of - // the token under the cursor. - SourceLocation SLoc = cxloc::translateSourceLocation(Loc); - - // Guard against an invalid SourceLocation, or we may assert in one - // of the following calls. - if (SLoc.isInvalid()) - return clang_getNullCursor(); - - SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(), - CXXUnit->getASTContext().getLangOptions()); - - CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound); - if (SLoc.isValid()) { - // FIXME: Would be great to have a "hint" cursor, then walk from that - // hint cursor upward until we find a cursor whose source range encloses - // the region of interest, rather than starting from the translation unit. - CXCursor Parent = clang_getTranslationUnitCursor(CXXUnit); - CursorVisitor CursorVis(CXXUnit, GetCursorVisitor, &Result, - Decl::MaxPCHLevel, SourceLocation(SLoc)); - CursorVis.VisitChildren(Parent); - } - return Result; -} - -CXCursor clang_getNullCursor(void) { - return MakeCXCursorInvalid(CXCursor_InvalidFile); -} - -unsigned clang_equalCursors(CXCursor X, CXCursor Y) { - return X == Y; -} - -unsigned clang_isInvalid(enum CXCursorKind K) { - return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid; -} - -unsigned clang_isDeclaration(enum CXCursorKind K) { - return K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl; -} - -unsigned clang_isReference(enum CXCursorKind K) { - return K >= CXCursor_FirstRef && K <= CXCursor_LastRef; -} - -unsigned clang_isExpression(enum CXCursorKind K) { - return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr; -} - -unsigned clang_isStatement(enum CXCursorKind K) { - return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt; -} - -unsigned clang_isTranslationUnit(enum CXCursorKind K) { - return K == CXCursor_TranslationUnit; -} - -unsigned clang_isPreprocessing(enum CXCursorKind K) { - return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing; -} - -unsigned clang_isUnexposed(enum CXCursorKind K) { - switch (K) { - case CXCursor_UnexposedDecl: - case CXCursor_UnexposedExpr: - case CXCursor_UnexposedStmt: - case CXCursor_UnexposedAttr: - return true; - default: - return false; - } -} - -CXCursorKind clang_getCursorKind(CXCursor C) { - return C.kind; -} - -CXSourceLocation clang_getCursorLocation(CXCursor C) { - if (clang_isReference(C.kind)) { - switch (C.kind) { - case CXCursor_ObjCSuperClassRef: { - std::pair<ObjCInterfaceDecl *, SourceLocation> P - = getCursorObjCSuperClassRef(C); - return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); - } - - case CXCursor_ObjCProtocolRef: { - std::pair<ObjCProtocolDecl *, SourceLocation> P - = getCursorObjCProtocolRef(C); - return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); - } - - case CXCursor_ObjCClassRef: { - std::pair<ObjCInterfaceDecl *, SourceLocation> P - = getCursorObjCClassRef(C); - return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); - } - - case CXCursor_TypeRef: { - std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C); - return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); - } - - case CXCursor_TemplateRef: { - std::pair<TemplateDecl *, SourceLocation> P = getCursorTemplateRef(C); - return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); - } - - case CXCursor_NamespaceRef: { - std::pair<NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C); - return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); - } - - case CXCursor_CXXBaseSpecifier: { - // FIXME: Figure out what location to return for a CXXBaseSpecifier. - return clang_getNullLocation(); - } - - default: - // FIXME: Need a way to enumerate all non-reference cases. - llvm_unreachable("Missed a reference kind"); - } - } - - if (clang_isExpression(C.kind)) - return cxloc::translateSourceLocation(getCursorContext(C), - getLocationFromExpr(getCursorExpr(C))); - - if (C.kind == CXCursor_PreprocessingDirective) { - SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin(); - return cxloc::translateSourceLocation(getCursorContext(C), L); - } - - if (C.kind == CXCursor_MacroInstantiation) { - SourceLocation L - = cxcursor::getCursorMacroInstantiation(C)->getSourceRange().getBegin(); - return cxloc::translateSourceLocation(getCursorContext(C), L); - } - - if (C.kind == CXCursor_MacroDefinition) { - SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation(); - return cxloc::translateSourceLocation(getCursorContext(C), L); - } - - if (C.kind < CXCursor_FirstDecl || C.kind > CXCursor_LastDecl) - return clang_getNullLocation(); - - Decl *D = getCursorDecl(C); - SourceLocation Loc = D->getLocation(); - if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(D)) - Loc = Class->getClassLoc(); - return cxloc::translateSourceLocation(getCursorContext(C), Loc); -} - -} // end extern "C" - -static SourceRange getRawCursorExtent(CXCursor C) { - if (clang_isReference(C.kind)) { - switch (C.kind) { - case CXCursor_ObjCSuperClassRef: - return getCursorObjCSuperClassRef(C).second; - - case CXCursor_ObjCProtocolRef: - return getCursorObjCProtocolRef(C).second; - - case CXCursor_ObjCClassRef: - return getCursorObjCClassRef(C).second; - - case CXCursor_TypeRef: - return getCursorTypeRef(C).second; - - case CXCursor_TemplateRef: - return getCursorTemplateRef(C).second; - - case CXCursor_NamespaceRef: - return getCursorNamespaceRef(C).second; - - case CXCursor_CXXBaseSpecifier: - // FIXME: Figure out what source range to use for a CXBaseSpecifier. - return SourceRange(); - - default: - // FIXME: Need a way to enumerate all non-reference cases. - llvm_unreachable("Missed a reference kind"); - } - } - - if (clang_isExpression(C.kind)) - return getCursorExpr(C)->getSourceRange(); - - if (clang_isStatement(C.kind)) - return getCursorStmt(C)->getSourceRange(); - - if (C.kind == CXCursor_PreprocessingDirective) - return cxcursor::getCursorPreprocessingDirective(C); - - if (C.kind == CXCursor_MacroInstantiation) - return cxcursor::getCursorMacroInstantiation(C)->getSourceRange(); - - if (C.kind == CXCursor_MacroDefinition) - return cxcursor::getCursorMacroDefinition(C)->getSourceRange(); - - if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) - return getCursorDecl(C)->getSourceRange(); - - return SourceRange(); -} - -extern "C" { - -CXSourceRange clang_getCursorExtent(CXCursor C) { - SourceRange R = getRawCursorExtent(C); - if (R.isInvalid()) - return clang_getNullRange(); - - return cxloc::translateSourceRange(getCursorContext(C), R); -} - -CXCursor clang_getCursorReferenced(CXCursor C) { - if (clang_isInvalid(C.kind)) - return clang_getNullCursor(); - - ASTUnit *CXXUnit = getCursorASTUnit(C); - if (clang_isDeclaration(C.kind)) - return C; - - if (clang_isExpression(C.kind)) { - Decl *D = getDeclFromExpr(getCursorExpr(C)); - if (D) - return MakeCXCursor(D, CXXUnit); - return clang_getNullCursor(); - } - - if (C.kind == CXCursor_MacroInstantiation) { - if (MacroDefinition *Def = getCursorMacroInstantiation(C)->getDefinition()) - return MakeMacroDefinitionCursor(Def, CXXUnit); - } - - if (!clang_isReference(C.kind)) - return clang_getNullCursor(); - - switch (C.kind) { - case CXCursor_ObjCSuperClassRef: - return MakeCXCursor(getCursorObjCSuperClassRef(C).first, CXXUnit); - - case CXCursor_ObjCProtocolRef: { - return MakeCXCursor(getCursorObjCProtocolRef(C).first, CXXUnit); - - case CXCursor_ObjCClassRef: - return MakeCXCursor(getCursorObjCClassRef(C).first, CXXUnit); - - case CXCursor_TypeRef: - return MakeCXCursor(getCursorTypeRef(C).first, CXXUnit); - - case CXCursor_TemplateRef: - return MakeCXCursor(getCursorTemplateRef(C).first, CXXUnit); - - case CXCursor_NamespaceRef: - return MakeCXCursor(getCursorNamespaceRef(C).first, CXXUnit); - - case CXCursor_CXXBaseSpecifier: { - CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C); - return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(), - CXXUnit)); - } - - default: - // We would prefer to enumerate all non-reference cursor kinds here. - llvm_unreachable("Unhandled reference cursor kind"); - break; - } - } - - return clang_getNullCursor(); -} - -CXCursor clang_getCursorDefinition(CXCursor C) { - if (clang_isInvalid(C.kind)) - return clang_getNullCursor(); - - ASTUnit *CXXUnit = getCursorASTUnit(C); - - bool WasReference = false; - if (clang_isReference(C.kind) || clang_isExpression(C.kind)) { - C = clang_getCursorReferenced(C); - WasReference = true; - } - - if (C.kind == CXCursor_MacroInstantiation) - return clang_getCursorReferenced(C); - - if (!clang_isDeclaration(C.kind)) - return clang_getNullCursor(); - - Decl *D = getCursorDecl(C); - if (!D) - return clang_getNullCursor(); - - switch (D->getKind()) { - // Declaration kinds that don't really separate the notions of - // declaration and definition. - case Decl::Namespace: - case Decl::Typedef: - case Decl::TemplateTypeParm: - case Decl::EnumConstant: - case Decl::Field: - case Decl::ObjCIvar: - case Decl::ObjCAtDefsField: - case Decl::ImplicitParam: - case Decl::ParmVar: - case Decl::NonTypeTemplateParm: - case Decl::TemplateTemplateParm: - case Decl::ObjCCategoryImpl: - case Decl::ObjCImplementation: - case Decl::AccessSpec: - case Decl::LinkageSpec: - case Decl::ObjCPropertyImpl: - case Decl::FileScopeAsm: - case Decl::StaticAssert: - case Decl::Block: - return C; - - // Declaration kinds that don't make any sense here, but are - // nonetheless harmless. - case Decl::TranslationUnit: - break; - - // Declaration kinds for which the definition is not resolvable. - case Decl::UnresolvedUsingTypename: - case Decl::UnresolvedUsingValue: - break; - - case Decl::UsingDirective: - return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(), - CXXUnit); - - case Decl::NamespaceAlias: - return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), CXXUnit); - - case Decl::Enum: - case Decl::Record: - case Decl::CXXRecord: - case Decl::ClassTemplateSpecialization: - case Decl::ClassTemplatePartialSpecialization: - if (TagDecl *Def = cast<TagDecl>(D)->getDefinition()) - return MakeCXCursor(Def, CXXUnit); - return clang_getNullCursor(); - - case Decl::Function: - case Decl::CXXMethod: - case Decl::CXXConstructor: - case Decl::CXXDestructor: - case Decl::CXXConversion: { - const FunctionDecl *Def = 0; - if (cast<FunctionDecl>(D)->getBody(Def)) - return MakeCXCursor(const_cast<FunctionDecl *>(Def), CXXUnit); - return clang_getNullCursor(); - } - - case Decl::Var: { - // Ask the variable if it has a definition. - if (VarDecl *Def = cast<VarDecl>(D)->getDefinition()) - return MakeCXCursor(Def, CXXUnit); - return clang_getNullCursor(); - } - - case Decl::FunctionTemplate: { - const FunctionDecl *Def = 0; - if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def)) - return MakeCXCursor(Def->getDescribedFunctionTemplate(), CXXUnit); - return clang_getNullCursor(); - } - - case Decl::ClassTemplate: { - if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl() - ->getDefinition()) - return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(), - CXXUnit); - return clang_getNullCursor(); - } - - case Decl::Using: { - UsingDecl *Using = cast<UsingDecl>(D); - CXCursor Def = clang_getNullCursor(); - for (UsingDecl::shadow_iterator S = Using->shadow_begin(), - SEnd = Using->shadow_end(); - S != SEnd; ++S) { - if (Def != clang_getNullCursor()) { - // FIXME: We have no way to return multiple results. - return clang_getNullCursor(); - } - - Def = clang_getCursorDefinition(MakeCXCursor((*S)->getTargetDecl(), - CXXUnit)); - } - - return Def; - } - - case Decl::UsingShadow: - return clang_getCursorDefinition( - MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(), - CXXUnit)); - - case Decl::ObjCMethod: { - ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D); - if (Method->isThisDeclarationADefinition()) - return C; - - // Dig out the method definition in the associated - // @implementation, if we have it. - // FIXME: The ASTs should make finding the definition easier. - if (ObjCInterfaceDecl *Class - = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext())) - if (ObjCImplementationDecl *ClassImpl = Class->getImplementation()) - if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(), - Method->isInstanceMethod())) - if (Def->isThisDeclarationADefinition()) - return MakeCXCursor(Def, CXXUnit); - - return clang_getNullCursor(); - } - - case Decl::ObjCCategory: - if (ObjCCategoryImplDecl *Impl - = cast<ObjCCategoryDecl>(D)->getImplementation()) - return MakeCXCursor(Impl, CXXUnit); - return clang_getNullCursor(); - - case Decl::ObjCProtocol: - if (!cast<ObjCProtocolDecl>(D)->isForwardDecl()) - return C; - return clang_getNullCursor(); - - case Decl::ObjCInterface: - // There are two notions of a "definition" for an Objective-C - // class: the interface and its implementation. When we resolved a - // reference to an Objective-C class, produce the @interface as - // the definition; when we were provided with the interface, - // produce the @implementation as the definition. - if (WasReference) { - if (!cast<ObjCInterfaceDecl>(D)->isForwardDecl()) - return C; - } else if (ObjCImplementationDecl *Impl - = cast<ObjCInterfaceDecl>(D)->getImplementation()) - return MakeCXCursor(Impl, CXXUnit); - return clang_getNullCursor(); - - case Decl::ObjCProperty: - // FIXME: We don't really know where to find the - // ObjCPropertyImplDecls that implement this property. - return clang_getNullCursor(); - - case Decl::ObjCCompatibleAlias: - if (ObjCInterfaceDecl *Class - = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface()) - if (!Class->isForwardDecl()) - return MakeCXCursor(Class, CXXUnit); - - return clang_getNullCursor(); - - case Decl::ObjCForwardProtocol: { - ObjCForwardProtocolDecl *Forward = cast<ObjCForwardProtocolDecl>(D); - if (Forward->protocol_size() == 1) - return clang_getCursorDefinition( - MakeCXCursor(*Forward->protocol_begin(), - CXXUnit)); - - // FIXME: Cannot return multiple definitions. - return clang_getNullCursor(); - } - - case Decl::ObjCClass: { - ObjCClassDecl *Class = cast<ObjCClassDecl>(D); - if (Class->size() == 1) { - ObjCInterfaceDecl *IFace = Class->begin()->getInterface(); - if (!IFace->isForwardDecl()) - return MakeCXCursor(IFace, CXXUnit); - return clang_getNullCursor(); - } - - // FIXME: Cannot return multiple definitions. - return clang_getNullCursor(); - } - - case Decl::Friend: - if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl()) - return clang_getCursorDefinition(MakeCXCursor(Friend, CXXUnit)); - return clang_getNullCursor(); - - case Decl::FriendTemplate: - if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl()) - return clang_getCursorDefinition(MakeCXCursor(Friend, CXXUnit)); - return clang_getNullCursor(); - } - - return clang_getNullCursor(); -} - -unsigned clang_isCursorDefinition(CXCursor C) { - if (!clang_isDeclaration(C.kind)) - return 0; - - return clang_getCursorDefinition(C) == C; -} - -void clang_getDefinitionSpellingAndExtent(CXCursor C, - const char **startBuf, - const char **endBuf, - unsigned *startLine, - unsigned *startColumn, - unsigned *endLine, - unsigned *endColumn) { - assert(getCursorDecl(C) && "CXCursor has null decl"); - NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C)); - FunctionDecl *FD = dyn_cast<FunctionDecl>(ND); - CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody()); - - SourceManager &SM = FD->getASTContext().getSourceManager(); - *startBuf = SM.getCharacterData(Body->getLBracLoc()); - *endBuf = SM.getCharacterData(Body->getRBracLoc()); - *startLine = SM.getSpellingLineNumber(Body->getLBracLoc()); - *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc()); - *endLine = SM.getSpellingLineNumber(Body->getRBracLoc()); - *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc()); -} - -void clang_enableStackTraces(void) { - llvm::sys::PrintStackTraceOnErrorSignal(); -} - -} // end: extern "C" - -//===----------------------------------------------------------------------===// -// Token-based Operations. -//===----------------------------------------------------------------------===// - -/* CXToken layout: - * int_data[0]: a CXTokenKind - * int_data[1]: starting token location - * int_data[2]: token length - * int_data[3]: reserved - * ptr_data: for identifiers and keywords, an IdentifierInfo*. - * otherwise unused. - */ -extern "C" { - -CXTokenKind clang_getTokenKind(CXToken CXTok) { - return static_cast<CXTokenKind>(CXTok.int_data[0]); -} - -CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) { - switch (clang_getTokenKind(CXTok)) { - case CXToken_Identifier: - case CXToken_Keyword: - // We know we have an IdentifierInfo*, so use that. - return createCXString(static_cast<IdentifierInfo *>(CXTok.ptr_data) - ->getNameStart()); - - case CXToken_Literal: { - // We have stashed the starting pointer in the ptr_data field. Use it. - const char *Text = static_cast<const char *>(CXTok.ptr_data); - return createCXString(llvm::StringRef(Text, CXTok.int_data[2])); - } - - case CXToken_Punctuation: - case CXToken_Comment: - break; - } - - // We have to find the starting buffer pointer the hard way, by - // deconstructing the source location. - ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU); - if (!CXXUnit) - return createCXString(""); - - SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]); - std::pair<FileID, unsigned> LocInfo - = CXXUnit->getSourceManager().getDecomposedLoc(Loc); - bool Invalid = false; - llvm::StringRef Buffer - = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid); - if (Invalid) - return createCXString(""); - - return createCXString(Buffer.substr(LocInfo.second, CXTok.int_data[2])); -} - -CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) { - ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU); - if (!CXXUnit) - return clang_getNullLocation(); - - return cxloc::translateSourceLocation(CXXUnit->getASTContext(), - SourceLocation::getFromRawEncoding(CXTok.int_data[1])); -} - -CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) { - ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU); - if (!CXXUnit) - return clang_getNullRange(); - - return cxloc::translateSourceRange(CXXUnit->getASTContext(), - SourceLocation::getFromRawEncoding(CXTok.int_data[1])); -} - -void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range, - CXToken **Tokens, unsigned *NumTokens) { - if (Tokens) - *Tokens = 0; - if (NumTokens) - *NumTokens = 0; - - ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU); - if (!CXXUnit || !Tokens || !NumTokens) - return; - - ASTUnit::ConcurrencyCheck Check(*CXXUnit); - - SourceRange R = cxloc::translateCXSourceRange(Range); - if (R.isInvalid()) - return; - - SourceManager &SourceMgr = CXXUnit->getSourceManager(); - std::pair<FileID, unsigned> BeginLocInfo - = SourceMgr.getDecomposedLoc(R.getBegin()); - std::pair<FileID, unsigned> EndLocInfo - = SourceMgr.getDecomposedLoc(R.getEnd()); - - // Cannot tokenize across files. - if (BeginLocInfo.first != EndLocInfo.first) - return; - - // Create a lexer - bool Invalid = false; - llvm::StringRef Buffer - = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid); - if (Invalid) - return; - - Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first), - CXXUnit->getASTContext().getLangOptions(), - Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end()); - Lex.SetCommentRetentionState(true); - - // Lex tokens until we hit the end of the range. - const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second; - llvm::SmallVector<CXToken, 32> CXTokens; - Token Tok; - do { - // Lex the next token - Lex.LexFromRawLexer(Tok); - if (Tok.is(tok::eof)) - break; - - // Initialize the CXToken. - CXToken CXTok; - - // - Common fields - CXTok.int_data[1] = Tok.getLocation().getRawEncoding(); - CXTok.int_data[2] = Tok.getLength(); - CXTok.int_data[3] = 0; - - // - Kind-specific fields - if (Tok.isLiteral()) { - CXTok.int_data[0] = CXToken_Literal; - CXTok.ptr_data = (void *)Tok.getLiteralData(); - } else if (Tok.is(tok::identifier)) { - // Lookup the identifier to determine whether we have a keyword. - std::pair<FileID, unsigned> LocInfo - = SourceMgr.getDecomposedLoc(Tok.getLocation()); - bool Invalid = false; - llvm::StringRef Buf - = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid); - if (Invalid) - return; - - const char *StartPos = Buf.data() + LocInfo.second; - IdentifierInfo *II - = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok, StartPos); - - if (II->getObjCKeywordID() != tok::objc_not_keyword) { - CXTok.int_data[0] = CXToken_Keyword; - } - else { - CXTok.int_data[0] = II->getTokenID() == tok::identifier? - CXToken_Identifier - : CXToken_Keyword; - } - CXTok.ptr_data = II; - } else if (Tok.is(tok::comment)) { - CXTok.int_data[0] = CXToken_Comment; - CXTok.ptr_data = 0; - } else { - CXTok.int_data[0] = CXToken_Punctuation; - CXTok.ptr_data = 0; - } - CXTokens.push_back(CXTok); - } while (Lex.getBufferLocation() <= EffectiveBufferEnd); - - if (CXTokens.empty()) - return; - - *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size()); - memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size()); - *NumTokens = CXTokens.size(); -} - -void clang_disposeTokens(CXTranslationUnit TU, - CXToken *Tokens, unsigned NumTokens) { - free(Tokens); -} - -} // end: extern "C" - -//===----------------------------------------------------------------------===// -// Token annotation APIs. -//===----------------------------------------------------------------------===// - -typedef llvm::DenseMap<unsigned, CXCursor> AnnotateTokensData; -static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor, - CXCursor parent, - CXClientData client_data); -namespace { -class AnnotateTokensWorker { - AnnotateTokensData &Annotated; - CXToken *Tokens; - CXCursor *Cursors; - unsigned NumTokens; - unsigned TokIdx; - CursorVisitor AnnotateVis; - SourceManager &SrcMgr; - - bool MoreTokens() const { return TokIdx < NumTokens; } - unsigned NextToken() const { return TokIdx; } - void AdvanceToken() { ++TokIdx; } - SourceLocation GetTokenLoc(unsigned tokI) { - return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]); - } - -public: - AnnotateTokensWorker(AnnotateTokensData &annotated, - CXToken *tokens, CXCursor *cursors, unsigned numTokens, - ASTUnit *CXXUnit, SourceRange RegionOfInterest) - : Annotated(annotated), Tokens(tokens), Cursors(cursors), - NumTokens(numTokens), TokIdx(0), - AnnotateVis(CXXUnit, AnnotateTokensVisitor, this, - Decl::MaxPCHLevel, RegionOfInterest), - SrcMgr(CXXUnit->getSourceManager()) {} - - void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); } - enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent); - void AnnotateTokens(CXCursor parent); -}; -} - -void AnnotateTokensWorker::AnnotateTokens(CXCursor parent) { - // Walk the AST within the region of interest, annotating tokens - // along the way. - VisitChildren(parent); - - for (unsigned I = 0 ; I < TokIdx ; ++I) { - AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]); - if (Pos != Annotated.end()) - Cursors[I] = Pos->second; - } - - // Finish up annotating any tokens left. - if (!MoreTokens()) - return; - - const CXCursor &C = clang_getNullCursor(); - for (unsigned I = TokIdx ; I < NumTokens ; ++I) { - AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]); - Cursors[I] = (Pos == Annotated.end()) ? C : Pos->second; - } -} - -enum CXChildVisitResult -AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) { - CXSourceLocation Loc = clang_getCursorLocation(cursor); - // We can always annotate a preprocessing directive/macro instantiation. - if (clang_isPreprocessing(cursor.kind)) { - Annotated[Loc.int_data] = cursor; - return CXChildVisit_Recurse; - } - - SourceRange cursorRange = getRawCursorExtent(cursor); - - if (cursorRange.isInvalid()) - return CXChildVisit_Continue; - - SourceLocation L = SourceLocation::getFromRawEncoding(Loc.int_data); - - // Adjust the annotated range based specific declarations. - const enum CXCursorKind cursorK = clang_getCursorKind(cursor); - if (cursorK >= CXCursor_FirstDecl && cursorK <= CXCursor_LastDecl) { - Decl *D = cxcursor::getCursorDecl(cursor); - // Don't visit synthesized ObjC methods, since they have no syntatic - // representation in the source. - if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { - if (MD->isSynthesized()) - return CXChildVisit_Continue; - } - if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) { - if (TypeSourceInfo *TI = DD->getTypeSourceInfo()) { - TypeLoc TL = TI->getTypeLoc(); - SourceLocation TLoc = TL.getSourceRange().getBegin(); - if (TLoc.isValid() && - SrcMgr.isBeforeInTranslationUnit(TLoc, L)) - cursorRange.setBegin(TLoc); - } - } - } - - // If the location of the cursor occurs within a macro instantiation, record - // the spelling location of the cursor in our annotation map. We can then - // paper over the token labelings during a post-processing step to try and - // get cursor mappings for tokens that are the *arguments* of a macro - // instantiation. - if (L.isMacroID()) { - unsigned rawEncoding = SrcMgr.getSpellingLoc(L).getRawEncoding(); - // Only invalidate the old annotation if it isn't part of a preprocessing - // directive. Here we assume that the default construction of CXCursor - // results in CXCursor.kind being an initialized value (i.e., 0). If - // this isn't the case, we can fix by doing lookup + insertion. - - CXCursor &oldC = Annotated[rawEncoding]; - if (!clang_isPreprocessing(oldC.kind)) - oldC = cursor; - } - - const enum CXCursorKind K = clang_getCursorKind(parent); - const CXCursor updateC = - (clang_isInvalid(K) || K == CXCursor_TranslationUnit) - ? clang_getNullCursor() : parent; - - while (MoreTokens()) { - const unsigned I = NextToken(); - SourceLocation TokLoc = GetTokenLoc(I); - switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) { - case RangeBefore: - Cursors[I] = updateC; - AdvanceToken(); - continue; - case RangeAfter: - case RangeOverlap: - break; - } - break; - } - - // Visit children to get their cursor information. - const unsigned BeforeChildren = NextToken(); - VisitChildren(cursor); - const unsigned AfterChildren = NextToken(); - - // Adjust 'Last' to the last token within the extent of the cursor. - while (MoreTokens()) { - const unsigned I = NextToken(); - SourceLocation TokLoc = GetTokenLoc(I); - switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) { - case RangeBefore: - assert(0 && "Infeasible"); - case RangeAfter: - break; - case RangeOverlap: - Cursors[I] = updateC; - AdvanceToken(); - continue; - } - break; - } - const unsigned Last = NextToken(); - - // Scan the tokens that are at the beginning of the cursor, but are not - // capture by the child cursors. - - // For AST elements within macros, rely on a post-annotate pass to - // to correctly annotate the tokens with cursors. Otherwise we can - // get confusing results of having tokens that map to cursors that really - // are expanded by an instantiation. - if (L.isMacroID()) - cursor = clang_getNullCursor(); - - for (unsigned I = BeforeChildren; I != AfterChildren; ++I) { - if (!clang_isInvalid(clang_getCursorKind(Cursors[I]))) - break; - Cursors[I] = cursor; - } - // Scan the tokens that are at the end of the cursor, but are not captured - // but the child cursors. - for (unsigned I = AfterChildren; I != Last; ++I) - Cursors[I] = cursor; - - TokIdx = Last; - return CXChildVisit_Continue; -} - -static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor, - CXCursor parent, - CXClientData client_data) { - return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent); -} - -extern "C" { - -void clang_annotateTokens(CXTranslationUnit TU, - CXToken *Tokens, unsigned NumTokens, - CXCursor *Cursors) { - - if (NumTokens == 0 || !Tokens || !Cursors) - return; - - ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU); - if (!CXXUnit) { - // Any token we don't specifically annotate will have a NULL cursor. - const CXCursor &C = clang_getNullCursor(); - for (unsigned I = 0; I != NumTokens; ++I) - Cursors[I] = C; - return; - } - - ASTUnit::ConcurrencyCheck Check(*CXXUnit); - - // Determine the region of interest, which contains all of the tokens. - SourceRange RegionOfInterest; - RegionOfInterest.setBegin(cxloc::translateSourceLocation( - clang_getTokenLocation(TU, Tokens[0]))); - RegionOfInterest.setEnd(cxloc::translateSourceLocation( - clang_getTokenLocation(TU, - Tokens[NumTokens - 1]))); - - // A mapping from the source locations found when re-lexing or traversing the - // region of interest to the corresponding cursors. - AnnotateTokensData Annotated; - - // Relex the tokens within the source range to look for preprocessing - // directives. - SourceManager &SourceMgr = CXXUnit->getSourceManager(); - std::pair<FileID, unsigned> BeginLocInfo - = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin()); - std::pair<FileID, unsigned> EndLocInfo - = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd()); - - llvm::StringRef Buffer; - bool Invalid = false; - if (BeginLocInfo.first == EndLocInfo.first && - ((Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid)),true) && - !Invalid) { - Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first), - CXXUnit->getASTContext().getLangOptions(), - Buffer.begin(), Buffer.data() + BeginLocInfo.second, - Buffer.end()); - Lex.SetCommentRetentionState(true); - - // Lex tokens in raw mode until we hit the end of the range, to avoid - // entering #includes or expanding macros. - while (true) { - Token Tok; - Lex.LexFromRawLexer(Tok); - - reprocess: - if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) { - // We have found a preprocessing directive. Gobble it up so that we - // don't see it while preprocessing these tokens later, but keep track of - // all of the token locations inside this preprocessing directive so that - // we can annotate them appropriately. - // - // FIXME: Some simple tests here could identify macro definitions and - // #undefs, to provide specific cursor kinds for those. - std::vector<SourceLocation> Locations; - do { - Locations.push_back(Tok.getLocation()); - Lex.LexFromRawLexer(Tok); - } while (!Tok.isAtStartOfLine() && !Tok.is(tok::eof)); - - using namespace cxcursor; - CXCursor Cursor - = MakePreprocessingDirectiveCursor(SourceRange(Locations.front(), - Locations.back()), - CXXUnit); - for (unsigned I = 0, N = Locations.size(); I != N; ++I) { - Annotated[Locations[I].getRawEncoding()] = Cursor; - } - - if (Tok.isAtStartOfLine()) - goto reprocess; - - continue; - } - - if (Tok.is(tok::eof)) - break; - } - } - - // Annotate all of the source locations in the region of interest that map to - // a specific cursor. - AnnotateTokensWorker W(Annotated, Tokens, Cursors, NumTokens, - CXXUnit, RegionOfInterest); - W.AnnotateTokens(clang_getTranslationUnitCursor(CXXUnit)); -} -} // end: extern "C" - -//===----------------------------------------------------------------------===// -// Operations for querying linkage of a cursor. -//===----------------------------------------------------------------------===// - -extern "C" { -CXLinkageKind clang_getCursorLinkage(CXCursor cursor) { - if (!clang_isDeclaration(cursor.kind)) - return CXLinkage_Invalid; - - Decl *D = cxcursor::getCursorDecl(cursor); - if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D)) - switch (ND->getLinkage()) { - case NoLinkage: return CXLinkage_NoLinkage; - case InternalLinkage: return CXLinkage_Internal; - case UniqueExternalLinkage: return CXLinkage_UniqueExternal; - case ExternalLinkage: return CXLinkage_External; - }; - - return CXLinkage_Invalid; -} -} // end: extern "C" - -//===----------------------------------------------------------------------===// -// Operations for querying language of a cursor. -//===----------------------------------------------------------------------===// - -static CXLanguageKind getDeclLanguage(const Decl *D) { - switch (D->getKind()) { - default: - break; - case Decl::ImplicitParam: - case Decl::ObjCAtDefsField: - case Decl::ObjCCategory: - case Decl::ObjCCategoryImpl: - case Decl::ObjCClass: - case Decl::ObjCCompatibleAlias: - case Decl::ObjCForwardProtocol: - case Decl::ObjCImplementation: - case Decl::ObjCInterface: - case Decl::ObjCIvar: - case Decl::ObjCMethod: - case Decl::ObjCProperty: - case Decl::ObjCPropertyImpl: - case Decl::ObjCProtocol: - return CXLanguage_ObjC; - case Decl::CXXConstructor: - case Decl::CXXConversion: - case Decl::CXXDestructor: - case Decl::CXXMethod: - case Decl::CXXRecord: - case Decl::ClassTemplate: - case Decl::ClassTemplatePartialSpecialization: - case Decl::ClassTemplateSpecialization: - case Decl::Friend: - case Decl::FriendTemplate: - case Decl::FunctionTemplate: - case Decl::LinkageSpec: - case Decl::Namespace: - case Decl::NamespaceAlias: - case Decl::NonTypeTemplateParm: - case Decl::StaticAssert: - case Decl::TemplateTemplateParm: - case Decl::TemplateTypeParm: - case Decl::UnresolvedUsingTypename: - case Decl::UnresolvedUsingValue: - case Decl::Using: - case Decl::UsingDirective: - case Decl::UsingShadow: - return CXLanguage_CPlusPlus; - } - - return CXLanguage_C; -} - -extern "C" { - -enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) { - if (clang_isDeclaration(cursor.kind)) - if (Decl *D = cxcursor::getCursorDecl(cursor)) { - if (D->hasAttr<UnavailableAttr>() || - (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())) - return CXAvailability_Available; - - if (D->hasAttr<DeprecatedAttr>()) - return CXAvailability_Deprecated; - } - - return CXAvailability_Available; -} - -CXLanguageKind clang_getCursorLanguage(CXCursor cursor) { - if (clang_isDeclaration(cursor.kind)) - return getDeclLanguage(cxcursor::getCursorDecl(cursor)); - - return CXLanguage_Invalid; -} -} // end: extern "C" - - -//===----------------------------------------------------------------------===// -// C++ AST instrospection. -//===----------------------------------------------------------------------===// - -extern "C" { -unsigned clang_CXXMethod_isStatic(CXCursor C) { - if (!clang_isDeclaration(C.kind)) - return 0; - - CXXMethodDecl *Method = 0; - Decl *D = cxcursor::getCursorDecl(C); - if (FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D)) - Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl()); - else - Method = dyn_cast_or_null<CXXMethodDecl>(D); - return (Method && Method->isStatic()) ? 1 : 0; -} - -} // end: extern "C" - -//===----------------------------------------------------------------------===// -// Attribute introspection. -//===----------------------------------------------------------------------===// - -extern "C" { -CXType clang_getIBOutletCollectionType(CXCursor C) { - if (C.kind != CXCursor_IBOutletCollectionAttr) - return cxtype::MakeCXType(QualType(), cxcursor::getCursorASTUnit(C)); - - IBOutletCollectionAttr *A = - cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C)); - - return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorASTUnit(C)); -} -} // end: extern "C" - -//===----------------------------------------------------------------------===// -// CXString Operations. -//===----------------------------------------------------------------------===// - -extern "C" { -const char *clang_getCString(CXString string) { - return string.Spelling; -} - -void clang_disposeString(CXString string) { - if (string.MustFreeString && string.Spelling) - free((void*)string.Spelling); -} - -} // end: extern "C" - -namespace clang { namespace cxstring { -CXString createCXString(const char *String, bool DupString){ - CXString Str; - if (DupString) { - Str.Spelling = strdup(String); - Str.MustFreeString = 1; - } else { - Str.Spelling = String; - Str.MustFreeString = 0; - } - return Str; -} - -CXString createCXString(llvm::StringRef String, bool DupString) { - CXString Result; - if (DupString || (!String.empty() && String.data()[String.size()] != 0)) { - char *Spelling = (char *)malloc(String.size() + 1); - memmove(Spelling, String.data(), String.size()); - Spelling[String.size()] = 0; - Result.Spelling = Spelling; - Result.MustFreeString = 1; - } else { - Result.Spelling = String.data(); - Result.MustFreeString = 0; - } - return Result; -} -}} - -//===----------------------------------------------------------------------===// -// Misc. utility functions. -//===----------------------------------------------------------------------===// - -extern "C" { - -CXString clang_getClangVersion() { - return createCXString(getClangFullVersion()); -} - -} // end: extern "C" diff --git a/contrib/llvm/tools/clang/tools/libclang/CIndexCXX.cpp b/contrib/llvm/tools/clang/tools/libclang/CIndexCXX.cpp deleted file mode 100644 index 3ade519..0000000 --- a/contrib/llvm/tools/clang/tools/libclang/CIndexCXX.cpp +++ /dev/null @@ -1,124 +0,0 @@ -//===- CIndexCXX.cpp - Clang-C Source Indexing Library --------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the libclang support for C++ cursors. -// -//===----------------------------------------------------------------------===// - -#include "CIndexer.h" -#include "CXCursor.h" -#include "CXType.h" -#include "clang/AST/DeclCXX.h" -#include "clang/AST/DeclTemplate.h" - -using namespace clang; -using namespace clang::cxstring; -using namespace clang::cxcursor; - -extern "C" { - -unsigned clang_isVirtualBase(CXCursor C) { - if (C.kind != CXCursor_CXXBaseSpecifier) - return 0; - - CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C); - return B->isVirtual(); -} - -enum CX_CXXAccessSpecifier clang_getCXXAccessSpecifier(CXCursor C) { - if (C.kind != CXCursor_CXXBaseSpecifier) - return CX_CXXInvalidAccessSpecifier; - - CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C); - switch (B->getAccessSpecifier()) { - case AS_public: return CX_CXXPublic; - case AS_protected: return CX_CXXProtected; - case AS_private: return CX_CXXPrivate; - case AS_none: return CX_CXXInvalidAccessSpecifier; - } - - // FIXME: Clang currently thinks this is reachable. - return CX_CXXInvalidAccessSpecifier; -} - -enum CXCursorKind clang_getTemplateCursorKind(CXCursor C) { - using namespace clang::cxcursor; - - switch (C.kind) { - case CXCursor_ClassTemplate: - case CXCursor_FunctionTemplate: - if (TemplateDecl *Template - = dyn_cast_or_null<TemplateDecl>(getCursorDecl(C))) - return MakeCXCursor(Template->getTemplatedDecl(), - getCursorASTUnit(C)).kind; - break; - - case CXCursor_ClassTemplatePartialSpecialization: - if (ClassTemplateSpecializationDecl *PartialSpec - = dyn_cast_or_null<ClassTemplatePartialSpecializationDecl>( - getCursorDecl(C))) { - switch (PartialSpec->getTagKind()) { - case TTK_Class: return CXCursor_ClassDecl; - case TTK_Struct: return CXCursor_StructDecl; - case TTK_Union: return CXCursor_UnionDecl; - case TTK_Enum: return CXCursor_NoDeclFound; - } - } - break; - - default: - break; - } - - return CXCursor_NoDeclFound; -} - -CXCursor clang_getSpecializedCursorTemplate(CXCursor C) { - if (!clang_isDeclaration(C.kind)) - return clang_getNullCursor(); - - Decl *D = getCursorDecl(C); - if (!D) - return clang_getNullCursor(); - - Decl *Template = 0; - if (CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) { - if (ClassTemplatePartialSpecializationDecl *PartialSpec - = dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord)) - Template = PartialSpec->getSpecializedTemplate(); - else if (ClassTemplateSpecializationDecl *ClassSpec - = dyn_cast<ClassTemplateSpecializationDecl>(CXXRecord)) { - llvm::PointerUnion<ClassTemplateDecl *, - ClassTemplatePartialSpecializationDecl *> Result - = ClassSpec->getSpecializedTemplateOrPartial(); - if (Result.is<ClassTemplateDecl *>()) - Template = Result.get<ClassTemplateDecl *>(); - else - Template = Result.get<ClassTemplatePartialSpecializationDecl *>(); - - } else - Template = CXXRecord->getInstantiatedFromMemberClass(); - } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) { - Template = Function->getPrimaryTemplate(); - if (!Template) - Template = Function->getInstantiatedFromMemberFunction(); - } else if (VarDecl *Var = dyn_cast<VarDecl>(D)) { - if (Var->isStaticDataMember()) - Template = Var->getInstantiatedFromStaticDataMember(); - } else if (RedeclarableTemplateDecl *Tmpl - = dyn_cast<RedeclarableTemplateDecl>(D)) - Template = Tmpl->getInstantiatedFromMemberTemplate(); - - if (!Template) - return clang_getNullCursor(); - - return MakeCXCursor(Template, getCursorASTUnit(C)); -} - -} // end extern "C" diff --git a/contrib/llvm/tools/clang/tools/libclang/CIndexCodeCompletion.cpp b/contrib/llvm/tools/clang/tools/libclang/CIndexCodeCompletion.cpp deleted file mode 100644 index d591c5d..0000000 --- a/contrib/llvm/tools/clang/tools/libclang/CIndexCodeCompletion.cpp +++ /dev/null @@ -1,822 +0,0 @@ -//===- CIndexCodeCompletion.cpp - Code Completion API hooks ---------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the Clang-C Source Indexing library hooks for -// code completion. -// -//===----------------------------------------------------------------------===// - -#include "CIndexer.h" -#include "CIndexDiagnostic.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Basic/FileManager.h" -#include "clang/Frontend/ASTUnit.h" -#include "clang/Frontend/CompilerInstance.h" -#include "clang/Frontend/FrontendDiagnostic.h" -#include "clang/Sema/CodeCompleteConsumer.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/Support/CrashRecoveryContext.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/Timer.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/System/Program.h" -#include <cstdlib> -#include <cstdio> - - -#ifdef UDP_CODE_COMPLETION_LOGGER -#include "clang/Basic/Version.h" -#include <arpa/inet.h> -#include <sys/socket.h> -#include <sys/types.h> -#include <unistd.h> -#endif - -using namespace clang; -using namespace clang::cxstring; - -namespace { - /// \brief Stored representation of a completion string. - /// - /// This is the representation behind a CXCompletionString. - class CXStoredCodeCompletionString : public CodeCompletionString { - unsigned Priority; - CXAvailabilityKind Availability; - - public: - CXStoredCodeCompletionString(unsigned Priority, - CXAvailabilityKind Availability) - : Priority(Priority), Availability(Availability) { } - - unsigned getPriority() const { return Priority; } - CXAvailabilityKind getAvailability() const { return Availability; } - }; -} - -extern "C" { - -enum CXCompletionChunkKind -clang_getCompletionChunkKind(CXCompletionString completion_string, - unsigned chunk_number) { - CXStoredCodeCompletionString *CCStr - = (CXStoredCodeCompletionString *)completion_string; - if (!CCStr || chunk_number >= CCStr->size()) - return CXCompletionChunk_Text; - - switch ((*CCStr)[chunk_number].Kind) { - case CodeCompletionString::CK_TypedText: - return CXCompletionChunk_TypedText; - case CodeCompletionString::CK_Text: - return CXCompletionChunk_Text; - case CodeCompletionString::CK_Optional: - return CXCompletionChunk_Optional; - case CodeCompletionString::CK_Placeholder: - return CXCompletionChunk_Placeholder; - case CodeCompletionString::CK_Informative: - return CXCompletionChunk_Informative; - case CodeCompletionString::CK_ResultType: - return CXCompletionChunk_ResultType; - case CodeCompletionString::CK_CurrentParameter: - return CXCompletionChunk_CurrentParameter; - case CodeCompletionString::CK_LeftParen: - return CXCompletionChunk_LeftParen; - case CodeCompletionString::CK_RightParen: - return CXCompletionChunk_RightParen; - case CodeCompletionString::CK_LeftBracket: - return CXCompletionChunk_LeftBracket; - case CodeCompletionString::CK_RightBracket: - return CXCompletionChunk_RightBracket; - case CodeCompletionString::CK_LeftBrace: - return CXCompletionChunk_LeftBrace; - case CodeCompletionString::CK_RightBrace: - return CXCompletionChunk_RightBrace; - case CodeCompletionString::CK_LeftAngle: - return CXCompletionChunk_LeftAngle; - case CodeCompletionString::CK_RightAngle: - return CXCompletionChunk_RightAngle; - case CodeCompletionString::CK_Comma: - return CXCompletionChunk_Comma; - case CodeCompletionString::CK_Colon: - return CXCompletionChunk_Colon; - case CodeCompletionString::CK_SemiColon: - return CXCompletionChunk_SemiColon; - case CodeCompletionString::CK_Equal: - return CXCompletionChunk_Equal; - case CodeCompletionString::CK_HorizontalSpace: - return CXCompletionChunk_HorizontalSpace; - case CodeCompletionString::CK_VerticalSpace: - return CXCompletionChunk_VerticalSpace; - } - - // Should be unreachable, but let's be careful. - return CXCompletionChunk_Text; -} - -CXString clang_getCompletionChunkText(CXCompletionString completion_string, - unsigned chunk_number) { - CXStoredCodeCompletionString *CCStr - = (CXStoredCodeCompletionString *)completion_string; - if (!CCStr || chunk_number >= CCStr->size()) - return createCXString(0); - - switch ((*CCStr)[chunk_number].Kind) { - case CodeCompletionString::CK_TypedText: - case CodeCompletionString::CK_Text: - case CodeCompletionString::CK_Placeholder: - case CodeCompletionString::CK_CurrentParameter: - case CodeCompletionString::CK_Informative: - case CodeCompletionString::CK_LeftParen: - case CodeCompletionString::CK_RightParen: - case CodeCompletionString::CK_LeftBracket: - case CodeCompletionString::CK_RightBracket: - case CodeCompletionString::CK_LeftBrace: - case CodeCompletionString::CK_RightBrace: - case CodeCompletionString::CK_LeftAngle: - case CodeCompletionString::CK_RightAngle: - case CodeCompletionString::CK_Comma: - case CodeCompletionString::CK_ResultType: - case CodeCompletionString::CK_Colon: - case CodeCompletionString::CK_SemiColon: - case CodeCompletionString::CK_Equal: - case CodeCompletionString::CK_HorizontalSpace: - return createCXString((*CCStr)[chunk_number].Text, false); - - case CodeCompletionString::CK_VerticalSpace: - // FIXME: Temporary hack until we figure out how to handle vertical space. - return createCXString(" "); - - case CodeCompletionString::CK_Optional: - // Note: treated as an empty text block. - return createCXString(""); - } - - // Should be unreachable, but let's be careful. - return createCXString(0); -} - - -CXCompletionString -clang_getCompletionChunkCompletionString(CXCompletionString completion_string, - unsigned chunk_number) { - CXStoredCodeCompletionString *CCStr - = (CXStoredCodeCompletionString *)completion_string; - if (!CCStr || chunk_number >= CCStr->size()) - return 0; - - switch ((*CCStr)[chunk_number].Kind) { - case CodeCompletionString::CK_TypedText: - case CodeCompletionString::CK_Text: - case CodeCompletionString::CK_Placeholder: - case CodeCompletionString::CK_CurrentParameter: - case CodeCompletionString::CK_Informative: - case CodeCompletionString::CK_LeftParen: - case CodeCompletionString::CK_RightParen: - case CodeCompletionString::CK_LeftBracket: - case CodeCompletionString::CK_RightBracket: - case CodeCompletionString::CK_LeftBrace: - case CodeCompletionString::CK_RightBrace: - case CodeCompletionString::CK_LeftAngle: - case CodeCompletionString::CK_RightAngle: - case CodeCompletionString::CK_Comma: - case CodeCompletionString::CK_ResultType: - case CodeCompletionString::CK_Colon: - case CodeCompletionString::CK_SemiColon: - case CodeCompletionString::CK_Equal: - case CodeCompletionString::CK_HorizontalSpace: - case CodeCompletionString::CK_VerticalSpace: - return 0; - - case CodeCompletionString::CK_Optional: - // Note: treated as an empty text block. - return (*CCStr)[chunk_number].Optional; - } - - // Should be unreachable, but let's be careful. - return 0; -} - -unsigned clang_getNumCompletionChunks(CXCompletionString completion_string) { - CXStoredCodeCompletionString *CCStr - = (CXStoredCodeCompletionString *)completion_string; - return CCStr? CCStr->size() : 0; -} - -unsigned clang_getCompletionPriority(CXCompletionString completion_string) { - CXStoredCodeCompletionString *CCStr - = (CXStoredCodeCompletionString *)completion_string; - return CCStr? CCStr->getPriority() : unsigned(CCP_Unlikely); -} - -enum CXAvailabilityKind -clang_getCompletionAvailability(CXCompletionString completion_string) { - CXStoredCodeCompletionString *CCStr - = (CXStoredCodeCompletionString *)completion_string; - return CCStr? CCStr->getAvailability() : CXAvailability_Available; -} - -static bool ReadUnsigned(const char *&Memory, const char *MemoryEnd, - unsigned &Value) { - if (Memory + sizeof(unsigned) > MemoryEnd) - return true; - - memmove(&Value, Memory, sizeof(unsigned)); - Memory += sizeof(unsigned); - return false; -} - -/// \brief The CXCodeCompleteResults structure we allocate internally; -/// the client only sees the initial CXCodeCompleteResults structure. -struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults { - AllocatedCXCodeCompleteResults(); - ~AllocatedCXCodeCompleteResults(); - - /// \brief Diagnostics produced while performing code completion. - llvm::SmallVector<StoredDiagnostic, 8> Diagnostics; - - /// \brief Diag object - llvm::IntrusiveRefCntPtr<Diagnostic> Diag; - - /// \brief Language options used to adjust source locations. - LangOptions LangOpts; - - /// \brief Source manager, used for diagnostics. - SourceManager SourceMgr; - - /// \brief File manager, used for diagnostics. - FileManager FileMgr; - - /// \brief Temporary files that should be removed once we have finished - /// with the code-completion results. - std::vector<llvm::sys::Path> TemporaryFiles; - - /// \brief Temporary buffers that will be deleted once we have finished with the code-completion results. - llvm::SmallVector<const llvm::MemoryBuffer *, 1> TemporaryBuffers; -}; - -AllocatedCXCodeCompleteResults::AllocatedCXCodeCompleteResults() - : CXCodeCompleteResults(), Diag(new Diagnostic), SourceMgr(*Diag) { } - -AllocatedCXCodeCompleteResults::~AllocatedCXCodeCompleteResults() { - for (unsigned I = 0, N = NumResults; I != N; ++I) - delete (CXStoredCodeCompletionString *)Results[I].CompletionString; - delete [] Results; - - for (unsigned I = 0, N = TemporaryFiles.size(); I != N; ++I) - TemporaryFiles[I].eraseFromDisk(); - for (unsigned I = 0, N = TemporaryBuffers.size(); I != N; ++I) - delete TemporaryBuffers[I]; -} - -CXCodeCompleteResults *clang_codeComplete(CXIndex CIdx, - const char *source_filename, - int num_command_line_args, - const char * const *command_line_args, - unsigned num_unsaved_files, - struct CXUnsavedFile *unsaved_files, - const char *complete_filename, - unsigned complete_line, - unsigned complete_column) { -#ifdef UDP_CODE_COMPLETION_LOGGER -#ifdef UDP_CODE_COMPLETION_LOGGER_PORT - const llvm::TimeRecord &StartTime = llvm::TimeRecord::getCurrentTime(); -#endif -#endif - - bool EnableLogging = getenv("LIBCLANG_CODE_COMPLETION_LOGGING") != 0; - - llvm::OwningPtr<llvm::NamedRegionTimer> CCTimer; - if (getenv("LIBCLANG_TIMING")) { - llvm::SmallString<128> TimerName; - llvm::raw_svector_ostream TimerNameOut(TimerName); - TimerNameOut << "Code completion (out-of-process) @ " << complete_filename - << ":" << complete_line << ":" << complete_column; - CCTimer.reset(new llvm::NamedRegionTimer(TimerNameOut.str())); - } - - // The indexer, which is mainly used to determine where diagnostics go. - CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx); - - // Configure the diagnostics. - DiagnosticOptions DiagOpts; - llvm::IntrusiveRefCntPtr<Diagnostic> Diags; - Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0); - - // The set of temporary files that we've built. - std::vector<llvm::sys::Path> TemporaryFiles; - - // Build up the arguments for invoking 'clang'. - std::vector<const char *> argv; - - // First add the complete path to the 'clang' executable. - llvm::sys::Path ClangPath = CXXIdx->getClangPath(); - argv.push_back(ClangPath.c_str()); - - // Always use Clang C++ support. - argv.push_back("-ccc-clang-cxx"); - - // Add the '-fsyntax-only' argument so that we only perform a basic - // syntax check of the code. - argv.push_back("-fsyntax-only"); - - // Add the appropriate '-code-completion-at=file:line:column' argument - // to perform code completion, with an "-Xclang" preceding it. - std::string code_complete_at; - code_complete_at += complete_filename; - code_complete_at += ":"; - code_complete_at += llvm::utostr(complete_line); - code_complete_at += ":"; - code_complete_at += llvm::utostr(complete_column); - argv.push_back("-Xclang"); - argv.push_back("-code-completion-at"); - argv.push_back("-Xclang"); - argv.push_back(code_complete_at.c_str()); - argv.push_back("-Xclang"); - argv.push_back("-no-code-completion-debug-printer"); - argv.push_back("-Xclang"); - argv.push_back("-code-completion-macros"); - argv.push_back("-fdiagnostics-binary"); - - // Remap any unsaved files to temporary files. - std::vector<std::string> RemapArgs; - if (RemapFiles(num_unsaved_files, unsaved_files, RemapArgs, TemporaryFiles)) - return 0; - - // The pointers into the elements of RemapArgs are stable because we - // won't be adding anything to RemapArgs after this point. - for (unsigned i = 0, e = RemapArgs.size(); i != e; ++i) - argv.push_back(RemapArgs[i].c_str()); - - // Add the source file name (FIXME: later, we'll want to build temporary - // file from the buffer, or just feed the source text via standard input). - if (source_filename) - argv.push_back(source_filename); - - // Process the compiler options, stripping off '-o', '-c', '-fsyntax-only'. - for (int i = 0; i < num_command_line_args; ++i) - if (const char *arg = command_line_args[i]) { - if (strcmp(arg, "-o") == 0) { - ++i; // Also skip the matching argument. - continue; - } - if (strcmp(arg, "-emit-ast") == 0 || - strcmp(arg, "-c") == 0 || - strcmp(arg, "-fsyntax-only") == 0) { - continue; - } - - // Keep the argument. - argv.push_back(arg); - } - - if (EnableLogging) { - std::string Log = ClangPath.str(); - for (unsigned I = 0, N = argv.size(); I != N; ++I) { - Log += ' '; - Log += argv[I]; - } - fprintf(stderr, "libclang (Code Completion): %s\n", Log.c_str()); - } - - // Add the null terminator. - argv.push_back(NULL); - - // Generate a temporary name for the code-completion results file. - char tmpFile[L_tmpnam]; - char *tmpFileName = tmpnam(tmpFile); - llvm::sys::Path ResultsFile(tmpFileName); - TemporaryFiles.push_back(ResultsFile); - - // Generate a temporary name for the diagnostics file. - char tmpFileResults[L_tmpnam]; - char *tmpResultsFileName = tmpnam(tmpFileResults); - llvm::sys::Path DiagnosticsFile(tmpResultsFileName); - TemporaryFiles.push_back(DiagnosticsFile); - - - - // Invoke 'clang'. - llvm::sys::Path DevNull; // leave empty, causes redirection to /dev/null - // on Unix or NUL (Windows). - std::string ErrMsg; - const llvm::sys::Path *Redirects[] = { &DevNull, &ResultsFile, - &DiagnosticsFile, 0 }; - llvm::sys::Program::ExecuteAndWait(ClangPath, &argv[0], /* env */ NULL, - /* redirects */ &Redirects[0], - /* secondsToWait */ 0, - /* memoryLimits */ 0, &ErrMsg); - - if (!ErrMsg.empty()) { - std::string AllArgs; - for (std::vector<const char*>::iterator I = argv.begin(), E = argv.end(); - I != E; ++I) { - AllArgs += ' '; - if (*I) - AllArgs += *I; - } - - Diags->Report(diag::err_fe_invoking) << AllArgs << ErrMsg; - } - - // Parse the resulting source file to find code-completion results. - using llvm::MemoryBuffer; - using llvm::StringRef; - AllocatedCXCodeCompleteResults *Results = new AllocatedCXCodeCompleteResults; - Results->Results = 0; - Results->NumResults = 0; - // FIXME: Set Results->LangOpts! - if (MemoryBuffer *F = MemoryBuffer::getFile(ResultsFile.c_str())) { - llvm::SmallVector<CXCompletionResult, 4> CompletionResults; - StringRef Buffer = F->getBuffer(); - for (const char *Str = Buffer.data(), *StrEnd = Str + Buffer.size(); - Str < StrEnd;) { - unsigned KindValue; - if (ReadUnsigned(Str, StrEnd, KindValue)) - break; - - unsigned Priority; - if (ReadUnsigned(Str, StrEnd, Priority)) - break; - - unsigned Availability; - if (ReadUnsigned(Str, StrEnd, Availability)) - break; - - CXStoredCodeCompletionString *CCStr - = new CXStoredCodeCompletionString(Priority, - (CXAvailabilityKind)Availability); - if (!CCStr->Deserialize(Str, StrEnd)) { - delete CCStr; - continue; - } - - if (!CCStr->empty()) { - // Vend the code-completion result to the caller. - CXCompletionResult Result; - Result.CursorKind = (CXCursorKind)KindValue; - Result.CompletionString = CCStr; - CompletionResults.push_back(Result); - } - }; - - // Allocate the results. - Results->Results = new CXCompletionResult [CompletionResults.size()]; - Results->NumResults = CompletionResults.size(); - memcpy(Results->Results, CompletionResults.data(), - CompletionResults.size() * sizeof(CXCompletionResult)); - Results->TemporaryBuffers.push_back(F); - } - - LoadSerializedDiagnostics(DiagnosticsFile, num_unsaved_files, unsaved_files, - Results->FileMgr, Results->SourceMgr, - Results->Diagnostics); - - // Make sure we delete temporary files when the code-completion results are - // destroyed. - Results->TemporaryFiles.swap(TemporaryFiles); - -#ifdef UDP_CODE_COMPLETION_LOGGER -#ifdef UDP_CODE_COMPLETION_LOGGER_PORT - const llvm::TimeRecord &EndTime = llvm::TimeRecord::getCurrentTime(); - llvm::SmallString<256> LogResult; - llvm::raw_svector_ostream os(LogResult); - - // Figure out the language and whether or not it uses PCH. - const char *lang = 0; - bool usesPCH = false; - - for (std::vector<const char*>::iterator I = argv.begin(), E = argv.end(); - I != E; ++I) { - if (*I == 0) - continue; - if (strcmp(*I, "-x") == 0) { - if (I + 1 != E) { - lang = *(++I); - continue; - } - } - else if (strcmp(*I, "-include") == 0) { - if (I+1 != E) { - const char *arg = *(++I); - llvm::SmallString<512> pchName; - { - llvm::raw_svector_ostream os(pchName); - os << arg << ".pth"; - } - pchName.push_back('\0'); - struct stat stat_results; - if (stat(pchName.data(), &stat_results) == 0) - usesPCH = true; - continue; - } - } - } - - os << "{ "; - os << "\"wall\": " << (EndTime.getWallTime() - StartTime.getWallTime()); - os << ", \"numRes\": " << Results->NumResults; - os << ", \"diags\": " << Results->Diagnostics.size(); - os << ", \"pch\": " << (usesPCH ? "true" : "false"); - os << ", \"lang\": \"" << (lang ? lang : "<unknown>") << '"'; - const char *name = getlogin(); - os << ", \"user\": \"" << (name ? name : "unknown") << '"'; - os << ", \"clangVer\": \"" << getClangFullVersion() << '"'; - os << " }"; - - llvm::StringRef res = os.str(); - if (res.size() > 0) { - do { - // Setup the UDP socket. - struct sockaddr_in servaddr; - bzero(&servaddr, sizeof(servaddr)); - servaddr.sin_family = AF_INET; - servaddr.sin_port = htons(UDP_CODE_COMPLETION_LOGGER_PORT); - if (inet_pton(AF_INET, UDP_CODE_COMPLETION_LOGGER, - &servaddr.sin_addr) <= 0) - break; - - int sockfd = socket(AF_INET, SOCK_DGRAM, 0); - if (sockfd < 0) - break; - - sendto(sockfd, res.data(), res.size(), 0, - (struct sockaddr *)&servaddr, sizeof(servaddr)); - close(sockfd); - } - while (false); - } -#endif -#endif - clang_sortCodeCompletionResults(Results->Results, Results->NumResults); - return Results; -} - -} // end extern "C" - -namespace { - class CaptureCompletionResults : public CodeCompleteConsumer { - AllocatedCXCodeCompleteResults &AllocatedResults; - - public: - explicit CaptureCompletionResults(AllocatedCXCodeCompleteResults &Results) - : CodeCompleteConsumer(true, false, true, false), - AllocatedResults(Results) { } - - virtual void ProcessCodeCompleteResults(Sema &S, - CodeCompletionContext Context, - CodeCompletionResult *Results, - unsigned NumResults) { - AllocatedResults.Results = new CXCompletionResult [NumResults]; - AllocatedResults.NumResults = NumResults; - for (unsigned I = 0; I != NumResults; ++I) { - CXStoredCodeCompletionString *StoredCompletion - = new CXStoredCodeCompletionString(Results[I].Priority, - Results[I].Availability); - (void)Results[I].CreateCodeCompletionString(S, StoredCompletion); - AllocatedResults.Results[I].CursorKind = Results[I].CursorKind; - AllocatedResults.Results[I].CompletionString = StoredCompletion; - } - } - - // FIXME: Add ProcessOverloadCandidates? - }; -} - -extern "C" { -struct CodeCompleteAtInfo { - CXTranslationUnit TU; - const char *complete_filename; - unsigned complete_line; - unsigned complete_column; - struct CXUnsavedFile *unsaved_files; - unsigned num_unsaved_files; - unsigned options; - CXCodeCompleteResults *result; -}; -void clang_codeCompleteAt_Impl(void *UserData) { - CodeCompleteAtInfo *CCAI = static_cast<CodeCompleteAtInfo*>(UserData); - CXTranslationUnit TU = CCAI->TU; - const char *complete_filename = CCAI->complete_filename; - unsigned complete_line = CCAI->complete_line; - unsigned complete_column = CCAI->complete_column; - struct CXUnsavedFile *unsaved_files = CCAI->unsaved_files; - unsigned num_unsaved_files = CCAI->num_unsaved_files; - unsigned options = CCAI->options; - CCAI->result = 0; - -#ifdef UDP_CODE_COMPLETION_LOGGER -#ifdef UDP_CODE_COMPLETION_LOGGER_PORT - const llvm::TimeRecord &StartTime = llvm::TimeRecord::getCurrentTime(); -#endif -#endif - - bool EnableLogging = getenv("LIBCLANG_CODE_COMPLETION_LOGGING") != 0; - - ASTUnit *AST = static_cast<ASTUnit *>(TU); - if (!AST) - return; - - // Perform the remapping of source files. - llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles; - for (unsigned I = 0; I != num_unsaved_files; ++I) { - llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length); - const llvm::MemoryBuffer *Buffer - = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename); - RemappedFiles.push_back(std::make_pair(unsaved_files[I].Filename, - Buffer)); - } - - if (EnableLogging) { - // FIXME: Add logging. - } - - // Parse the resulting source file to find code-completion results. - AllocatedCXCodeCompleteResults *Results = new AllocatedCXCodeCompleteResults; - Results->Results = 0; - Results->NumResults = 0; - - // Create a code-completion consumer to capture the results. - CaptureCompletionResults Capture(*Results); - - // Perform completion. - AST->CodeComplete(complete_filename, complete_line, complete_column, - RemappedFiles.data(), RemappedFiles.size(), - (options & CXCodeComplete_IncludeMacros), - (options & CXCodeComplete_IncludeCodePatterns), - Capture, - *Results->Diag, Results->LangOpts, Results->SourceMgr, - Results->FileMgr, Results->Diagnostics, - Results->TemporaryBuffers); - - - -#ifdef UDP_CODE_COMPLETION_LOGGER -#ifdef UDP_CODE_COMPLETION_LOGGER_PORT - const llvm::TimeRecord &EndTime = llvm::TimeRecord::getCurrentTime(); - llvm::SmallString<256> LogResult; - llvm::raw_svector_ostream os(LogResult); - - // Figure out the language and whether or not it uses PCH. - const char *lang = 0; - bool usesPCH = false; - - for (std::vector<const char*>::iterator I = argv.begin(), E = argv.end(); - I != E; ++I) { - if (*I == 0) - continue; - if (strcmp(*I, "-x") == 0) { - if (I + 1 != E) { - lang = *(++I); - continue; - } - } - else if (strcmp(*I, "-include") == 0) { - if (I+1 != E) { - const char *arg = *(++I); - llvm::SmallString<512> pchName; - { - llvm::raw_svector_ostream os(pchName); - os << arg << ".pth"; - } - pchName.push_back('\0'); - struct stat stat_results; - if (stat(pchName.data(), &stat_results) == 0) - usesPCH = true; - continue; - } - } - } - - os << "{ "; - os << "\"wall\": " << (EndTime.getWallTime() - StartTime.getWallTime()); - os << ", \"numRes\": " << Results->NumResults; - os << ", \"diags\": " << Results->Diagnostics.size(); - os << ", \"pch\": " << (usesPCH ? "true" : "false"); - os << ", \"lang\": \"" << (lang ? lang : "<unknown>") << '"'; - const char *name = getlogin(); - os << ", \"user\": \"" << (name ? name : "unknown") << '"'; - os << ", \"clangVer\": \"" << getClangFullVersion() << '"'; - os << " }"; - - llvm::StringRef res = os.str(); - if (res.size() > 0) { - do { - // Setup the UDP socket. - struct sockaddr_in servaddr; - bzero(&servaddr, sizeof(servaddr)); - servaddr.sin_family = AF_INET; - servaddr.sin_port = htons(UDP_CODE_COMPLETION_LOGGER_PORT); - if (inet_pton(AF_INET, UDP_CODE_COMPLETION_LOGGER, - &servaddr.sin_addr) <= 0) - break; - - int sockfd = socket(AF_INET, SOCK_DGRAM, 0); - if (sockfd < 0) - break; - - sendto(sockfd, res.data(), res.size(), 0, - (struct sockaddr *)&servaddr, sizeof(servaddr)); - close(sockfd); - } - while (false); - } -#endif -#endif - CCAI->result = Results; -} -CXCodeCompleteResults *clang_codeCompleteAt(CXTranslationUnit TU, - const char *complete_filename, - unsigned complete_line, - unsigned complete_column, - struct CXUnsavedFile *unsaved_files, - unsigned num_unsaved_files, - unsigned options) { - CodeCompleteAtInfo CCAI = { TU, complete_filename, complete_line, - complete_column, unsaved_files, num_unsaved_files, - options, 0 }; - llvm::CrashRecoveryContext CRC; - - if (!CRC.RunSafely(clang_codeCompleteAt_Impl, &CCAI)) { - fprintf(stderr, "libclang: crash detected in code completion\n"); - static_cast<ASTUnit *>(TU)->setUnsafeToFree(true); - return 0; - } - - return CCAI.result; -} - -unsigned clang_defaultCodeCompleteOptions(void) { - return CXCodeComplete_IncludeMacros; -} - -void clang_disposeCodeCompleteResults(CXCodeCompleteResults *ResultsIn) { - if (!ResultsIn) - return; - - AllocatedCXCodeCompleteResults *Results - = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn); - delete Results; -} - -unsigned -clang_codeCompleteGetNumDiagnostics(CXCodeCompleteResults *ResultsIn) { - AllocatedCXCodeCompleteResults *Results - = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn); - if (!Results) - return 0; - - return Results->Diagnostics.size(); -} - -CXDiagnostic -clang_codeCompleteGetDiagnostic(CXCodeCompleteResults *ResultsIn, - unsigned Index) { - AllocatedCXCodeCompleteResults *Results - = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn); - if (!Results || Index >= Results->Diagnostics.size()) - return 0; - - return new CXStoredDiagnostic(Results->Diagnostics[Index], Results->LangOpts); -} - - -} // end extern "C" - -namespace { - struct OrderCompletionResults { - bool operator()(const CXCompletionResult &XR, - const CXCompletionResult &YR) const { - CXStoredCodeCompletionString *X - = (CXStoredCodeCompletionString *)XR.CompletionString; - CXStoredCodeCompletionString *Y - = (CXStoredCodeCompletionString *)YR.CompletionString; - - const char *XText = X->getTypedText(); - const char *YText = Y->getTypedText(); - if (!XText || !YText) - return XText != 0; - - int result = llvm::StringRef(XText).compare_lower(YText); - if (result < 0) - return true; - if (result > 0) - return false; - - result = llvm::StringRef(XText).compare(YText); - return result; - } - }; -} - -extern "C" { - void clang_sortCodeCompletionResults(CXCompletionResult *Results, - unsigned NumResults) { - std::stable_sort(Results, Results + NumResults, OrderCompletionResults()); - } -} diff --git a/contrib/llvm/tools/clang/tools/libclang/CIndexDiagnostic.cpp b/contrib/llvm/tools/clang/tools/libclang/CIndexDiagnostic.cpp deleted file mode 100644 index 531992e..0000000 --- a/contrib/llvm/tools/clang/tools/libclang/CIndexDiagnostic.cpp +++ /dev/null @@ -1,272 +0,0 @@ -/*===-- CIndexDiagnostics.cpp - Diagnostics C Interface ---------*- C++ -*-===*\ -|* *| -|* The LLVM Compiler Infrastructure *| -|* *| -|* This file is distributed under the University of Illinois Open Source *| -|* License. See LICENSE.TXT for details. *| -|* *| -|*===----------------------------------------------------------------------===*| -|* *| -|* Implements the diagnostic functions of the Clang C interface. *| -|* *| -\*===----------------------------------------------------------------------===*/ -#include "CIndexDiagnostic.h" -#include "CIndexer.h" -#include "CXSourceLocation.h" - -#include "clang/Frontend/ASTUnit.h" -#include "clang/Frontend/FrontendDiagnostic.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/Twine.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/raw_ostream.h" - -using namespace clang; -using namespace clang::cxloc; -using namespace clang::cxstring; -using namespace llvm; - -//----------------------------------------------------------------------------- -// C Interface Routines -//----------------------------------------------------------------------------- -extern "C" { - -unsigned clang_getNumDiagnostics(CXTranslationUnit Unit) { - ASTUnit *CXXUnit = static_cast<ASTUnit *>(Unit); - return CXXUnit? CXXUnit->stored_diag_size() : 0; -} - -CXDiagnostic clang_getDiagnostic(CXTranslationUnit Unit, unsigned Index) { - ASTUnit *CXXUnit = static_cast<ASTUnit *>(Unit); - if (!CXXUnit || Index >= CXXUnit->stored_diag_size()) - return 0; - - return new CXStoredDiagnostic(CXXUnit->stored_diag_begin()[Index], - CXXUnit->getASTContext().getLangOptions()); -} - -void clang_disposeDiagnostic(CXDiagnostic Diagnostic) { - CXStoredDiagnostic *Stored = static_cast<CXStoredDiagnostic *>(Diagnostic); - delete Stored; -} - -CXString clang_formatDiagnostic(CXDiagnostic Diagnostic, unsigned Options) { - if (!Diagnostic) - return createCXString(""); - - CXDiagnosticSeverity Severity = clang_getDiagnosticSeverity(Diagnostic); - - // Ignore diagnostics that should be ignored. - if (Severity == CXDiagnostic_Ignored) - return createCXString(""); - - llvm::SmallString<256> Str; - llvm::raw_svector_ostream Out(Str); - - if (Options & CXDiagnostic_DisplaySourceLocation) { - // Print source location (file:line), along with optional column - // and source ranges. - CXFile File; - unsigned Line, Column; - clang_getInstantiationLocation(clang_getDiagnosticLocation(Diagnostic), - &File, &Line, &Column, 0); - if (File) { - CXString FName = clang_getFileName(File); - Out << clang_getCString(FName) << ":" << Line << ":"; - clang_disposeString(FName); - if (Options & CXDiagnostic_DisplayColumn) - Out << Column << ":"; - - if (Options & CXDiagnostic_DisplaySourceRanges) { - unsigned N = clang_getDiagnosticNumRanges(Diagnostic); - bool PrintedRange = false; - for (unsigned I = 0; I != N; ++I) { - CXFile StartFile, EndFile; - CXSourceRange Range = clang_getDiagnosticRange(Diagnostic, I); - - unsigned StartLine, StartColumn, EndLine, EndColumn; - clang_getInstantiationLocation(clang_getRangeStart(Range), - &StartFile, &StartLine, &StartColumn, - 0); - clang_getInstantiationLocation(clang_getRangeEnd(Range), - &EndFile, &EndLine, &EndColumn, 0); - - if (StartFile != EndFile || StartFile != File) - continue; - - Out << "{" << StartLine << ":" << StartColumn << "-" - << EndLine << ":" << EndColumn << "}"; - PrintedRange = true; - } - if (PrintedRange) - Out << ":"; - } - } - - Out << " "; - } - - /* Print warning/error/etc. */ - switch (Severity) { - case CXDiagnostic_Ignored: assert(0 && "impossible"); break; - case CXDiagnostic_Note: Out << "note: "; break; - case CXDiagnostic_Warning: Out << "warning: "; break; - case CXDiagnostic_Error: Out << "error: "; break; - case CXDiagnostic_Fatal: Out << "fatal error: "; break; - } - - CXString Text = clang_getDiagnosticSpelling(Diagnostic); - if (clang_getCString(Text)) - Out << clang_getCString(Text); - else - Out << "<no diagnostic text>"; - clang_disposeString(Text); - return createCXString(Out.str(), true); -} - -unsigned clang_defaultDiagnosticDisplayOptions() { - return CXDiagnostic_DisplaySourceLocation | CXDiagnostic_DisplayColumn; -} - -enum CXDiagnosticSeverity clang_getDiagnosticSeverity(CXDiagnostic Diag) { - CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag); - if (!StoredDiag) - return CXDiagnostic_Ignored; - - switch (StoredDiag->Diag.getLevel()) { - case Diagnostic::Ignored: return CXDiagnostic_Ignored; - case Diagnostic::Note: return CXDiagnostic_Note; - case Diagnostic::Warning: return CXDiagnostic_Warning; - case Diagnostic::Error: return CXDiagnostic_Error; - case Diagnostic::Fatal: return CXDiagnostic_Fatal; - } - - llvm_unreachable("Invalid diagnostic level"); - return CXDiagnostic_Ignored; -} - -CXSourceLocation clang_getDiagnosticLocation(CXDiagnostic Diag) { - CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag); - if (!StoredDiag || StoredDiag->Diag.getLocation().isInvalid()) - return clang_getNullLocation(); - - return translateSourceLocation(StoredDiag->Diag.getLocation().getManager(), - StoredDiag->LangOpts, - StoredDiag->Diag.getLocation()); -} - -CXString clang_getDiagnosticSpelling(CXDiagnostic Diag) { - CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag); - if (!StoredDiag) - return createCXString(""); - - return createCXString(StoredDiag->Diag.getMessage(), false); -} - -unsigned clang_getDiagnosticNumRanges(CXDiagnostic Diag) { - CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag); - if (!StoredDiag || StoredDiag->Diag.getLocation().isInvalid()) - return 0; - - return StoredDiag->Diag.range_size(); -} - -CXSourceRange clang_getDiagnosticRange(CXDiagnostic Diag, unsigned Range) { - CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag); - if (!StoredDiag || Range >= StoredDiag->Diag.range_size() || - StoredDiag->Diag.getLocation().isInvalid()) - return clang_getNullRange(); - - return translateSourceRange(StoredDiag->Diag.getLocation().getManager(), - StoredDiag->LangOpts, - StoredDiag->Diag.range_begin()[Range]); -} - -unsigned clang_getDiagnosticNumFixIts(CXDiagnostic Diag) { - CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag); - if (!StoredDiag) - return 0; - - return StoredDiag->Diag.fixit_size(); -} - -CXString clang_getDiagnosticFixIt(CXDiagnostic Diagnostic, unsigned FixIt, - CXSourceRange *ReplacementRange) { - CXStoredDiagnostic *StoredDiag - = static_cast<CXStoredDiagnostic *>(Diagnostic); - if (!StoredDiag || FixIt >= StoredDiag->Diag.fixit_size() || - StoredDiag->Diag.getLocation().isInvalid()) { - if (ReplacementRange) - *ReplacementRange = clang_getNullRange(); - - return createCXString(""); - } - - const FixItHint &Hint = StoredDiag->Diag.fixit_begin()[FixIt]; - if (ReplacementRange) { - // Create a range that covers the entire replacement (or - // removal) range, adjusting the end of the range to point to - // the end of the token. - *ReplacementRange - = translateSourceRange(StoredDiag->Diag.getLocation().getManager(), - StoredDiag->LangOpts, - Hint.RemoveRange); - } - - return createCXString(Hint.CodeToInsert); -} - -} // end extern "C" - -void clang::LoadSerializedDiagnostics(const llvm::sys::Path &DiagnosticsPath, - unsigned num_unsaved_files, - struct CXUnsavedFile *unsaved_files, - FileManager &FileMgr, - SourceManager &SourceMgr, - SmallVectorImpl<StoredDiagnostic> &Diags) { - using llvm::MemoryBuffer; - using llvm::StringRef; - MemoryBuffer *F = MemoryBuffer::getFile(DiagnosticsPath.c_str()); - if (!F) - return; - - // Enter the unsaved files into the file manager. - for (unsigned I = 0; I != num_unsaved_files; ++I) { - const FileEntry *File = FileMgr.getVirtualFile(unsaved_files[I].Filename, - unsaved_files[I].Length, - 0); - if (!File) { - // FIXME: Hard to localize when we have no diagnostics engine! - Diags.push_back(StoredDiagnostic(Diagnostic::Fatal, - (Twine("could not remap from missing file ") + - unsaved_files[I].Filename).str())); - delete F; - return; - } - - MemoryBuffer *Buffer - = MemoryBuffer::getMemBuffer(unsaved_files[I].Contents, - unsaved_files[I].Contents + unsaved_files[I].Length); - if (!Buffer) { - delete F; - return; - } - - SourceMgr.overrideFileContents(File, Buffer); - SourceMgr.createFileID(File, SourceLocation(), SrcMgr::C_User); - } - - // Parse the diagnostics, emitting them one by one until we've - // exhausted the data. - StringRef Buffer = F->getBuffer(); - const char *Memory = Buffer.data(), *MemoryEnd = Memory + Buffer.size(); - while (Memory != MemoryEnd) { - StoredDiagnostic Stored = StoredDiagnostic::Deserialize(FileMgr, SourceMgr, - Memory, MemoryEnd); - if (!Stored) - break; - - Diags.push_back(Stored); - } - delete F; -} diff --git a/contrib/llvm/tools/clang/tools/libclang/CIndexDiagnostic.h b/contrib/llvm/tools/clang/tools/libclang/CIndexDiagnostic.h deleted file mode 100644 index 919c21c..0000000 --- a/contrib/llvm/tools/clang/tools/libclang/CIndexDiagnostic.h +++ /dev/null @@ -1,53 +0,0 @@ -/*===-- CIndexDiagnostic.h - Diagnostics C Interface ------------*- C++ -*-===*\ -|* *| -|* The LLVM Compiler Infrastructure *| -|* *| -|* This file is distributed under the University of Illinois Open Source *| -|* License. See LICENSE.TXT for details. *| -|* *| -|*===----------------------------------------------------------------------===*| -|* *| -|* Implements the diagnostic functions of the Clang C interface. *| -|* *| -\*===----------------------------------------------------------------------===*/ -#ifndef LLVM_CLANG_CINDEX_DIAGNOSTIC_H -#define LLVM_CLANG_CINDEX_DIAGNOSTIC_H - -struct CXUnsavedFile; - -namespace llvm { -template<typename T> class SmallVectorImpl; -namespace sys { class Path; } -} - -namespace clang { - -class Diagnostic; -class FileManager; -class LangOptions; -class Preprocessor; -class StoredDiagnostic; -class SourceManager; - -/// \brief The storage behind a CXDiagnostic -struct CXStoredDiagnostic { - const StoredDiagnostic &Diag; - const LangOptions &LangOpts; - - CXStoredDiagnostic(const StoredDiagnostic &Diag, - const LangOptions &LangOpts) - : Diag(Diag), LangOpts(LangOpts) { } -}; - -/// \brief Given the path to a file that contains binary, serialized -/// diagnostics produced by Clang, load those diagnostics. -void LoadSerializedDiagnostics(const llvm::sys::Path &DiagnosticsPath, - unsigned num_unsaved_files, - struct CXUnsavedFile *unsaved_files, - FileManager &FileMgr, - SourceManager &SourceMgr, - llvm::SmallVectorImpl<StoredDiagnostic> &Diags); - -} // end namespace clang - -#endif // LLVM_CLANG_CINDEX_DIAGNOSTIC_H diff --git a/contrib/llvm/tools/clang/tools/libclang/CIndexInclusionStack.cpp b/contrib/llvm/tools/clang/tools/libclang/CIndexInclusionStack.cpp deleted file mode 100644 index e863239..0000000 --- a/contrib/llvm/tools/clang/tools/libclang/CIndexInclusionStack.cpp +++ /dev/null @@ -1,67 +0,0 @@ -//===- CIndexInclusionStack.cpp - Clang-C Source Indexing Library ---------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines a callback mechanism for clients to get the inclusion -// stack from a translation unit. -// -//===----------------------------------------------------------------------===// - -#include "CIndexer.h" -#include "CXSourceLocation.h" -#include "clang/AST/DeclVisitor.h" -#include "clang/Frontend/ASTUnit.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/Support/raw_ostream.h" -using namespace clang; - -extern "C" { -void clang_getInclusions(CXTranslationUnit TU, CXInclusionVisitor CB, - CXClientData clientData) { - - ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU); - SourceManager &SM = CXXUnit->getSourceManager(); - ASTContext &Ctx = CXXUnit->getASTContext(); - - llvm::SmallVector<CXSourceLocation, 10> InclusionStack; - unsigned i = SM.sloc_loaded_entry_size(); - unsigned n = SM.sloc_entry_size(); - - // In the case where all the SLocEntries are in an external source, traverse - // those SLocEntries as well. This is the case where we are looking - // at the inclusion stack of an AST/PCH file. - if (i >= n) - i = 0; - - for ( ; i < n ; ++i) { - - const SrcMgr::SLocEntry &SL = SM.getSLocEntry(i); - - if (!SL.isFile()) - continue; - - const SrcMgr::FileInfo &FI = SL.getFile(); - if (!FI.getContentCache()->Entry) - continue; - - // Build the inclusion stack. - SourceLocation L = FI.getIncludeLoc(); - InclusionStack.clear(); - while (L.isValid()) { - PresumedLoc PLoc = SM.getPresumedLoc(L); - InclusionStack.push_back(cxloc::translateSourceLocation(Ctx, L)); - L = PLoc.getIncludeLoc(); - } - - // Callback to the client. - // FIXME: We should have a function to construct CXFiles. - CB((CXFile) FI.getContentCache()->Entry, - InclusionStack.data(), InclusionStack.size(), clientData); - } -} -} // end extern C diff --git a/contrib/llvm/tools/clang/tools/libclang/CIndexUSRs.cpp b/contrib/llvm/tools/clang/tools/libclang/CIndexUSRs.cpp deleted file mode 100644 index 8f3dacf..0000000 --- a/contrib/llvm/tools/clang/tools/libclang/CIndexUSRs.cpp +++ /dev/null @@ -1,847 +0,0 @@ -//===- CIndexUSR.cpp - Clang-C Source Indexing Library --------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the generation and use of USRs from CXEntities. -// -//===----------------------------------------------------------------------===// - -#include "CIndexer.h" -#include "CXCursor.h" -#include "clang/AST/DeclTemplate.h" -#include "clang/AST/DeclVisitor.h" -#include "clang/Frontend/ASTUnit.h" -#include "clang/Lex/PreprocessingRecord.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/Support/raw_ostream.h" - -using namespace clang; -using namespace clang::cxstring; - -//===----------------------------------------------------------------------===// -// USR generation. -//===----------------------------------------------------------------------===// - -namespace { -class USRGenerator : public DeclVisitor<USRGenerator> { - llvm::SmallString<1024> Buf; - llvm::raw_svector_ostream Out; - bool IgnoreResults; - ASTUnit *AU; - bool generatedLoc; -public: - USRGenerator(const CXCursor *C = 0) - : Out(Buf), - IgnoreResults(false), - AU(C ? cxcursor::getCursorASTUnit(*C) : 0), - generatedLoc(false) - { - // Add the USR space prefix. - Out << "c:"; - } - - llvm::StringRef str() { - return Out.str(); - } - - USRGenerator* operator->() { return this; } - - template <typename T> - llvm::raw_svector_ostream &operator<<(const T &x) { - Out << x; - return Out; - } - - bool ignoreResults() const { return IgnoreResults; } - - // Visitation methods from generating USRs from AST elements. - void VisitDeclContext(DeclContext *D); - void VisitFieldDecl(FieldDecl *D); - void VisitFunctionDecl(FunctionDecl *D); - void VisitNamedDecl(NamedDecl *D); - void VisitNamespaceDecl(NamespaceDecl *D); - void VisitNamespaceAliasDecl(NamespaceAliasDecl *D); - void VisitFunctionTemplateDecl(FunctionTemplateDecl *D); - void VisitClassTemplateDecl(ClassTemplateDecl *D); - void VisitObjCClassDecl(ObjCClassDecl *CD); - void VisitObjCContainerDecl(ObjCContainerDecl *CD); - void VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *P); - void VisitObjCMethodDecl(ObjCMethodDecl *MD); - void VisitObjCPropertyDecl(ObjCPropertyDecl *D); - void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D); - void VisitTagDecl(TagDecl *D); - void VisitTypedefDecl(TypedefDecl *D); - void VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D); - void VisitVarDecl(VarDecl *D); - void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D); - void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D); - void VisitLinkageSpecDecl(LinkageSpecDecl *D) { - IgnoreResults = true; - } - void VisitUsingDirectiveDecl(UsingDirectiveDecl *D) { - IgnoreResults = true; - } - void VisitUsingDecl(UsingDecl *D) { - IgnoreResults = true; - } - void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) { - IgnoreResults = true; - } - void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) { - IgnoreResults = true; - } - - /// Generate the string component containing the location of the - /// declaration. - bool GenLoc(const Decl *D); - - /// String generation methods used both by the visitation methods - /// and from other clients that want to directly generate USRs. These - /// methods do not construct complete USRs (which incorporate the parents - /// of an AST element), but only the fragments concerning the AST element - /// itself. - - /// Generate a USR for an Objective-C class. - void GenObjCClass(llvm::StringRef cls); - /// Generate a USR for an Objective-C class category. - void GenObjCCategory(llvm::StringRef cls, llvm::StringRef cat); - /// Generate a USR fragment for an Objective-C instance variable. The - /// complete USR can be created by concatenating the USR for the - /// encompassing class with this USR fragment. - void GenObjCIvar(llvm::StringRef ivar); - /// Generate a USR fragment for an Objective-C method. - void GenObjCMethod(llvm::StringRef sel, bool isInstanceMethod); - /// Generate a USR fragment for an Objective-C property. - void GenObjCProperty(llvm::StringRef prop); - /// Generate a USR for an Objective-C protocol. - void GenObjCProtocol(llvm::StringRef prot); - - void VisitType(QualType T); - void VisitTemplateParameterList(const TemplateParameterList *Params); - void VisitTemplateName(TemplateName Name); - void VisitTemplateArgument(const TemplateArgument &Arg); - - /// Emit a Decl's name using NamedDecl::printName() and return true if - /// the decl had no name. - bool EmitDeclName(const NamedDecl *D); -}; - -} // end anonymous namespace - -//===----------------------------------------------------------------------===// -// Generating USRs from ASTS. -//===----------------------------------------------------------------------===// - -bool USRGenerator::EmitDeclName(const NamedDecl *D) { - Out.flush(); - const unsigned startSize = Buf.size(); - D->printName(Out); - Out.flush(); - const unsigned endSize = Buf.size(); - return startSize == endSize; -} - -static bool InAnonymousNamespace(const Decl *D) { - if (const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(D->getDeclContext())) - return ND->isAnonymousNamespace(); - return false; -} - -static inline bool ShouldGenerateLocation(const NamedDecl *D) { - return D->getLinkage() != ExternalLinkage && !InAnonymousNamespace(D); -} - -void USRGenerator::VisitDeclContext(DeclContext *DC) { - if (NamedDecl *D = dyn_cast<NamedDecl>(DC)) - Visit(D); -} - -void USRGenerator::VisitFieldDecl(FieldDecl *D) { - VisitDeclContext(D->getDeclContext()); - Out << (isa<ObjCIvarDecl>(D) ? "@" : "@FI@"); - if (EmitDeclName(D)) { - // Bit fields can be anonymous. - IgnoreResults = true; - return; - } -} - -void USRGenerator::VisitFunctionDecl(FunctionDecl *D) { - if (ShouldGenerateLocation(D) && GenLoc(D)) - return; - - VisitDeclContext(D->getDeclContext()); - if (FunctionTemplateDecl *FunTmpl = D->getDescribedFunctionTemplate()) { - Out << "@FT@"; - VisitTemplateParameterList(FunTmpl->getTemplateParameters()); - } else - Out << "@F@"; - D->printName(Out); - - ASTContext &Ctx = AU->getASTContext(); - if (!Ctx.getLangOptions().CPlusPlus || D->isExternC()) - return; - - // Mangle in type information for the arguments. - for (FunctionDecl::param_iterator I = D->param_begin(), E = D->param_end(); - I != E; ++I) { - Out << '#'; - if (ParmVarDecl *PD = *I) - VisitType(PD->getType()); - } - if (D->isVariadic()) - Out << '.'; - Out << '#'; - if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) { - if (MD->isStatic()) - Out << 'S'; - if (unsigned quals = MD->getTypeQualifiers()) - Out << (char)('0' + quals); - } -} - -void USRGenerator::VisitNamedDecl(NamedDecl *D) { - VisitDeclContext(D->getDeclContext()); - Out << "@"; - - if (EmitDeclName(D)) { - // The string can be empty if the declaration has no name; e.g., it is - // the ParmDecl with no name for declaration of a function pointer type, - // e.g.: void (*f)(void *); - // In this case, don't generate a USR. - IgnoreResults = true; - } -} - -void USRGenerator::VisitVarDecl(VarDecl *D) { - // VarDecls can be declared 'extern' within a function or method body, - // but their enclosing DeclContext is the function, not the TU. We need - // to check the storage class to correctly generate the USR. - if (ShouldGenerateLocation(D) && GenLoc(D)) - return; - - VisitDeclContext(D->getDeclContext()); - - // Variables always have simple names. - llvm::StringRef s = D->getName(); - - // The string can be empty if the declaration has no name; e.g., it is - // the ParmDecl with no name for declaration of a function pointer type, e.g.: - // void (*f)(void *); - // In this case, don't generate a USR. - if (s.empty()) - IgnoreResults = true; - else - Out << '@' << s; -} - -void USRGenerator::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) { - GenLoc(D); - return; -} - -void USRGenerator::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) { - GenLoc(D); - return; -} - -void USRGenerator::VisitNamespaceDecl(NamespaceDecl *D) { - if (D->isAnonymousNamespace()) { - Out << "@aN"; - return; - } - - VisitDeclContext(D->getDeclContext()); - if (!IgnoreResults) - Out << "@N@" << D->getName(); -} - -void USRGenerator::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { - VisitFunctionDecl(D->getTemplatedDecl()); -} - -void USRGenerator::VisitClassTemplateDecl(ClassTemplateDecl *D) { - VisitTagDecl(D->getTemplatedDecl()); -} - -void USRGenerator::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) { - VisitDeclContext(D->getDeclContext()); - if (!IgnoreResults) - Out << "@NA@" << D->getName(); -} - -void USRGenerator::VisitObjCMethodDecl(ObjCMethodDecl *D) { - Decl *container = cast<Decl>(D->getDeclContext()); - - // The USR for a method declared in a class extension is based on - // the ObjCInterfaceDecl, not the ObjCCategoryDecl. - do { - if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(container)) - if (CD->IsClassExtension()) { - Visit(CD->getClassInterface()); - break; - } - Visit(cast<Decl>(D->getDeclContext())); - } - while (false); - - // Ideally we would use 'GenObjCMethod', but this is such a hot path - // for Objective-C code that we don't want to use - // DeclarationName::getAsString(). - Out << (D->isInstanceMethod() ? "(im)" : "(cm)"); - DeclarationName N(D->getSelector()); - N.printName(Out); -} - -void USRGenerator::VisitObjCClassDecl(ObjCClassDecl *D) { - // FIXME: @class declarations can refer to multiple classes. We need - // to be able to traverse these. - IgnoreResults = true; -} - -void USRGenerator::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) { - // FIXME: @protocol declarations can refer to multiple protocols. We need - // to be able to traverse these. - IgnoreResults = true; -} - -void USRGenerator::VisitObjCContainerDecl(ObjCContainerDecl *D) { - switch (D->getKind()) { - default: - assert(false && "Invalid ObjC container."); - case Decl::ObjCInterface: - case Decl::ObjCImplementation: - GenObjCClass(D->getName()); - break; - case Decl::ObjCCategory: { - ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(D); - ObjCInterfaceDecl *ID = CD->getClassInterface(); - if (!ID) { - // Handle invalid code where the @interface might not - // have been specified. - // FIXME: We should be able to generate this USR even if the - // @interface isn't available. - IgnoreResults = true; - return; - } - // Specially handle class extensions, which are anonymous categories. - // We want to mangle in the location to uniquely distinguish them. - if (CD->IsClassExtension()) { - Out << "objc(ext)" << ID->getName() << '@'; - GenLoc(CD); - } - else - GenObjCCategory(ID->getName(), CD->getName()); - - break; - } - case Decl::ObjCCategoryImpl: { - ObjCCategoryImplDecl *CD = cast<ObjCCategoryImplDecl>(D); - ObjCInterfaceDecl *ID = CD->getClassInterface(); - if (!ID) { - // Handle invalid code where the @interface might not - // have been specified. - // FIXME: We should be able to generate this USR even if the - // @interface isn't available. - IgnoreResults = true; - return; - } - GenObjCCategory(ID->getName(), CD->getName()); - break; - } - case Decl::ObjCProtocol: - GenObjCProtocol(cast<ObjCProtocolDecl>(D)->getName()); - break; - } -} - -void USRGenerator::VisitObjCPropertyDecl(ObjCPropertyDecl *D) { - Visit(cast<Decl>(D->getDeclContext())); - GenObjCProperty(D->getName()); -} - -void USRGenerator::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) { - if (ObjCPropertyDecl *PD = D->getPropertyDecl()) { - VisitObjCPropertyDecl(PD); - return; - } - - IgnoreResults = true; -} - -void USRGenerator::VisitTagDecl(TagDecl *D) { - // Add the location of the tag decl to handle resolution across - // translation units. - if (ShouldGenerateLocation(D) && GenLoc(D)) - return; - - D = D->getCanonicalDecl(); - VisitDeclContext(D->getDeclContext()); - - bool AlreadyStarted = false; - if (CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) { - if (ClassTemplateDecl *ClassTmpl = CXXRecord->getDescribedClassTemplate()) { - AlreadyStarted = true; - - switch (D->getTagKind()) { - case TTK_Struct: Out << "@ST"; break; - case TTK_Class: Out << "@CT"; break; - case TTK_Union: Out << "@UT"; break; - case TTK_Enum: llvm_unreachable("enum template"); break; - } - VisitTemplateParameterList(ClassTmpl->getTemplateParameters()); - } else if (ClassTemplatePartialSpecializationDecl *PartialSpec - = dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord)) { - AlreadyStarted = true; - - switch (D->getTagKind()) { - case TTK_Struct: Out << "@SP"; break; - case TTK_Class: Out << "@CP"; break; - case TTK_Union: Out << "@UP"; break; - case TTK_Enum: llvm_unreachable("enum partial specialization"); break; - } - VisitTemplateParameterList(PartialSpec->getTemplateParameters()); - } - } - - if (!AlreadyStarted) { - switch (D->getTagKind()) { - case TTK_Struct: Out << "@S"; break; - case TTK_Class: Out << "@C"; break; - case TTK_Union: Out << "@U"; break; - case TTK_Enum: Out << "@E"; break; - } - } - - Out << '@'; - Out.flush(); - assert(Buf.size() > 0); - const unsigned off = Buf.size() - 1; - - if (EmitDeclName(D)) { - if (const TypedefDecl *TD = D->getTypedefForAnonDecl()) { - Buf[off] = 'A'; - Out << '@' << TD; - } - else - Buf[off] = 'a'; - } - - // For a class template specialization, mangle the template arguments. - if (ClassTemplateSpecializationDecl *Spec - = dyn_cast<ClassTemplateSpecializationDecl>(D)) { - const TemplateArgumentList &Args = Spec->getTemplateInstantiationArgs(); - Out << '>'; - for (unsigned I = 0, N = Args.size(); I != N; ++I) { - Out << '#'; - VisitTemplateArgument(Args.get(I)); - } - } -} - -void USRGenerator::VisitTypedefDecl(TypedefDecl *D) { - if (ShouldGenerateLocation(D) && GenLoc(D)) - return; - DeclContext *DC = D->getDeclContext(); - if (NamedDecl *DCN = dyn_cast<NamedDecl>(DC)) - Visit(DCN); - Out << "@T@"; - Out << D->getName(); -} - -void USRGenerator::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { - GenLoc(D); - return; -} - -bool USRGenerator::GenLoc(const Decl *D) { - if (generatedLoc) - return IgnoreResults; - generatedLoc = true; - - const SourceManager &SM = AU->getSourceManager(); - SourceLocation L = D->getLocStart(); - if (L.isInvalid()) { - IgnoreResults = true; - return true; - } - L = SM.getInstantiationLoc(L); - const std::pair<FileID, unsigned> &Decomposed = SM.getDecomposedLoc(L); - const FileEntry *FE = SM.getFileEntryForID(Decomposed.first); - if (FE) { - llvm::sys::Path P(FE->getName()); - Out << P.getLast(); - } - else { - // This case really isn't interesting. - IgnoreResults = true; - return true; - } - // Use the offest into the FileID to represent the location. Using - // a line/column can cause us to look back at the original source file, - // which is expensive. - Out << '@' << Decomposed.second; - return IgnoreResults; -} - -void USRGenerator::VisitType(QualType T) { - // This method mangles in USR information for types. It can possibly - // just reuse the naming-mangling logic used by codegen, although the - // requirements for USRs might not be the same. - ASTContext &Ctx = AU->getASTContext(); - - do { - T = Ctx.getCanonicalType(T); - Qualifiers Q = T.getQualifiers(); - unsigned qVal = 0; - if (Q.hasConst()) - qVal |= 0x1; - if (Q.hasVolatile()) - qVal |= 0x2; - if (Q.hasRestrict()) - qVal |= 0x4; - if(qVal) - Out << ((char) ('0' + qVal)); - - // Mangle in ObjC GC qualifiers? - - if (const PointerType *PT = T->getAs<PointerType>()) { - Out << '*'; - T = PT->getPointeeType(); - continue; - } - if (const ReferenceType *RT = T->getAs<ReferenceType>()) { - Out << '&'; - T = RT->getPointeeType(); - continue; - } - if (const FunctionProtoType *FT = T->getAs<FunctionProtoType>()) { - Out << 'F'; - VisitType(FT->getResultType()); - for (FunctionProtoType::arg_type_iterator - I = FT->arg_type_begin(), E = FT->arg_type_end(); I!=E; ++I) { - VisitType(*I); - } - if (FT->isVariadic()) - Out << '.'; - return; - } - if (const BlockPointerType *BT = T->getAs<BlockPointerType>()) { - Out << 'B'; - T = BT->getPointeeType(); - continue; - } - if (const BuiltinType *BT = T->getAs<BuiltinType>()) { - unsigned char c = '\0'; - switch (BT->getKind()) { - case BuiltinType::Void: - c = 'v'; break; - case BuiltinType::Bool: - c = 'b'; break; - case BuiltinType::Char_U: - case BuiltinType::UChar: - c = 'c'; break; - case BuiltinType::Char16: - c = 'q'; break; - case BuiltinType::Char32: - c = 'w'; break; - case BuiltinType::UShort: - c = 's'; break; - case BuiltinType::UInt: - c = 'i'; break; - case BuiltinType::ULong: - c = 'l'; break; - case BuiltinType::ULongLong: - c = 'k'; break; - case BuiltinType::UInt128: - c = 'j'; break; - case BuiltinType::Char_S: - case BuiltinType::SChar: - c = 'C'; break; - case BuiltinType::WChar: - c = 'W'; break; - case BuiltinType::Short: - c = 'S'; break; - case BuiltinType::Int: - c = 'I'; break; - case BuiltinType::Long: - c = 'L'; break; - case BuiltinType::LongLong: - c = 'K'; break; - case BuiltinType::Int128: - c = 'J'; break; - case BuiltinType::Float: - c = 'f'; break; - case BuiltinType::Double: - c = 'd'; break; - case BuiltinType::LongDouble: - c = 'D'; break; - case BuiltinType::NullPtr: - c = 'n'; break; - case BuiltinType::Overload: - case BuiltinType::Dependent: - case BuiltinType::UndeducedAuto: - IgnoreResults = true; - return; - case BuiltinType::ObjCId: - c = 'o'; break; - case BuiltinType::ObjCClass: - c = 'O'; break; - case BuiltinType::ObjCSel: - c = 'e'; break; - } - Out << c; - return; - } - if (const ComplexType *CT = T->getAs<ComplexType>()) { - Out << '<'; - T = CT->getElementType(); - continue; - } - if (const TagType *TT = T->getAs<TagType>()) { - Out << '$'; - VisitTagDecl(TT->getDecl()); - return; - } - if (const TemplateTypeParmType *TTP = T->getAs<TemplateTypeParmType>()) { - Out << 't' << TTP->getDepth() << '.' << TTP->getIndex(); - return; - } - if (const TemplateSpecializationType *Spec - = T->getAs<TemplateSpecializationType>()) { - Out << '>'; - VisitTemplateName(Spec->getTemplateName()); - Out << Spec->getNumArgs(); - for (unsigned I = 0, N = Spec->getNumArgs(); I != N; ++I) - VisitTemplateArgument(Spec->getArg(I)); - return; - } - - // Unhandled type. - Out << ' '; - break; - } while (true); -} - -void USRGenerator::VisitTemplateParameterList( - const TemplateParameterList *Params) { - if (!Params) - return; - Out << '>' << Params->size(); - for (TemplateParameterList::const_iterator P = Params->begin(), - PEnd = Params->end(); - P != PEnd; ++P) { - Out << '#'; - if (isa<TemplateTypeParmDecl>(*P)) { - Out << 'T'; - continue; - } - - if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) { - Out << 'N'; - VisitType(NTTP->getType()); - continue; - } - - TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P); - Out << 't'; - VisitTemplateParameterList(TTP->getTemplateParameters()); - } -} - -void USRGenerator::VisitTemplateName(TemplateName Name) { - if (TemplateDecl *Template = Name.getAsTemplateDecl()) { - if (TemplateTemplateParmDecl *TTP - = dyn_cast<TemplateTemplateParmDecl>(Template)) { - Out << 't' << TTP->getDepth() << '.' << TTP->getIndex(); - return; - } - - Visit(Template); - return; - } - - // FIXME: Visit dependent template names. -} - -void USRGenerator::VisitTemplateArgument(const TemplateArgument &Arg) { - switch (Arg.getKind()) { - case TemplateArgument::Null: - break; - - case TemplateArgument::Declaration: - Visit(Arg.getAsDecl()); - break; - - case TemplateArgument::Template: - VisitTemplateName(Arg.getAsTemplate()); - break; - - case TemplateArgument::Expression: - // FIXME: Visit expressions. - break; - - case TemplateArgument::Pack: - // FIXME: Variadic templates - break; - - case TemplateArgument::Type: - VisitType(Arg.getAsType()); - break; - - case TemplateArgument::Integral: - Out << 'V'; - VisitType(Arg.getIntegralType()); - Out << *Arg.getAsIntegral(); - break; - } -} - -//===----------------------------------------------------------------------===// -// General purpose USR generation methods. -//===----------------------------------------------------------------------===// - -void USRGenerator::GenObjCClass(llvm::StringRef cls) { - Out << "objc(cs)" << cls; -} - -void USRGenerator::GenObjCCategory(llvm::StringRef cls, llvm::StringRef cat) { - Out << "objc(cy)" << cls << '@' << cat; -} - -void USRGenerator::GenObjCIvar(llvm::StringRef ivar) { - Out << '@' << ivar; -} - -void USRGenerator::GenObjCMethod(llvm::StringRef meth, bool isInstanceMethod) { - Out << (isInstanceMethod ? "(im)" : "(cm)") << meth; -} - -void USRGenerator::GenObjCProperty(llvm::StringRef prop) { - Out << "(py)" << prop; -} - -void USRGenerator::GenObjCProtocol(llvm::StringRef prot) { - Out << "objc(pl)" << prot; -} - -//===----------------------------------------------------------------------===// -// API hooks. -//===----------------------------------------------------------------------===// - -static inline llvm::StringRef extractUSRSuffix(llvm::StringRef s) { - return s.startswith("c:") ? s.substr(2) : ""; -} - -static CXString getDeclCursorUSR(const CXCursor &C) { - Decl *D = cxcursor::getCursorDecl(C); - - // Don't generate USRs for things with invalid locations. - if (!D || D->getLocStart().isInvalid()) - return createCXString(""); - - // Check if the cursor has 'NoLinkage'. - if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) - switch (ND->getLinkage()) { - case ExternalLinkage: - // Generate USRs for all entities with external linkage. - break; - case NoLinkage: - case UniqueExternalLinkage: - // We allow enums, typedefs, and structs that have no linkage to - // have USRs that are anchored to the file they were defined in - // (e.g., the header). This is a little gross, but in principal - // enums/anonymous structs/etc. defined in a common header file - // are referred to across multiple translation units. - if (isa<TagDecl>(ND) || isa<TypedefDecl>(ND) || - isa<EnumConstantDecl>(ND) || isa<FieldDecl>(ND) || - isa<VarDecl>(ND) || isa<NamespaceDecl>(ND)) - break; - // Fall-through. - case InternalLinkage: - if (isa<FunctionDecl>(ND)) - break; - } - - USRGenerator UG(&C); - UG->Visit(D); - - if (UG->ignoreResults()) - return createCXString(""); - -#if 0 - // For development testing. - assert(UG.str().size() > 2); -#endif - - // Return a copy of the string that must be disposed by the caller. - return createCXString(UG.str(), true); -} - -extern "C" { - -CXString clang_getCursorUSR(CXCursor C) { - const CXCursorKind &K = clang_getCursorKind(C); - - if (clang_isDeclaration(K)) - return getDeclCursorUSR(C); - - if (K == CXCursor_MacroDefinition) { - USRGenerator UG(&C); - UG << "macro@" - << cxcursor::getCursorMacroDefinition(C)->getName()->getNameStart(); - return createCXString(UG.str(), true); - } - - return createCXString(""); -} - -CXString clang_constructUSR_ObjCIvar(const char *name, CXString classUSR) { - USRGenerator UG; - UG << extractUSRSuffix(clang_getCString(classUSR)); - UG->GenObjCIvar(name); - return createCXString(UG.str(), true); -} - -CXString clang_constructUSR_ObjCMethod(const char *name, - unsigned isInstanceMethod, - CXString classUSR) { - USRGenerator UG; - UG << extractUSRSuffix(clang_getCString(classUSR)); - UG->GenObjCMethod(name, isInstanceMethod); - return createCXString(UG.str(), true); -} - -CXString clang_constructUSR_ObjCClass(const char *name) { - USRGenerator UG; - UG->GenObjCClass(name); - return createCXString(UG.str(), true); -} - -CXString clang_constructUSR_ObjCProtocol(const char *name) { - USRGenerator UG; - UG->GenObjCProtocol(name); - return createCXString(UG.str(), true); -} - -CXString clang_constructUSR_ObjCCategory(const char *class_name, - const char *category_name) { - USRGenerator UG; - UG->GenObjCCategory(class_name, category_name); - return createCXString(UG.str(), true); -} - -CXString clang_constructUSR_ObjCProperty(const char *property, - CXString classUSR) { - USRGenerator UG; - UG << extractUSRSuffix(clang_getCString(classUSR)); - UG->GenObjCProperty(property); - return createCXString(UG.str(), true); -} - -} // end extern "C" diff --git a/contrib/llvm/tools/clang/tools/libclang/CIndexer.cpp b/contrib/llvm/tools/clang/tools/libclang/CIndexer.cpp deleted file mode 100644 index cdf6c61..0000000 --- a/contrib/llvm/tools/clang/tools/libclang/CIndexer.cpp +++ /dev/null @@ -1,155 +0,0 @@ -//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the Clang-C Source Indexing library. -// -//===----------------------------------------------------------------------===// - -#include "CIndexer.h" - -#include "clang/AST/Decl.h" -#include "clang/AST/DeclVisitor.h" -#include "clang/AST/StmtVisitor.h" -#include "clang/Basic/FileManager.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Basic/Version.h" -#include "clang/Sema/CodeCompleteConsumer.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/Config/config.h" -#include "llvm/Support/Compiler.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/System/Program.h" - -#include <cstdio> -#include <vector> -#include <sstream> - -#ifdef LLVM_ON_WIN32 -#include <windows.h> -#else -#include <dlfcn.h> -#endif - -using namespace clang; - -const llvm::sys::Path& CIndexer::getClangPath() { - // Did we already compute the path? - if (!ClangPath.empty()) - return ClangPath; - - // Find the location where this library lives (libCIndex.dylib). -#ifdef LLVM_ON_WIN32 - MEMORY_BASIC_INFORMATION mbi; - char path[MAX_PATH]; - VirtualQuery((void *)(uintptr_t)clang_createTranslationUnit, &mbi, - sizeof(mbi)); - GetModuleFileNameA((HINSTANCE)mbi.AllocationBase, path, MAX_PATH); - - llvm::sys::Path CIndexPath(path); - - CIndexPath.eraseComponent(); - CIndexPath.appendComponent("clang"); - CIndexPath.appendSuffix("exe"); - CIndexPath.makeAbsolute(); -#else - // This silly cast below avoids a C++ warning. - Dl_info info; - if (dladdr((void *)(uintptr_t)clang_createTranslationUnit, &info) == 0) - assert(0 && "Call to dladdr() failed"); - - llvm::sys::Path CIndexPath(info.dli_fname); - - // We now have the CIndex directory, locate clang relative to it. - CIndexPath.eraseComponent(); - CIndexPath.appendComponent(".."); - CIndexPath.appendComponent("bin"); - CIndexPath.appendComponent("clang"); -#endif - - // Cache our result. - ClangPath = CIndexPath; - return ClangPath; -} - -std::string CIndexer::getClangResourcesPath() { - llvm::sys::Path P = getClangPath(); - - if (!P.empty()) { - P.eraseComponent(); // Remove /clang from foo/bin/clang - P.eraseComponent(); // Remove /bin from foo/bin - - // Get foo/lib/clang/<version>/include - P.appendComponent("lib"); - P.appendComponent("clang"); - P.appendComponent(CLANG_VERSION_STRING); - } - - return P.str(); -} - -static llvm::sys::Path GetTemporaryPath() { - // FIXME: This is lame; sys::Path should provide this function (in particular, - // it should know how to find the temporary files dir). - std::string Error; - const char *TmpDir = ::getenv("TMPDIR"); - if (!TmpDir) - TmpDir = ::getenv("TEMP"); - if (!TmpDir) - TmpDir = ::getenv("TMP"); - if (!TmpDir) - TmpDir = "/tmp"; - llvm::sys::Path P(TmpDir); - P.appendComponent("remap"); - if (P.makeUnique(false, &Error)) - return llvm::sys::Path(""); - - // FIXME: Grumble, makeUnique sometimes leaves the file around!? PR3837. - P.eraseFromDisk(false, 0); - - return P; -} - -bool clang::RemapFiles(unsigned num_unsaved_files, - struct CXUnsavedFile *unsaved_files, - std::vector<std::string> &RemapArgs, - std::vector<llvm::sys::Path> &TemporaryFiles) { - for (unsigned i = 0; i != num_unsaved_files; ++i) { - // Write the contents of this unsaved file into the temporary file. - llvm::sys::Path SavedFile(GetTemporaryPath()); - if (SavedFile.empty()) - return true; - - std::string ErrorInfo; - llvm::raw_fd_ostream OS(SavedFile.c_str(), ErrorInfo); - if (!ErrorInfo.empty()) - return true; - - OS.write(unsaved_files[i].Contents, unsaved_files[i].Length); - OS.close(); - if (OS.has_error()) { - SavedFile.eraseFromDisk(); - OS.clear_error(); - return true; - } - - // Remap the file. - std::string RemapArg = unsaved_files[i].Filename; - RemapArg += ';'; - RemapArg += SavedFile.str(); - RemapArgs.push_back("-Xclang"); - RemapArgs.push_back("-remap-file"); - RemapArgs.push_back("-Xclang"); - RemapArgs.push_back(RemapArg); - TemporaryFiles.push_back(SavedFile); - } - - return false; -} - diff --git a/contrib/llvm/tools/clang/tools/libclang/CIndexer.h b/contrib/llvm/tools/clang/tools/libclang/CIndexer.h deleted file mode 100644 index 31bf779..0000000 --- a/contrib/llvm/tools/clang/tools/libclang/CIndexer.h +++ /dev/null @@ -1,78 +0,0 @@ -//===- CIndexer.h - Clang-C Source Indexing Library -----------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines CIndexer, a subclass of Indexer that provides extra -// functionality needed by the CIndex library. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_CINDEXER_H -#define LLVM_CLANG_CINDEXER_H - -#include "clang-c/Index.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/System/Path.h" -#include <vector> - -namespace clang { -namespace cxstring { - CXString createCXString(const char *String, bool DupString = false); - CXString createCXString(llvm::StringRef String, bool DupString = true); -} -} - -class CIndexer { - bool UseExternalASTGeneration; - bool OnlyLocalDecls; - bool DisplayDiagnostics; - - llvm::sys::Path ClangPath; - -public: - CIndexer() - : UseExternalASTGeneration(false), OnlyLocalDecls(false), - DisplayDiagnostics(false) { } - - /// \brief Whether we only want to see "local" declarations (that did not - /// come from a previous precompiled header). If false, we want to see all - /// declarations. - bool getOnlyLocalDecls() const { return OnlyLocalDecls; } - void setOnlyLocalDecls(bool Local = true) { OnlyLocalDecls = Local; } - - bool getDisplayDiagnostics() const { return DisplayDiagnostics; } - void setDisplayDiagnostics(bool Display = true) { - DisplayDiagnostics = Display; - } - - bool getUseExternalASTGeneration() const { return UseExternalASTGeneration; } - void setUseExternalASTGeneration(bool Value) { - UseExternalASTGeneration = Value; - } - - /// \brief Get the path of the clang binary. - const llvm::sys::Path& getClangPath(); - - /// \brief Get the path of the clang resource files. - std::string getClangResourcesPath(); -}; - -namespace clang { - /** - * \brief Given a set of "unsaved" files, create temporary files and - * construct the clang -cc1 argument list needed to perform the remapping. - * - * \returns true if an error occurred. - */ - bool RemapFiles(unsigned num_unsaved_files, - struct CXUnsavedFile *unsaved_files, - std::vector<std::string> &RemapArgs, - std::vector<llvm::sys::Path> &TemporaryFiles); -} - -#endif diff --git a/contrib/llvm/tools/clang/tools/libclang/CMakeLists.txt b/contrib/llvm/tools/clang/tools/libclang/CMakeLists.txt deleted file mode 100644 index 29ef574..0000000 --- a/contrib/llvm/tools/clang/tools/libclang/CMakeLists.txt +++ /dev/null @@ -1,64 +0,0 @@ -set(SHARED_LIBRARY TRUE) - -set(LLVM_NO_RTTI 1) - -set(LLVM_USED_LIBS - clangFrontend - clangDriver - clangSerialization - clangParse - clangSema - clangAnalysis - clangAST - clangLex - clangBasic) - -set( LLVM_LINK_COMPONENTS - bitreader - mc - core - ) - -add_clang_library(libclang - CIndex.cpp - CIndexCXX.cpp - CIndexCodeCompletion.cpp - CIndexDiagnostic.cpp - CIndexInclusionStack.cpp - CIndexUSRs.cpp - CIndexer.cpp - CXCursor.cpp - CXType.cpp - ../../include/clang-c/Index.h -) - -if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - # dylib versioning information - # FIXME: Is there a more CMake-ish way to handle this? - set(LIBCLANG_VERSION 1 - CACHE STRING "Version number of the libclang library") - set(LIBCLANG_SUBVERSION 0 - CACHE STRING "Minor version number of the libclang library") - set(LIBCLANG_LINK_FLAGS - "-Wl,-current_version -Wl,${LIBCLANG_VERSION}.${LIBCLANG_SUBVERSION} -Wl,-compatibility_version -Wl,1") - - set(LIBCLANG_LINK_FLAGS - "${LIBCLANG_LINK_FLAGS} -Wl,-dead_strip -Wl,-seg1addr -Wl,0xE0000000") - - set_target_properties(libclang - PROPERTIES - LINK_FLAGS "${LIBCLANG_LINK_FLAGS}" - INSTALL_NAME_DIR "@executable_path/../lib") -endif() - -if(MSVC) - # windows.h doesn't compile with /Za - get_target_property(NON_ANSI_COMPILE_FLAGS libclang COMPILE_FLAGS) - string(REPLACE /Za "" NON_ANSI_COMPILE_FLAGS ${NON_ANSI_COMPILE_FLAGS}) - set_target_properties(libclang PROPERTIES COMPILE_FLAGS ${NON_ANSI_COMPILE_FLAGS}) -endif(MSVC) - -set_target_properties(libclang - PROPERTIES - LINKER_LANGUAGE CXX - DEFINE_SYMBOL _CINDEX_LIB_) diff --git a/contrib/llvm/tools/clang/tools/libclang/CXCursor.cpp b/contrib/llvm/tools/clang/tools/libclang/CXCursor.cpp deleted file mode 100644 index a8fd049..0000000 --- a/contrib/llvm/tools/clang/tools/libclang/CXCursor.cpp +++ /dev/null @@ -1,374 +0,0 @@ -//===- CXCursor.cpp - Routines for manipulating CXCursors -----------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines routines for manipulating CXCursors. It should be the -// only file that has internal knowledge of the encoding of the data in -// CXCursor. -// -//===----------------------------------------------------------------------===// - -#include "CXCursor.h" -#include "clang/Frontend/ASTUnit.h" -#include "clang/AST/Decl.h" -#include "clang/AST/DeclCXX.h" -#include "clang/AST/DeclObjC.h" -#include "clang/AST/Expr.h" -#include "llvm/Support/ErrorHandling.h" - -using namespace clang; - -CXCursor cxcursor::MakeCXCursorInvalid(CXCursorKind K) { - assert(K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid); - CXCursor C = { K, { 0, 0, 0 } }; - return C; -} - -static CXCursorKind GetCursorKind(const Attr *A) { - assert(A && "Invalid arguments!"); - switch (A->getKind()) { - default: break; - case attr::IBAction: return CXCursor_IBActionAttr; - case attr::IBOutlet: return CXCursor_IBOutletAttr; - case attr::IBOutletCollection: return CXCursor_IBOutletCollectionAttr; - } - - return CXCursor_UnexposedAttr; -} - -CXCursor cxcursor::MakeCXCursor(const Attr *A, Decl *Parent, ASTUnit *TU) { - assert(A && Parent && TU && "Invalid arguments!"); - CXCursor C = { GetCursorKind(A), { Parent, (void*)A, TU } }; - return C; -} - -CXCursor cxcursor::MakeCXCursor(Decl *D, ASTUnit *TU) { - assert(D && TU && "Invalid arguments!"); - CXCursor C = { getCursorKindForDecl(D), { D, 0, TU } }; - return C; -} - -CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent, ASTUnit *TU) { - assert(S && TU && "Invalid arguments!"); - CXCursorKind K = CXCursor_NotImplemented; - - switch (S->getStmtClass()) { - case Stmt::NoStmtClass: - break; - - case Stmt::NullStmtClass: - case Stmt::CompoundStmtClass: - case Stmt::CaseStmtClass: - case Stmt::DefaultStmtClass: - case Stmt::LabelStmtClass: - case Stmt::IfStmtClass: - case Stmt::SwitchStmtClass: - case Stmt::WhileStmtClass: - case Stmt::DoStmtClass: - case Stmt::ForStmtClass: - case Stmt::GotoStmtClass: - case Stmt::IndirectGotoStmtClass: - case Stmt::ContinueStmtClass: - case Stmt::BreakStmtClass: - case Stmt::ReturnStmtClass: - case Stmt::DeclStmtClass: - case Stmt::SwitchCaseClass: - case Stmt::AsmStmtClass: - case Stmt::ObjCAtTryStmtClass: - case Stmt::ObjCAtCatchStmtClass: - case Stmt::ObjCAtFinallyStmtClass: - case Stmt::ObjCAtThrowStmtClass: - case Stmt::ObjCAtSynchronizedStmtClass: - case Stmt::ObjCForCollectionStmtClass: - case Stmt::CXXCatchStmtClass: - case Stmt::CXXTryStmtClass: - K = CXCursor_UnexposedStmt; - break; - - case Stmt::PredefinedExprClass: - case Stmt::IntegerLiteralClass: - case Stmt::FloatingLiteralClass: - case Stmt::ImaginaryLiteralClass: - case Stmt::StringLiteralClass: - case Stmt::CharacterLiteralClass: - case Stmt::ParenExprClass: - case Stmt::UnaryOperatorClass: - case Stmt::OffsetOfExprClass: - case Stmt::SizeOfAlignOfExprClass: - case Stmt::ArraySubscriptExprClass: - case Stmt::BinaryOperatorClass: - case Stmt::CompoundAssignOperatorClass: - case Stmt::ConditionalOperatorClass: - case Stmt::ImplicitCastExprClass: - case Stmt::CStyleCastExprClass: - case Stmt::CompoundLiteralExprClass: - case Stmt::ExtVectorElementExprClass: - case Stmt::InitListExprClass: - case Stmt::DesignatedInitExprClass: - case Stmt::ImplicitValueInitExprClass: - case Stmt::ParenListExprClass: - case Stmt::VAArgExprClass: - case Stmt::AddrLabelExprClass: - case Stmt::StmtExprClass: - case Stmt::TypesCompatibleExprClass: - case Stmt::ChooseExprClass: - case Stmt::GNUNullExprClass: - case Stmt::CXXStaticCastExprClass: - case Stmt::CXXDynamicCastExprClass: - case Stmt::CXXReinterpretCastExprClass: - case Stmt::CXXConstCastExprClass: - case Stmt::CXXFunctionalCastExprClass: - case Stmt::CXXTypeidExprClass: - case Stmt::CXXBoolLiteralExprClass: - case Stmt::CXXNullPtrLiteralExprClass: - case Stmt::CXXThisExprClass: - case Stmt::CXXThrowExprClass: - case Stmt::CXXDefaultArgExprClass: - case Stmt::CXXScalarValueInitExprClass: - case Stmt::CXXNewExprClass: - case Stmt::CXXDeleteExprClass: - case Stmt::CXXPseudoDestructorExprClass: - case Stmt::UnresolvedLookupExprClass: - case Stmt::UnaryTypeTraitExprClass: - case Stmt::DependentScopeDeclRefExprClass: - case Stmt::CXXBindTemporaryExprClass: - case Stmt::CXXExprWithTemporariesClass: - case Stmt::CXXUnresolvedConstructExprClass: - case Stmt::CXXDependentScopeMemberExprClass: - case Stmt::UnresolvedMemberExprClass: - case Stmt::ObjCStringLiteralClass: - case Stmt::ObjCEncodeExprClass: - case Stmt::ObjCSelectorExprClass: - case Stmt::ObjCProtocolExprClass: - case Stmt::ObjCImplicitSetterGetterRefExprClass: - case Stmt::ObjCSuperExprClass: - case Stmt::ObjCIsaExprClass: - case Stmt::ShuffleVectorExprClass: - case Stmt::BlockExprClass: - K = CXCursor_UnexposedExpr; - break; - case Stmt::DeclRefExprClass: - case Stmt::BlockDeclRefExprClass: - // FIXME: UnresolvedLookupExpr? - // FIXME: DependentScopeDeclRefExpr? - K = CXCursor_DeclRefExpr; - break; - - case Stmt::MemberExprClass: - case Stmt::ObjCIvarRefExprClass: - case Stmt::ObjCPropertyRefExprClass: - // FIXME: UnresolvedMemberExpr? - // FIXME: CXXDependentScopeMemberExpr? - K = CXCursor_MemberRefExpr; - break; - - case Stmt::CallExprClass: - case Stmt::CXXOperatorCallExprClass: - case Stmt::CXXMemberCallExprClass: - case Stmt::CXXConstructExprClass: - case Stmt::CXXTemporaryObjectExprClass: - // FIXME: CXXUnresolvedConstructExpr - // FIXME: ObjCImplicitSetterGetterRefExpr? - K = CXCursor_CallExpr; - break; - - case Stmt::ObjCMessageExprClass: - K = CXCursor_ObjCMessageExpr; - break; - } - - CXCursor C = { K, { Parent, S, TU } }; - return C; -} - -CXCursor cxcursor::MakeCursorObjCSuperClassRef(ObjCInterfaceDecl *Super, - SourceLocation Loc, - ASTUnit *TU) { - assert(Super && TU && "Invalid arguments!"); - void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding()); - CXCursor C = { CXCursor_ObjCSuperClassRef, { Super, RawLoc, TU } }; - return C; -} - -std::pair<ObjCInterfaceDecl *, SourceLocation> -cxcursor::getCursorObjCSuperClassRef(CXCursor C) { - assert(C.kind == CXCursor_ObjCSuperClassRef); - return std::make_pair(static_cast<ObjCInterfaceDecl *>(C.data[0]), - SourceLocation::getFromRawEncoding( - reinterpret_cast<uintptr_t>(C.data[1]))); -} - -CXCursor cxcursor::MakeCursorObjCProtocolRef(ObjCProtocolDecl *Super, - SourceLocation Loc, - ASTUnit *TU) { - assert(Super && TU && "Invalid arguments!"); - void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding()); - CXCursor C = { CXCursor_ObjCProtocolRef, { Super, RawLoc, TU } }; - return C; -} - -std::pair<ObjCProtocolDecl *, SourceLocation> -cxcursor::getCursorObjCProtocolRef(CXCursor C) { - assert(C.kind == CXCursor_ObjCProtocolRef); - return std::make_pair(static_cast<ObjCProtocolDecl *>(C.data[0]), - SourceLocation::getFromRawEncoding( - reinterpret_cast<uintptr_t>(C.data[1]))); -} - -CXCursor cxcursor::MakeCursorObjCClassRef(ObjCInterfaceDecl *Class, - SourceLocation Loc, - ASTUnit *TU) { - // 'Class' can be null for invalid code. - if (!Class) - return MakeCXCursorInvalid(CXCursor_InvalidCode); - assert(TU && "Invalid arguments!"); - void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding()); - CXCursor C = { CXCursor_ObjCClassRef, { Class, RawLoc, TU } }; - return C; -} - -std::pair<ObjCInterfaceDecl *, SourceLocation> -cxcursor::getCursorObjCClassRef(CXCursor C) { - assert(C.kind == CXCursor_ObjCClassRef); - return std::make_pair(static_cast<ObjCInterfaceDecl *>(C.data[0]), - SourceLocation::getFromRawEncoding( - reinterpret_cast<uintptr_t>(C.data[1]))); -} - -CXCursor cxcursor::MakeCursorTypeRef(TypeDecl *Type, SourceLocation Loc, - ASTUnit *TU) { - assert(Type && TU && "Invalid arguments!"); - void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding()); - CXCursor C = { CXCursor_TypeRef, { Type, RawLoc, TU } }; - return C; -} - -std::pair<TypeDecl *, SourceLocation> -cxcursor::getCursorTypeRef(CXCursor C) { - assert(C.kind == CXCursor_TypeRef); - return std::make_pair(static_cast<TypeDecl *>(C.data[0]), - SourceLocation::getFromRawEncoding( - reinterpret_cast<uintptr_t>(C.data[1]))); -} - -CXCursor cxcursor::MakeCursorTemplateRef(TemplateDecl *Template, - SourceLocation Loc, ASTUnit *TU) { - assert(Template && TU && "Invalid arguments!"); - void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding()); - CXCursor C = { CXCursor_TemplateRef, { Template, RawLoc, TU } }; - return C; -} - -std::pair<TemplateDecl *, SourceLocation> -cxcursor::getCursorTemplateRef(CXCursor C) { - assert(C.kind == CXCursor_TemplateRef); - return std::make_pair(static_cast<TemplateDecl *>(C.data[0]), - SourceLocation::getFromRawEncoding( - reinterpret_cast<uintptr_t>(C.data[1]))); -} - -CXCursor cxcursor::MakeCursorNamespaceRef(NamedDecl *NS, SourceLocation Loc, - ASTUnit *TU) { - - assert(NS && (isa<NamespaceDecl>(NS) || isa<NamespaceAliasDecl>(NS)) && TU && - "Invalid arguments!"); - void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding()); - CXCursor C = { CXCursor_NamespaceRef, { NS, RawLoc, TU } }; - return C; -} - -std::pair<NamedDecl *, SourceLocation> -cxcursor::getCursorNamespaceRef(CXCursor C) { - assert(C.kind == CXCursor_NamespaceRef); - return std::make_pair(static_cast<NamedDecl *>(C.data[0]), - SourceLocation::getFromRawEncoding( - reinterpret_cast<uintptr_t>(C.data[1]))); -} - -CXCursor cxcursor::MakeCursorCXXBaseSpecifier(CXXBaseSpecifier *B, ASTUnit *TU){ - CXCursor C = { CXCursor_CXXBaseSpecifier, { B, 0, TU } }; - return C; -} - -CXXBaseSpecifier *cxcursor::getCursorCXXBaseSpecifier(CXCursor C) { - assert(C.kind == CXCursor_CXXBaseSpecifier); - return static_cast<CXXBaseSpecifier*>(C.data[0]); -} - -CXCursor cxcursor::MakePreprocessingDirectiveCursor(SourceRange Range, - ASTUnit *TU) { - CXCursor C = { CXCursor_PreprocessingDirective, - { reinterpret_cast<void *>(Range.getBegin().getRawEncoding()), - reinterpret_cast<void *>(Range.getEnd().getRawEncoding()), - TU } - }; - return C; -} - -SourceRange cxcursor::getCursorPreprocessingDirective(CXCursor C) { - assert(C.kind == CXCursor_PreprocessingDirective); - return SourceRange(SourceLocation::getFromRawEncoding( - reinterpret_cast<uintptr_t> (C.data[0])), - SourceLocation::getFromRawEncoding( - reinterpret_cast<uintptr_t> (C.data[1]))); -} - -CXCursor cxcursor::MakeMacroDefinitionCursor(MacroDefinition *MI, ASTUnit *TU) { - CXCursor C = { CXCursor_MacroDefinition, { MI, 0, TU } }; - return C; -} - -MacroDefinition *cxcursor::getCursorMacroDefinition(CXCursor C) { - assert(C.kind == CXCursor_MacroDefinition); - return static_cast<MacroDefinition *>(C.data[0]); -} - -CXCursor cxcursor::MakeMacroInstantiationCursor(MacroInstantiation *MI, - ASTUnit *TU) { - CXCursor C = { CXCursor_MacroInstantiation, { MI, 0, TU } }; - return C; -} - -MacroInstantiation *cxcursor::getCursorMacroInstantiation(CXCursor C) { - assert(C.kind == CXCursor_MacroInstantiation); - return static_cast<MacroInstantiation *>(C.data[0]); -} - -Decl *cxcursor::getCursorDecl(CXCursor Cursor) { - return (Decl *)Cursor.data[0]; -} - -Expr *cxcursor::getCursorExpr(CXCursor Cursor) { - return dyn_cast_or_null<Expr>(getCursorStmt(Cursor)); -} - -Stmt *cxcursor::getCursorStmt(CXCursor Cursor) { - if (Cursor.kind == CXCursor_ObjCSuperClassRef || - Cursor.kind == CXCursor_ObjCProtocolRef || - Cursor.kind == CXCursor_ObjCClassRef) - return 0; - - return (Stmt *)Cursor.data[1]; -} - -Attr *cxcursor::getCursorAttr(CXCursor Cursor) { - return (Attr *)Cursor.data[1]; -} - -ASTContext &cxcursor::getCursorContext(CXCursor Cursor) { - return getCursorASTUnit(Cursor)->getASTContext(); -} - -ASTUnit *cxcursor::getCursorASTUnit(CXCursor Cursor) { - return static_cast<ASTUnit *>(Cursor.data[2]); -} - -bool cxcursor::operator==(CXCursor X, CXCursor Y) { - return X.kind == Y.kind && X.data[0] == Y.data[0] && X.data[1] == Y.data[1] && - X.data[2] == Y.data[2]; -} diff --git a/contrib/llvm/tools/clang/tools/libclang/CXCursor.h b/contrib/llvm/tools/clang/tools/libclang/CXCursor.h deleted file mode 100644 index a5f111e..0000000 --- a/contrib/llvm/tools/clang/tools/libclang/CXCursor.h +++ /dev/null @@ -1,138 +0,0 @@ -//===- CXCursor.h - Routines for manipulating CXCursors -------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines routines for manipulating CXCursors. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_CXCURSOR_H -#define LLVM_CLANG_CXCURSOR_H - -#include "clang-c/Index.h" -#include "clang/Basic/SourceLocation.h" -#include <utility> - -namespace clang { - -class ASTContext; -class ASTUnit; -class Attr; -class CXXBaseSpecifier; -class Decl; -class Expr; -class MacroDefinition; -class MacroInstantiation; -class NamedDecl; -class ObjCInterfaceDecl; -class ObjCProtocolDecl; -class Stmt; -class TemplateDecl; -class TypeDecl; - -namespace cxcursor { - -CXCursor MakeCXCursor(const clang::Attr *A, clang::Decl *Parent, ASTUnit *TU); -CXCursor MakeCXCursor(clang::Decl *D, ASTUnit *TU); -CXCursor MakeCXCursor(clang::Stmt *S, clang::Decl *Parent, ASTUnit *TU); -CXCursor MakeCXCursorInvalid(CXCursorKind K); - -/// \brief Create an Objective-C superclass reference at the given location. -CXCursor MakeCursorObjCSuperClassRef(ObjCInterfaceDecl *Super, - SourceLocation Loc, - ASTUnit *TU); - -/// \brief Unpack an ObjCSuperClassRef cursor into the interface it references -/// and optionally the location where the reference occurred. -std::pair<ObjCInterfaceDecl *, SourceLocation> - getCursorObjCSuperClassRef(CXCursor C); - -/// \brief Create an Objective-C protocol reference at the given location. -CXCursor MakeCursorObjCProtocolRef(ObjCProtocolDecl *Proto, SourceLocation Loc, - ASTUnit *TU); - -/// \brief Unpack an ObjCProtocolRef cursor into the protocol it references -/// and optionally the location where the reference occurred. -std::pair<ObjCProtocolDecl *, SourceLocation> - getCursorObjCProtocolRef(CXCursor C); - -/// \brief Create an Objective-C class reference at the given location. -CXCursor MakeCursorObjCClassRef(ObjCInterfaceDecl *Class, SourceLocation Loc, - ASTUnit *TU); - -/// \brief Unpack an ObjCClassRef cursor into the class it references -/// and optionally the location where the reference occurred. -std::pair<ObjCInterfaceDecl *, SourceLocation> - getCursorObjCClassRef(CXCursor C); - -/// \brief Create a type reference at the given location. -CXCursor MakeCursorTypeRef(TypeDecl *Type, SourceLocation Loc, ASTUnit *TU); - -/// \brief Unpack a TypeRef cursor into the class it references -/// and optionally the location where the reference occurred. -std::pair<TypeDecl *, SourceLocation> getCursorTypeRef(CXCursor C); - -/// \brief Create a reference to a template at the given location. -CXCursor MakeCursorTemplateRef(TemplateDecl *Template, SourceLocation Loc, - ASTUnit *TU); - -/// \brief Unpack a TemplateRef cursor into the template it references and -/// the location where the reference occurred. -std::pair<TemplateDecl *, SourceLocation> getCursorTemplateRef(CXCursor C); - -/// \brief Create a reference to a namespace or namespace alias at the given -/// location. -CXCursor MakeCursorNamespaceRef(NamedDecl *NS, SourceLocation Loc, ASTUnit *TU); - -/// \brief Unpack a NamespaceRef cursor into the namespace or namespace alias -/// it references and the location where the reference occurred. -std::pair<NamedDecl *, SourceLocation> getCursorNamespaceRef(CXCursor C); - -/// \brief Create a CXX base specifier cursor. -CXCursor MakeCursorCXXBaseSpecifier(CXXBaseSpecifier *B, ASTUnit *TU); - -/// \brief Unpack a CXXBaseSpecifier cursor into a CXXBaseSpecifier. -CXXBaseSpecifier *getCursorCXXBaseSpecifier(CXCursor C); - -/// \brief Create a preprocessing directive cursor. -CXCursor MakePreprocessingDirectiveCursor(SourceRange Range, ASTUnit *TU); - -/// \brief Unpack a given preprocessing directive to retrieve its source range. -SourceRange getCursorPreprocessingDirective(CXCursor C); - -/// \brief Create a macro definition cursor. -CXCursor MakeMacroDefinitionCursor(MacroDefinition *, ASTUnit *TU); - -/// \brief Unpack a given macro definition cursor to retrieve its -/// source range. -MacroDefinition *getCursorMacroDefinition(CXCursor C); - -/// \brief Create a macro instantiation cursor. -CXCursor MakeMacroInstantiationCursor(MacroInstantiation *, ASTUnit *TU); - -/// \brief Unpack a given macro instantiation cursor to retrieve its -/// source range. -MacroInstantiation *getCursorMacroInstantiation(CXCursor C); - -Decl *getCursorDecl(CXCursor Cursor); -Expr *getCursorExpr(CXCursor Cursor); -Stmt *getCursorStmt(CXCursor Cursor); -Attr *getCursorAttr(CXCursor Cursor); - -ASTContext &getCursorContext(CXCursor Cursor); -ASTUnit *getCursorASTUnit(CXCursor Cursor); - -bool operator==(CXCursor X, CXCursor Y); - -inline bool operator!=(CXCursor X, CXCursor Y) { - return !(X == Y); -} - -}} // end namespace: clang::cxcursor - -#endif diff --git a/contrib/llvm/tools/clang/tools/libclang/CXSourceLocation.h b/contrib/llvm/tools/clang/tools/libclang/CXSourceLocation.h deleted file mode 100644 index 7a50205..0000000 --- a/contrib/llvm/tools/clang/tools/libclang/CXSourceLocation.h +++ /dev/null @@ -1,78 +0,0 @@ -//===- CXSourceLocation.h - CXSourceLocations Utilities ---------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines routines for manipulating CXSourceLocations. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_CXSOURCELOCATION_H -#define LLVM_CLANG_CXSOURCELOCATION_H - -#include "clang-c/Index.h" -#include "clang/Basic/SourceLocation.h" -#include "clang/Basic/LangOptions.h" -#include "clang/AST/ASTContext.h" - -namespace clang { - -class SourceManager; - -namespace cxloc { - -/// \brief Translate a Clang source location into a CIndex source location. -static inline CXSourceLocation -translateSourceLocation(const SourceManager &SM, const LangOptions &LangOpts, - SourceLocation Loc) { - if (Loc.isInvalid()) - clang_getNullLocation(); - - CXSourceLocation Result = { { (void*) &SM, (void*) &LangOpts, }, - Loc.getRawEncoding() }; - return Result; -} - -/// \brief Translate a Clang source location into a CIndex source location. -static inline CXSourceLocation translateSourceLocation(ASTContext &Context, - SourceLocation Loc) { - return translateSourceLocation(Context.getSourceManager(), - Context.getLangOptions(), - Loc); -} - -/// \brief Translate a Clang source range into a CIndex source range. -/// -/// Clang internally represents ranges where the end location points to the -/// start of the token at the end. However, for external clients it is more -/// useful to have a CXSourceRange be a proper half-open interval. This routine -/// does the appropriate translation. -CXSourceRange translateSourceRange(const SourceManager &SM, - const LangOptions &LangOpts, - const CharSourceRange &R); - -/// \brief Translate a Clang source range into a CIndex source range. -static inline CXSourceRange translateSourceRange(ASTContext &Context, - SourceRange R) { - return translateSourceRange(Context.getSourceManager(), - Context.getLangOptions(), - CharSourceRange::getTokenRange(R)); -} - -static inline SourceLocation translateSourceLocation(CXSourceLocation L) { - return SourceLocation::getFromRawEncoding(L.int_data); -} - -static inline SourceRange translateCXSourceRange(CXSourceRange R) { - return SourceRange(SourceLocation::getFromRawEncoding(R.begin_int_data), - SourceLocation::getFromRawEncoding(R.end_int_data)); -} - - -}} // end namespace: clang::cxloc - -#endif diff --git a/contrib/llvm/tools/clang/tools/libclang/CXType.cpp b/contrib/llvm/tools/clang/tools/libclang/CXType.cpp deleted file mode 100644 index aa173ca..0000000 --- a/contrib/llvm/tools/clang/tools/libclang/CXType.cpp +++ /dev/null @@ -1,297 +0,0 @@ -//===- CXTypes.cpp - Implements 'CXTypes' aspect of libclang ------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===--------------------------------------------------------------------===// -// -// This file implements the 'CXTypes' API hooks in the Clang-C library. -// -//===--------------------------------------------------------------------===// - -#include "CIndexer.h" -#include "CXCursor.h" -#include "CXType.h" -#include "clang/AST/Expr.h" -#include "clang/AST/Type.h" -#include "clang/AST/Decl.h" -#include "clang/AST/DeclObjC.h" -#include "clang/Frontend/ASTUnit.h" - -using namespace clang; - -static CXTypeKind GetBuiltinTypeKind(const BuiltinType *BT) { -#define BTCASE(K) case BuiltinType::K: return CXType_##K - switch (BT->getKind()) { - BTCASE(Void); - BTCASE(Bool); - BTCASE(Char_U); - BTCASE(UChar); - BTCASE(Char16); - BTCASE(Char32); - BTCASE(UShort); - BTCASE(UInt); - BTCASE(ULong); - BTCASE(ULongLong); - BTCASE(UInt128); - BTCASE(Char_S); - BTCASE(SChar); - BTCASE(WChar); - BTCASE(Short); - BTCASE(Int); - BTCASE(Long); - BTCASE(LongLong); - BTCASE(Int128); - BTCASE(Float); - BTCASE(Double); - BTCASE(LongDouble); - BTCASE(NullPtr); - BTCASE(Overload); - BTCASE(Dependent); - BTCASE(ObjCId); - BTCASE(ObjCClass); - BTCASE(ObjCSel); - default: - return CXType_Unexposed; - } -#undef BTCASE -} - -static CXTypeKind GetTypeKind(QualType T) { - Type *TP = T.getTypePtr(); - if (!TP) - return CXType_Invalid; - -#define TKCASE(K) case Type::K: return CXType_##K - switch (TP->getTypeClass()) { - case Type::Builtin: - return GetBuiltinTypeKind(cast<BuiltinType>(TP)); - TKCASE(Complex); - TKCASE(Pointer); - TKCASE(BlockPointer); - TKCASE(LValueReference); - TKCASE(RValueReference); - TKCASE(Record); - TKCASE(Enum); - TKCASE(Typedef); - TKCASE(ObjCInterface); - TKCASE(ObjCObjectPointer); - TKCASE(FunctionNoProto); - TKCASE(FunctionProto); - default: - return CXType_Unexposed; - } -#undef TKCASE -} - - -CXType cxtype::MakeCXType(QualType T, ASTUnit *TU) { - CXTypeKind TK = GetTypeKind(T); - CXType CT = { TK, { TK == CXType_Invalid ? 0 : T.getAsOpaquePtr(), TU }}; - return CT; -} - -using cxtype::MakeCXType; - -static inline QualType GetQualType(CXType CT) { - return QualType::getFromOpaquePtr(CT.data[0]); -} - -static inline ASTUnit* GetASTU(CXType CT) { - return static_cast<ASTUnit*>(CT.data[1]); -} - -extern "C" { - -CXType clang_getCursorType(CXCursor C) { - ASTUnit *AU = cxcursor::getCursorASTUnit(C); - - if (clang_isExpression(C.kind)) { - QualType T = cxcursor::getCursorExpr(C)->getType(); - return MakeCXType(T, AU); - } - - if (clang_isDeclaration(C.kind)) { - Decl *D = cxcursor::getCursorDecl(C); - - if (TypeDecl *TD = dyn_cast<TypeDecl>(D)) - return MakeCXType(QualType(TD->getTypeForDecl(), 0), AU); - if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) - return MakeCXType(QualType(ID->getTypeForDecl(), 0), AU); - if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) - return MakeCXType(VD->getType(), AU); - if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) - return MakeCXType(PD->getType(), AU); - if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) - return MakeCXType(FD->getType(), AU); - return MakeCXType(QualType(), AU); - } - - return MakeCXType(QualType(), AU); -} - -CXType clang_getCanonicalType(CXType CT) { - if (CT.kind == CXType_Invalid) - return CT; - - QualType T = GetQualType(CT); - - if (T.isNull()) - return MakeCXType(QualType(), GetASTU(CT)); - - ASTUnit *AU = GetASTU(CT); - return MakeCXType(AU->getASTContext().getCanonicalType(T), AU); -} - -CXType clang_getPointeeType(CXType CT) { - QualType T = GetQualType(CT); - Type *TP = T.getTypePtr(); - - if (!TP) - return MakeCXType(QualType(), GetASTU(CT)); - - switch (TP->getTypeClass()) { - case Type::Pointer: - T = cast<PointerType>(TP)->getPointeeType(); - break; - case Type::BlockPointer: - T = cast<BlockPointerType>(TP)->getPointeeType(); - break; - case Type::LValueReference: - case Type::RValueReference: - T = cast<ReferenceType>(TP)->getPointeeType(); - break; - case Type::ObjCObjectPointer: - T = cast<ObjCObjectPointerType>(TP)->getPointeeType(); - break; - default: - T = QualType(); - break; - } - return MakeCXType(T, GetASTU(CT)); -} - -CXCursor clang_getTypeDeclaration(CXType CT) { - if (CT.kind == CXType_Invalid) - return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound); - - QualType T = GetQualType(CT); - Type *TP = T.getTypePtr(); - - if (!TP) - return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound); - - Decl *D = 0; - - switch (TP->getTypeClass()) { - case Type::Typedef: - D = cast<TypedefType>(TP)->getDecl(); - break; - case Type::ObjCObject: - D = cast<ObjCObjectType>(TP)->getInterface(); - break; - case Type::ObjCInterface: - D = cast<ObjCInterfaceType>(TP)->getDecl(); - break; - case Type::Record: - case Type::Enum: - D = cast<TagType>(TP)->getDecl(); - break; - default: - break; - } - - if (!D) - return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound); - - return cxcursor::MakeCXCursor(D, GetASTU(CT)); -} - -CXString clang_getTypeKindSpelling(enum CXTypeKind K) { - const char *s = 0; -#define TKIND(X) case CXType_##X: s = "" #X ""; break - switch (K) { - TKIND(Invalid); - TKIND(Unexposed); - TKIND(Void); - TKIND(Bool); - TKIND(Char_U); - TKIND(UChar); - TKIND(Char16); - TKIND(Char32); - TKIND(UShort); - TKIND(UInt); - TKIND(ULong); - TKIND(ULongLong); - TKIND(UInt128); - TKIND(Char_S); - TKIND(SChar); - TKIND(WChar); - TKIND(Short); - TKIND(Int); - TKIND(Long); - TKIND(LongLong); - TKIND(Int128); - TKIND(Float); - TKIND(Double); - TKIND(LongDouble); - TKIND(NullPtr); - TKIND(Overload); - TKIND(Dependent); - TKIND(ObjCId); - TKIND(ObjCClass); - TKIND(ObjCSel); - TKIND(Complex); - TKIND(Pointer); - TKIND(BlockPointer); - TKIND(LValueReference); - TKIND(RValueReference); - TKIND(Record); - TKIND(Enum); - TKIND(Typedef); - TKIND(ObjCInterface); - TKIND(ObjCObjectPointer); - TKIND(FunctionNoProto); - TKIND(FunctionProto); - } -#undef TKIND - return cxstring::createCXString(s); -} - -unsigned clang_equalTypes(CXType A, CXType B) { - return A.data[0] == B.data[0] && A.data[1] == B.data[1];; -} - -CXType clang_getResultType(CXType X) { - QualType T = GetQualType(X); - if (!T.getTypePtr()) - return MakeCXType(QualType(), GetASTU(X)); - - if (const FunctionType *FD = T->getAs<FunctionType>()) - return MakeCXType(FD->getResultType(), GetASTU(X)); - - return MakeCXType(QualType(), GetASTU(X)); -} - -CXType clang_getCursorResultType(CXCursor C) { - if (clang_isDeclaration(C.kind)) { - Decl *D = cxcursor::getCursorDecl(C); - if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) - return MakeCXType(MD->getResultType(), cxcursor::getCursorASTUnit(C)); - - return clang_getResultType(clang_getCursorType(C)); - } - - return MakeCXType(QualType(), cxcursor::getCursorASTUnit(C)); -} - -unsigned clang_isPODType(CXType X) { - QualType T = GetQualType(X); - if (!T.getTypePtr()) - return 0; - return T->isPODType() ? 1 : 0; -} - -} // end: extern "C" diff --git a/contrib/llvm/tools/clang/tools/libclang/CXType.h b/contrib/llvm/tools/clang/tools/libclang/CXType.h deleted file mode 100644 index 94151ed..0000000 --- a/contrib/llvm/tools/clang/tools/libclang/CXType.h +++ /dev/null @@ -1,29 +0,0 @@ -//===- CXTypes.h - Routines for manipulating CXTypes ----------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines routines for manipulating CXCursors. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_CXTYPES_H -#define LLVM_CLANG_CXTYPES_H - -#include "clang-c/Index.h" -#include "clang/AST/Type.h" - -namespace clang { - -class ASTUnit; - -namespace cxtype { - -CXType MakeCXType(QualType T, ASTUnit *TU); - -}} // end namespace clang::cxtype -#endif diff --git a/contrib/llvm/tools/clang/tools/libclang/Makefile b/contrib/llvm/tools/clang/tools/libclang/Makefile deleted file mode 100644 index 6d2a13c..0000000 --- a/contrib/llvm/tools/clang/tools/libclang/Makefile +++ /dev/null @@ -1,46 +0,0 @@ -##===- tools/libclang/Makefile -----------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -CLANG_LEVEL := ../.. -LIBRARYNAME = clang - -EXPORTED_SYMBOL_FILE = $(PROJ_SRC_DIR)/libclang.exports - -LINK_LIBS_IN_SHARED = 1 -SHARED_LIBRARY = 1 - -LINK_COMPONENTS := bitreader mc core -USEDLIBS = clangFrontend.a clangDriver.a clangSerialization.a clangParse.a \ - clangSema.a clangAnalysis.a clangAST.a clangLex.a clangBasic.a - -include $(CLANG_LEVEL)/Makefile - -##===----------------------------------------------------------------------===## -# FIXME: This is copied from the 'lto' makefile. Should we share this? -##===----------------------------------------------------------------------===## - -ifeq ($(HOST_OS),Darwin) - LLVMLibsOptions += -Wl,-compatibility_version,1 - - # Set dylib internal version number to submission number. - ifdef LLVM_SUBMIT_VERSION - LLVMLibsOptions += -Wl,-current_version \ - -Wl,$(LLVM_SUBMIT_VERSION).$(LLVM_SUBMIT_SUBVERSION) - endif - - # Extra options to override libtool defaults. - LLVMLibsOptions += -Wl,-dead_strip -Wl,-seg1addr,0xE0000000 - - # Mac OS X 10.4 and earlier tools do not allow a second -install_name on command line - DARWIN_VERS := $(shell echo $(TARGET_TRIPLE) | sed 's/.*darwin\([0-9]*\).*/\1/') - ifneq ($(DARWIN_VERS),8) - LLVMLibsOptions += -Wl,-install_name \ - -Wl,"@rpath/lib$(LIBRARYNAME)$(SHLIBEXT)" - endif -endif diff --git a/contrib/llvm/tools/clang/tools/libclang/libclang.darwin.exports b/contrib/llvm/tools/clang/tools/libclang/libclang.darwin.exports deleted file mode 100644 index d1b45a2..0000000 --- a/contrib/llvm/tools/clang/tools/libclang/libclang.darwin.exports +++ /dev/null @@ -1,108 +0,0 @@ -_clang_CXXMethod_isStatic -_clang_annotateTokens -_clang_codeComplete -_clang_codeCompleteAt -_clang_codeCompleteGetDiagnostic -_clang_codeCompleteGetNumDiagnostics -_clang_constructUSR_ObjCCategory -_clang_constructUSR_ObjCClass -_clang_constructUSR_ObjCIvar -_clang_constructUSR_ObjCMethod -_clang_constructUSR_ObjCProperty -_clang_constructUSR_ObjCProtocol -_clang_createIndex -_clang_createTranslationUnit -_clang_createTranslationUnitFromSourceFile -_clang_defaultCodeCompleteOptions -_clang_defaultDiagnosticDisplayOptions -_clang_defaultEditingTranslationUnitOptions -_clang_defaultReparseOptions -_clang_defaultSaveOptions -_clang_disposeCodeCompleteResults -_clang_disposeDiagnostic -_clang_disposeIndex -_clang_disposeString -_clang_disposeTokens -_clang_disposeTranslationUnit -_clang_enableStackTraces -_clang_equalCursors -_clang_equalLocations -_clang_equalTypes -_clang_formatDiagnostic -_clang_getCString -_clang_getCXXAccessSpecifier -_clang_getCanonicalType -_clang_getClangVersion -_clang_getCompletionAvailability -_clang_getCompletionChunkCompletionString -_clang_getCompletionChunkKind -_clang_getCompletionChunkText -_clang_getCompletionPriority -_clang_getCursor -_clang_getCursorAvailability -_clang_getCursorDefinition -_clang_getCursorExtent -_clang_getCursorKind -_clang_getCursorKindSpelling -_clang_getCursorLanguage -_clang_getCursorLinkage -_clang_getCursorLocation -_clang_getCursorReferenced -_clang_getCursorResultType -_clang_getCursorSpelling -_clang_getCursorType -_clang_getCursorUSR -_clang_getDefinitionSpellingAndExtent -_clang_getDiagnostic -_clang_getDiagnosticFixIt -_clang_getDiagnosticLocation -_clang_getDiagnosticNumFixIts -_clang_getDiagnosticNumRanges -_clang_getDiagnosticRange -_clang_getDiagnosticSeverity -_clang_getDiagnosticSpelling -_clang_getFile -_clang_getFileName -_clang_getFileTime -_clang_getIBOutletCollectionType -_clang_getInclusions -_clang_getInstantiationLocation -_clang_getLocation -_clang_getNullCursor -_clang_getNullLocation -_clang_getNullRange -_clang_getNumCompletionChunks -_clang_getNumDiagnostics -_clang_getPointeeType -_clang_getRange -_clang_getRangeEnd -_clang_getRangeStart -_clang_getResultType -_clang_getSpecializedCursorTemplate -_clang_getTemplateCursorKind -_clang_getTokenExtent -_clang_getTokenKind -_clang_getTokenLocation -_clang_getTokenSpelling -_clang_getTranslationUnitCursor -_clang_getTranslationUnitSpelling -_clang_getTypeDeclaration -_clang_getTypeKindSpelling -_clang_isCursorDefinition -_clang_isDeclaration -_clang_isExpression -_clang_isInvalid -_clang_isPODType -_clang_isPreprocessing -_clang_isReference -_clang_isStatement -_clang_isTranslationUnit -_clang_isUnexposed -_clang_isVirtualBase -_clang_parseTranslationUnit -_clang_reparseTranslationUnit -_clang_saveTranslationUnit -_clang_setUseExternalASTGeneration -_clang_sortCodeCompletionResults -_clang_tokenize -_clang_visitChildren diff --git a/contrib/llvm/tools/clang/tools/libclang/libclang.exports b/contrib/llvm/tools/clang/tools/libclang/libclang.exports deleted file mode 100644 index 0ea6993..0000000 --- a/contrib/llvm/tools/clang/tools/libclang/libclang.exports +++ /dev/null @@ -1,108 +0,0 @@ -clang_CXXMethod_isStatic -clang_annotateTokens -clang_codeComplete -clang_codeCompleteAt -clang_codeCompleteGetDiagnostic -clang_codeCompleteGetNumDiagnostics -clang_constructUSR_ObjCCategory -clang_constructUSR_ObjCClass -clang_constructUSR_ObjCIvar -clang_constructUSR_ObjCMethod -clang_constructUSR_ObjCProperty -clang_constructUSR_ObjCProtocol -clang_createIndex -clang_createTranslationUnit -clang_createTranslationUnitFromSourceFile -clang_defaultCodeCompleteOptions -clang_defaultDiagnosticDisplayOptions -clang_defaultEditingTranslationUnitOptions -clang_defaultReparseOptions -clang_defaultSaveOptions -clang_disposeCodeCompleteResults -clang_disposeDiagnostic -clang_disposeIndex -clang_disposeString -clang_disposeTokens -clang_disposeTranslationUnit -clang_enableStackTraces -clang_equalCursors -clang_equalLocations -clang_equalTypes -clang_formatDiagnostic -clang_getCString -clang_getCXXAccessSpecifier -clang_getCanonicalType -clang_getClangVersion -clang_getCompletionAvailability -clang_getCompletionChunkCompletionString -clang_getCompletionChunkKind -clang_getCompletionChunkText -clang_getCompletionPriority -clang_getCursor -clang_getCursorAvailability -clang_getCursorDefinition -clang_getCursorExtent -clang_getCursorKind -clang_getCursorKindSpelling -clang_getCursorLanguage -clang_getCursorLinkage -clang_getCursorLocation -clang_getCursorReferenced -clang_getCursorResultType -clang_getCursorSpelling -clang_getCursorType -clang_getCursorUSR -clang_getDefinitionSpellingAndExtent -clang_getDiagnostic -clang_getDiagnosticFixIt -clang_getDiagnosticLocation -clang_getDiagnosticNumFixIts -clang_getDiagnosticNumRanges -clang_getDiagnosticRange -clang_getDiagnosticSeverity -clang_getDiagnosticSpelling -clang_getFile -clang_getFileName -clang_getFileTime -clang_getIBOutletCollectionType -clang_getInclusions -clang_getInstantiationLocation -clang_getLocation -clang_getNullCursor -clang_getNullLocation -clang_getNullRange -clang_getNumCompletionChunks -clang_getNumDiagnostics -clang_getPointeeType -clang_getRange -clang_getRangeEnd -clang_getRangeStart -clang_getResultType -clang_getSpecializedCursorTemplate -clang_getTemplateCursorKind -clang_getTokenExtent -clang_getTokenKind -clang_getTokenLocation -clang_getTokenSpelling -clang_getTranslationUnitCursor -clang_getTranslationUnitSpelling -clang_getTypeDeclaration -clang_getTypeKindSpelling -clang_isCursorDefinition -clang_isDeclaration -clang_isExpression -clang_isInvalid -clang_isPODType -clang_isPreprocessing -clang_isReference -clang_isStatement -clang_isTranslationUnit -clang_isUnexposed -clang_isVirtualBase -clang_parseTranslationUnit -clang_reparseTranslationUnit -clang_saveTranslationUnit -clang_setUseExternalASTGeneration -clang_sortCodeCompletionResults -clang_tokenize -clang_visitChildren diff --git a/contrib/llvm/tools/clang/tools/scan-build/c++-analyzer b/contrib/llvm/tools/clang/tools/scan-build/c++-analyzer deleted file mode 120000 index ca10bf5..0000000 --- a/contrib/llvm/tools/clang/tools/scan-build/c++-analyzer +++ /dev/null @@ -1 +0,0 @@ -ccc-analyzer
\ No newline at end of file diff --git a/contrib/llvm/tools/clang/tools/scan-build/ccc-analyzer b/contrib/llvm/tools/clang/tools/scan-build/ccc-analyzer deleted file mode 100755 index c182a68..0000000 --- a/contrib/llvm/tools/clang/tools/scan-build/ccc-analyzer +++ /dev/null @@ -1,661 +0,0 @@ -#!/usr/bin/env perl -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -# -# A script designed to interpose between the build system and gcc. It invokes -# both gcc and the static analyzer. -# -##===----------------------------------------------------------------------===## - -use strict; -use warnings; -use FindBin; -use Cwd qw/ getcwd abs_path /; -use File::Temp qw/ tempfile /; -use File::Path qw / mkpath /; -use File::Basename; -use Text::ParseWords; - -##===----------------------------------------------------------------------===## -# Compiler command setup. -##===----------------------------------------------------------------------===## - -my $Compiler; -my $Clang; - -if ($FindBin::Script =~ /c\+\+-analyzer/) { - $Compiler = $ENV{'CCC_CXX'}; - if (!defined $Compiler) { $Compiler = "g++"; } - - $Clang = $ENV{'CLANG_CXX'}; - if (!defined $Clang) { $Clang = 'clang++'; } -} -else { - $Compiler = $ENV{'CCC_CC'}; - if (!defined $Compiler) { $Compiler = "gcc"; } - - $Clang = $ENV{'CLANG'}; - if (!defined $Clang) { $Clang = 'clang'; } -} - -##===----------------------------------------------------------------------===## -# Cleanup. -##===----------------------------------------------------------------------===## - -my $ReportFailures = $ENV{'CCC_REPORT_FAILURES'}; -if (!defined $ReportFailures) { $ReportFailures = 1; } - -my $CleanupFile; -my $ResultFile; - -# Remove any stale files at exit. -END { - if (defined $CleanupFile && -z $CleanupFile) { - `rm -f $CleanupFile`; - } -} - -##----------------------------------------------------------------------------## -# Process Clang Crashes. -##----------------------------------------------------------------------------## - -sub GetPPExt { - my $Lang = shift; - if ($Lang =~ /objective-c\+\+/) { return ".mii" }; - if ($Lang =~ /objective-c/) { return ".mi"; } - if ($Lang =~ /c\+\+/) { return ".ii"; } - return ".i"; -} - -# Set this to 1 if we want to include 'parser rejects' files. -my $IncludeParserRejects = 0; -my $ParserRejects = "Parser Rejects"; - -my $AttributeIgnored = "Attribute Ignored"; - -sub ProcessClangFailure { - my ($Clang, $Lang, $file, $Args, $HtmlDir, $ErrorType, $ofile) = @_; - my $Dir = "$HtmlDir/failures"; - mkpath $Dir; - - my $prefix = "clang_crash"; - if ($ErrorType eq $ParserRejects) { - $prefix = "clang_parser_rejects"; - } - elsif ($ErrorType eq $AttributeIgnored) { - $prefix = "clang_attribute_ignored"; - } - - # Generate the preprocessed file with Clang. - my ($PPH, $PPFile) = tempfile( $prefix . "_XXXXXX", - SUFFIX => GetPPExt($Lang), - DIR => $Dir); - system $Clang, @$Args, "-E", "-o", $PPFile; - close ($PPH); - - # Create the info file. - open (OUT, ">", "$PPFile.info.txt") or die "Cannot open $PPFile.info.txt\n"; - print OUT abs_path($file), "\n"; - print OUT "$ErrorType\n"; - print OUT "@$Args\n"; - close OUT; - `uname -a >> $PPFile.info.txt 2>&1`; - `$Compiler -v >> $PPFile.info.txt 2>&1`; - system 'mv',$ofile,"$PPFile.stderr.txt"; - return (basename $PPFile); -} - -##----------------------------------------------------------------------------## -# Running the analyzer. -##----------------------------------------------------------------------------## - -sub GetCCArgs { - my $Args = shift; - - pipe (FROM_CHILD, TO_PARENT); - my $pid = fork(); - if ($pid == 0) { - close FROM_CHILD; - open(STDOUT,">&", \*TO_PARENT); - open(STDERR,">&", \*TO_PARENT); - exec $Clang, "-###", "-fsyntax-only", @$Args; - } - close(TO_PARENT); - my $line; - while (<FROM_CHILD>) { - next if (!/-cc1/); - $line = $_; - } - - waitpid($pid,0); - close(FROM_CHILD); - - die "could not find clang line\n" if (!defined $line); - # Strip the newline and initial whitspace - chomp $line; - $line =~ s/^\s+//; - my @items = quotewords('\s+', 0, $line); - my $cmd = shift @items; - die "cannot find 'clang' in 'clang' command\n" if (!($cmd =~ /clang/)); - return \@items; -} - -sub Analyze { - my ($Clang, $Args, $AnalyzeArgs, $Lang, $Output, $Verbose, $HtmlDir, - $file, $Analyses) = @_; - - $Args = GetCCArgs($Args); - - my $RunAnalyzer = 0; - my $Cmd; - my @CmdArgs; - my @CmdArgsSansAnalyses; - - if ($Lang =~ /header/) { - exit 0 if (!defined ($Output)); - $Cmd = 'cp'; - push @CmdArgs,$file; - # Remove the PCH extension. - $Output =~ s/[.]gch$//; - push @CmdArgs,$Output; - @CmdArgsSansAnalyses = @CmdArgs; - } - else { - $Cmd = $Clang; - push @CmdArgs, "-cc1"; - push @CmdArgs,'-DIBOutlet=__attribute__((iboutlet))'; - push @CmdArgs, @$Args; - @CmdArgsSansAnalyses = @CmdArgs; - push @CmdArgs,'-analyze'; - push @CmdArgs,"-analyzer-display-progress"; - push @CmdArgs,"-analyzer-eagerly-assume"; - push @CmdArgs,"-analyzer-opt-analyze-nested-blocks"; - push @CmdArgs,(split /\s/,$Analyses); - - if (defined $ENV{"CCC_EXPERIMENTAL_CHECKS"}) { - push @CmdArgs,"-analyzer-experimental-internal-checks"; - push @CmdArgs,"-analyzer-experimental-checks"; - } - - $RunAnalyzer = 1; - } - - # Add the analysis arguments passed down from scan-build. - foreach my $Arg (@$AnalyzeArgs) { - push @CmdArgs, $Arg; - } - - my @PrintArgs; - my $dir; - - if ($RunAnalyzer) { - if (defined $ResultFile) { - push @CmdArgs,'-o'; - push @CmdArgs, $ResultFile; - } - elsif (defined $HtmlDir) { - push @CmdArgs,'-o'; - push @CmdArgs, $HtmlDir; - } - } - - if ($Verbose) { - $dir = getcwd(); - print STDERR "\n[LOCATION]: $dir\n"; - push @PrintArgs,"'$Cmd'"; - foreach my $arg (@CmdArgs) { push @PrintArgs,"\'$arg\'"; } - } - - if ($Verbose == 1) { - # We MUST print to stderr. Some clients use the stdout output of - # gcc for various purposes. - print STDERR join(' ',@PrintArgs); - print STDERR "\n"; - } - elsif ($Verbose == 2) { - print STDERR "#SHELL (cd '$dir' && @PrintArgs)\n"; - } - - if (defined $ENV{'CCC_UBI'}) { - push @CmdArgs,"--analyzer-viz-egraph-ubigraph"; - } - - # Capture the STDERR of clang and send it to a temporary file. - # Capture the STDOUT of clang and reroute it to ccc-analyzer's STDERR. - # We save the output file in the 'crashes' directory if clang encounters - # any problems with the file. - pipe (FROM_CHILD, TO_PARENT); - my $pid = fork(); - if ($pid == 0) { - close FROM_CHILD; - open(STDOUT,">&", \*TO_PARENT); - open(STDERR,">&", \*TO_PARENT); - exec $Cmd, @CmdArgs; - } - - close TO_PARENT; - my ($ofh, $ofile) = tempfile("clang_output_XXXXXX", DIR => $HtmlDir); - - while (<FROM_CHILD>) { - print $ofh $_; - print STDERR $_; - } - - waitpid($pid,0); - close(FROM_CHILD); - my $Result = $?; - - # Did the command die because of a signal? - if ($ReportFailures) { - if ($Result & 127 and $Cmd eq $Clang and defined $HtmlDir) { - ProcessClangFailure($Clang, $Lang, $file, \@CmdArgsSansAnalyses, - $HtmlDir, "Crash", $ofile); - } - elsif ($Result) { - if ($IncludeParserRejects && !($file =~/conftest/)) { - ProcessClangFailure($Clang, $Lang, $file, \@CmdArgsSansAnalyses, - $HtmlDir, $ParserRejects, $ofile); - } - } - else { - # Check if there were any unhandled attributes. - if (open(CHILD, $ofile)) { - my %attributes_not_handled; - - # Don't flag warnings about the following attributes that we - # know are currently not supported by Clang. - $attributes_not_handled{"cdecl"} = 1; - - my $ppfile; - while (<CHILD>) { - next if (! /warning: '([^\']+)' attribute ignored/); - - # Have we already spotted this unhandled attribute? - next if (defined $attributes_not_handled{$1}); - $attributes_not_handled{$1} = 1; - - # Get the name of the attribute file. - my $dir = "$HtmlDir/failures"; - my $afile = "$dir/attribute_ignored_$1.txt"; - - # Only create another preprocessed file if the attribute file - # doesn't exist yet. - next if (-e $afile); - - # Add this file to the list of files that contained this attribute. - # Generate a preprocessed file if we haven't already. - if (!(defined $ppfile)) { - $ppfile = ProcessClangFailure($Clang, $Lang, $file, - \@CmdArgsSansAnalyses, - $HtmlDir, $AttributeIgnored, $ofile); - } - - mkpath $dir; - open(AFILE, ">$afile"); - print AFILE "$ppfile\n"; - close(AFILE); - } - close CHILD; - } - } - } - - unlink($ofile); -} - -##----------------------------------------------------------------------------## -# Lookup tables. -##----------------------------------------------------------------------------## - -my %CompileOptionMap = ( - '-nostdinc' => 0, - '-fblocks' => 0, - '-fno-builtin' => 0, - '-fobjc-gc-only' => 0, - '-fobjc-gc' => 0, - '-ffreestanding' => 0, - '-include' => 1, - '-idirafter' => 1, - '-imacros' => 1, - '-iprefix' => 1, - '-iquote' => 1, - '-isystem' => 1, - '-iwithprefix' => 1, - '-iwithprefixbefore' => 1 -); - -my %LinkerOptionMap = ( - '-framework' => 1 -); - -my %CompilerLinkerOptionMap = ( - '-isysroot' => 1, - '-arch' => 1, - '-m32' => 0, - '-m64' => 0, - '-v' => 0, - '-fpascal-strings' => 0, - '-mmacosx-version-min' => 0, # This is really a 1 argument, but always has '=' - '-miphoneos-version-min' => 0 # This is really a 1 argument, but always has '=' -); - -my %IgnoredOptionMap = ( - '-MT' => 1, # Ignore these preprocessor options. - '-MF' => 1, - - '-fsyntax-only' => 0, - '-save-temps' => 0, - '-install_name' => 1, - '-exported_symbols_list' => 1, - '-current_version' => 1, - '-compatibility_version' => 1, - '-init' => 1, - '-e' => 1, - '-seg1addr' => 1, - '-bundle_loader' => 1, - '-multiply_defined' => 1, - '-sectorder' => 3, - '--param' => 1, - '-u' => 1 -); - -my %LangMap = ( - 'c' => 'c', - 'cp' => 'c++', - 'cpp' => 'c++', - 'cc' => 'c++', - 'i' => 'c-cpp-output', - 'm' => 'objective-c', - 'mi' => 'objective-c-cpp-output' -); - -my %UniqueOptions = ( - '-isysroot' => 0 -); - -##----------------------------------------------------------------------------## -# Languages accepted. -##----------------------------------------------------------------------------## - -my %LangsAccepted = ( - "objective-c" => 1, - "c" => 1 -); - -if (defined $ENV{'CCC_ANALYZER_CPLUSPLUS'}) { - $LangsAccepted{"c++"} = 1; - $LangsAccepted{"objective-c++"} = 1; -} - -##----------------------------------------------------------------------------## -# Main Logic. -##----------------------------------------------------------------------------## - -my $Action = 'link'; -my @CompileOpts; -my @LinkOpts; -my @Files; -my $Lang; -my $Output; -my %Uniqued; - -# Forward arguments to gcc. -my $Status = system($Compiler,@ARGV); -if ($Status) { exit($Status >> 8); } - -# Get the analysis options. -my $Analyses = $ENV{'CCC_ANALYZER_ANALYSIS'}; -if (!defined($Analyses)) { $Analyses = '-analyzer-check-objc-mem'; } - -# Get the store model. -my $StoreModel = $ENV{'CCC_ANALYZER_STORE_MODEL'}; -if (!defined $StoreModel) { $StoreModel = "region"; } - -# Get the constraints engine. -my $ConstraintsModel = $ENV{'CCC_ANALYZER_CONSTRAINTS_MODEL'}; -if (!defined $ConstraintsModel) { $ConstraintsModel = "range"; } - -# Get the output format. -my $OutputFormat = $ENV{'CCC_ANALYZER_OUTPUT_FORMAT'}; -if (!defined $OutputFormat) { $OutputFormat = "html"; } - -# Determine the level of verbosity. -my $Verbose = 0; -if (defined $ENV{CCC_ANALYZER_VERBOSE}) { $Verbose = 1; } -if (defined $ENV{CCC_ANALYZER_LOG}) { $Verbose = 2; } - -# Get the HTML output directory. -my $HtmlDir = $ENV{'CCC_ANALYZER_HTML'}; - -my %DisabledArchs = ('ppc' => 1, 'ppc64' => 1); -my %ArchsSeen; -my $HadArch = 0; - -# Process the arguments. -foreach (my $i = 0; $i < scalar(@ARGV); ++$i) { - my $Arg = $ARGV[$i]; - my ($ArgKey) = split /=/,$Arg,2; - - # Modes ccc-analyzer supports - if ($Arg =~ /^-(E|MM?)$/) { $Action = 'preprocess'; } - elsif ($Arg eq '-c') { $Action = 'compile'; } - elsif ($Arg =~ /^-print-prog-name/) { exit 0; } - - # Specially handle duplicate cases of -arch - if ($Arg eq "-arch") { - my $arch = $ARGV[$i+1]; - # We don't want to process 'ppc' because of Clang's lack of support - # for Altivec (also some #defines won't likely be defined correctly, etc.) - if (!(defined $DisabledArchs{$arch})) { $ArchsSeen{$arch} = 1; } - $HadArch = 1; - ++$i; - next; - } - - # Options with possible arguments that should pass through to compiler. - if (defined $CompileOptionMap{$ArgKey}) { - my $Cnt = $CompileOptionMap{$ArgKey}; - push @CompileOpts,$Arg; - while ($Cnt > 0) { ++$i; --$Cnt; push @CompileOpts, $ARGV[$i]; } - next; - } - - # Options with possible arguments that should pass through to linker. - if (defined $LinkerOptionMap{$ArgKey}) { - my $Cnt = $LinkerOptionMap{$ArgKey}; - push @LinkOpts,$Arg; - while ($Cnt > 0) { ++$i; --$Cnt; push @LinkOpts, $ARGV[$i]; } - next; - } - - # Options with possible arguments that should pass through to both compiler - # and the linker. - if (defined $CompilerLinkerOptionMap{$ArgKey}) { - my $Cnt = $CompilerLinkerOptionMap{$ArgKey}; - - # Check if this is an option that should have a unique value, and if so - # determine if the value was checked before. - if ($UniqueOptions{$Arg}) { - if (defined $Uniqued{$Arg}) { - $i += $Cnt; - next; - } - $Uniqued{$Arg} = 1; - } - - push @CompileOpts,$Arg; - push @LinkOpts,$Arg; - - while ($Cnt > 0) { - ++$i; --$Cnt; - push @CompileOpts, $ARGV[$i]; - push @LinkOpts, $ARGV[$i]; - } - next; - } - - # Ignored options. - if (defined $IgnoredOptionMap{$ArgKey}) { - my $Cnt = $IgnoredOptionMap{$ArgKey}; - while ($Cnt > 0) { - ++$i; --$Cnt; - } - next; - } - - # Compile mode flags. - if ($Arg =~ /^-[D,I,U](.*)$/) { - my $Tmp = $Arg; - if ($1 eq '') { - # FIXME: Check if we are going off the end. - ++$i; - $Tmp = $Arg . $ARGV[$i]; - } - push @CompileOpts,$Tmp; - next; - } - - # Language. - if ($Arg eq '-x') { - $Lang = $ARGV[$i+1]; - ++$i; next; - } - - # Output file. - if ($Arg eq '-o') { - ++$i; - $Output = $ARGV[$i]; - next; - } - - # Get the link mode. - if ($Arg =~ /^-[l,L,O]/) { - if ($Arg eq '-O') { push @LinkOpts,'-O1'; } - elsif ($Arg eq '-Os') { push @LinkOpts,'-O2'; } - else { push @LinkOpts,$Arg; } - next; - } - - if ($Arg =~ /^-std=/) { - push @CompileOpts,$Arg; - next; - } - -# if ($Arg =~ /^-f/) { -# # FIXME: Not sure if the remaining -fxxxx options have no arguments. -# push @CompileOpts,$Arg; -# push @LinkOpts,$Arg; # FIXME: Not sure if these are link opts. -# } - - # Get the compiler/link mode. - if ($Arg =~ /^-F(.+)$/) { - my $Tmp = $Arg; - if ($1 eq '') { - # FIXME: Check if we are going off the end. - ++$i; - $Tmp = $Arg . $ARGV[$i]; - } - push @CompileOpts,$Tmp; - push @LinkOpts,$Tmp; - next; - } - - # Input files. - if ($Arg eq '-filelist') { - # FIXME: Make sure we aren't walking off the end. - open(IN, $ARGV[$i+1]); - while (<IN>) { s/\015?\012//; push @Files,$_; } - close(IN); - ++$i; - next; - } - - # Handle -Wno-. We don't care about extra warnings, but - # we should suppress ones that we don't want to see. - if ($Arg =~ /^-Wno-/) { - push @CompileOpts, $Arg; - next; - } - - if (!($Arg =~ /^-/)) { - push @Files, $Arg; - next; - } -} - -if ($Action eq 'compile' or $Action eq 'link') { - my @Archs = keys %ArchsSeen; - # Skip the file if we don't support the architectures specified. - exit 0 if ($HadArch && scalar(@Archs) == 0); - - foreach my $file (@Files) { - # Determine the language for the file. - my $FileLang = $Lang; - - if (!defined($FileLang)) { - # Infer the language from the extension. - if ($file =~ /[.]([^.]+)$/) { - $FileLang = $LangMap{$1}; - } - } - - # FileLang still not defined? Skip the file. - next if (!defined $FileLang); - - # Language not accepted? - next if (!defined $LangsAccepted{$FileLang}); - - my @CmdArgs; - my @AnalyzeArgs; - - if ($FileLang ne 'unknown') { - push @CmdArgs,'-x'; - push @CmdArgs,$FileLang; - } - - if (defined $StoreModel) { - push @AnalyzeArgs, "-analyzer-store=$StoreModel"; - } - - if (defined $ConstraintsModel) { - push @AnalyzeArgs, "-analyzer-constraints=$ConstraintsModel"; - } - - if (defined $OutputFormat) { - push @AnalyzeArgs, "-analyzer-output=" . $OutputFormat; - if ($OutputFormat =~ /plist/) { - # Change "Output" to be a file. - my ($h, $f) = tempfile("report-XXXXXX", SUFFIX => ".plist", - DIR => $HtmlDir); - $ResultFile = $f; - $CleanupFile = $f; - } - } - - push @CmdArgs,@CompileOpts; - push @CmdArgs,$file; - - if (scalar @Archs) { - foreach my $arch (@Archs) { - my @NewArgs; - push @NewArgs, '-arch'; - push @NewArgs, $arch; - push @NewArgs, @CmdArgs; - Analyze($Clang, \@NewArgs, \@AnalyzeArgs, $FileLang, $Output, - $Verbose, $HtmlDir, $file, $Analyses); - } - } - else { - Analyze($Clang, \@CmdArgs, \@AnalyzeArgs, $FileLang, $Output, - $Verbose, $HtmlDir, $file, $Analyses); - } - } -} - -exit($Status >> 8); - diff --git a/contrib/llvm/tools/clang/tools/scan-build/scan-build b/contrib/llvm/tools/clang/tools/scan-build/scan-build deleted file mode 100755 index 8a7afbb..0000000 --- a/contrib/llvm/tools/clang/tools/scan-build/scan-build +++ /dev/null @@ -1,1265 +0,0 @@ -#!/usr/bin/env perl -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -# -# A script designed to wrap a build so that all calls to gcc are intercepted -# and piped to the static analyzer. -# -##===----------------------------------------------------------------------===## - -use strict; -use warnings; -use FindBin qw($RealBin); -use Digest::MD5; -use File::Basename; -use Term::ANSIColor; -use Term::ANSIColor qw(:constants); -use Cwd qw/ getcwd abs_path /; -use Sys::Hostname; - -my $Verbose = 0; # Verbose output from this script. -my $Prog = "scan-build"; -my $BuildName; -my $BuildDate; - -my $TERM = $ENV{'TERM'}; -my $UseColor = (defined $TERM and $TERM eq 'xterm-color' and -t STDOUT - and defined $ENV{'SCAN_BUILD_COLOR'}); - -my $UserName = HtmlEscape(getpwuid($<) || 'unknown'); -my $HostName = HtmlEscape(hostname() || 'unknown'); -my $CurrentDir = HtmlEscape(getcwd()); -my $CurrentDirSuffix = basename($CurrentDir); - -my $CmdArgs; - -my $HtmlTitle; - -my $Date = localtime(); - -##----------------------------------------------------------------------------## -# Diagnostics -##----------------------------------------------------------------------------## - -sub Diag { - if ($UseColor) { - print BOLD, MAGENTA "$Prog: @_"; - print RESET; - } - else { - print "$Prog: @_"; - } -} - -sub DiagCrashes { - my $Dir = shift; - Diag ("The analyzer encountered problems on some source files.\n"); - Diag ("Preprocessed versions of these sources were deposited in '$Dir/failures'.\n"); - Diag ("Please consider submitting a bug report using these files:\n"); - Diag (" http://clang.llvm.org/StaticAnalysisUsage.html#filingbugs\n") -} - -sub DieDiag { - if ($UseColor) { - print BOLD, RED "$Prog: "; - print RESET, RED @_; - print RESET; - } - else { - print "$Prog: ", @_; - } - exit(0); -} - -##----------------------------------------------------------------------------## -# Some initial preprocessing of Clang options. -##----------------------------------------------------------------------------## - -# Find 'clang' -my $ClangSB = Cwd::realpath("$RealBin/bin/clang"); -if (!defined $ClangSB || ! -x $ClangSB) { - $ClangSB = Cwd::realpath("$RealBin/clang"); -} -my $Clang; -if (!defined $ClangSB || ! -x $ClangSB) { - # Default to looking for 'clang' in the path. - $Clang = `which clang`; - chomp $Clang; - if ($Clang eq "") { - DieDiag("No 'clang' executable found in path."); - } -} -else { - $Clang = $ClangSB; -} -my $ClangCXX = $Clang . "++"; - -my %AvailableAnalyses; - -# Query clang for analysis options. -open(PIPE, "-|", $Clang, "-cc1", "-help") or - DieDiag("Cannot execute '$Clang'\n"); - -while(<PIPE>) { - if (/(-analyzer-check-[^\s]+)/) { - $AvailableAnalyses{$1} = 1; - next; - } -} -close (PIPE); - -my %AnalysesDefaultEnabled = ( - '-analyzer-check-dead-stores' => 1, - '-analyzer-check-objc-mem' => 1, - '-analyzer-check-objc-methodsigs' => 1, - # Do not enable the missing -dealloc check by default. - # '-analyzer-check-objc-missing-dealloc' => 1, - '-analyzer-check-objc-unused-ivars' => 1, - '-analyzer-check-security-syntactic' => 1 -); - -##----------------------------------------------------------------------------## -# GetHTMLRunDir - Construct an HTML directory name for the current sub-run. -##----------------------------------------------------------------------------## - -sub GetHTMLRunDir { - die "Not enough arguments." if (@_ == 0); - my $Dir = shift @_; - my $TmpMode = 0; - if (!defined $Dir) { - if (`uname` =~ /Darwin/) { - $Dir = $ENV{'TMPDIR'}; - if (!defined $Dir) { $Dir = "/tmp"; } - } - else { - $Dir = "/tmp"; - } - $TmpMode = 1; - } - - # Chop off any trailing '/' characters. - while ($Dir =~ /\/$/) { chop $Dir; } - - # Get current date and time. - my @CurrentTime = localtime(); - my $year = $CurrentTime[5] + 1900; - my $day = $CurrentTime[3]; - my $month = $CurrentTime[4] + 1; - my $DateString = sprintf("%d-%02d-%02d", $year, $month, $day); - - # Determine the run number. - my $RunNumber; - - if (-d $Dir) { - if (! -r $Dir) { - DieDiag("directory '$Dir' exists but is not readable.\n"); - } - # Iterate over all files in the specified directory. - my $max = 0; - opendir(DIR, $Dir); - my @FILES = grep { -d "$Dir/$_" } readdir(DIR); - closedir(DIR); - - foreach my $f (@FILES) { - # Strip the prefix '$Prog-' if we are dumping files to /tmp. - if ($TmpMode) { - next if (!($f =~ /^$Prog-(.+)/)); - $f = $1; - } - - my @x = split/-/, $f; - next if (scalar(@x) != 4); - next if ($x[0] != $year); - next if ($x[1] != $month); - next if ($x[2] != $day); - - if ($x[3] > $max) { - $max = $x[3]; - } - } - - $RunNumber = $max + 1; - } - else { - - if (-x $Dir) { - DieDiag("'$Dir' exists but is not a directory.\n"); - } - - if ($TmpMode) { - DieDiag("The directory '/tmp' does not exist or cannot be accessed.\n"); - } - - # $Dir does not exist. It will be automatically created by the - # clang driver. Set the run number to 1. - - $RunNumber = 1; - } - - die "RunNumber must be defined!" if (!defined $RunNumber); - - # Append the run number. - my $NewDir; - if ($TmpMode) { - $NewDir = "$Dir/$Prog-$DateString-$RunNumber"; - } - else { - $NewDir = "$Dir/$DateString-$RunNumber"; - } - system 'mkdir','-p',$NewDir; - return $NewDir; -} - -sub SetHtmlEnv { - - die "Wrong number of arguments." if (scalar(@_) != 2); - - my $Args = shift; - my $Dir = shift; - - die "No build command." if (scalar(@$Args) == 0); - - my $Cmd = $$Args[0]; - - if ($Cmd =~ /configure/) { - return; - } - - if ($Verbose) { - Diag("Emitting reports for this run to '$Dir'.\n"); - } - - $ENV{'CCC_ANALYZER_HTML'} = $Dir; -} - -##----------------------------------------------------------------------------## -# ComputeDigest - Compute a digest of the specified file. -##----------------------------------------------------------------------------## - -sub ComputeDigest { - my $FName = shift; - DieDiag("Cannot read $FName to compute Digest.\n") if (! -r $FName); - - # Use Digest::MD5. We don't have to be cryptographically secure. We're - # just looking for duplicate files that come from a non-malicious source. - # We use Digest::MD5 because it is a standard Perl module that should - # come bundled on most systems. - open(FILE, $FName) or DieDiag("Cannot open $FName when computing Digest.\n"); - binmode FILE; - my $Result = Digest::MD5->new->addfile(*FILE)->hexdigest; - close(FILE); - - # Return the digest. - return $Result; -} - -##----------------------------------------------------------------------------## -# UpdatePrefix - Compute the common prefix of files. -##----------------------------------------------------------------------------## - -my $Prefix; - -sub UpdatePrefix { - my $x = shift; - my $y = basename($x); - $x =~ s/\Q$y\E$//; - - if (!defined $Prefix) { - $Prefix = $x; - return; - } - - chop $Prefix while (!($x =~ /^\Q$Prefix/)); -} - -sub GetPrefix { - return $Prefix; -} - -##----------------------------------------------------------------------------## -# UpdateInFilePath - Update the path in the report file. -##----------------------------------------------------------------------------## - -sub UpdateInFilePath { - my $fname = shift; - my $regex = shift; - my $newtext = shift; - - open (RIN, $fname) or die "cannot open $fname"; - open (ROUT, ">", "$fname.tmp") or die "cannot open $fname.tmp"; - - while (<RIN>) { - s/$regex/$newtext/; - print ROUT $_; - } - - close (ROUT); - close (RIN); - system("mv", "$fname.tmp", $fname); -} - -##----------------------------------------------------------------------------## -# ScanFile - Scan a report file for various identifying attributes. -##----------------------------------------------------------------------------## - -# Sometimes a source file is scanned more than once, and thus produces -# multiple error reports. We use a cache to solve this problem. - -my %AlreadyScanned; - -sub ScanFile { - - my $Index = shift; - my $Dir = shift; - my $FName = shift; - - # Compute a digest for the report file. Determine if we have already - # scanned a file that looks just like it. - - my $digest = ComputeDigest("$Dir/$FName"); - - if (defined $AlreadyScanned{$digest}) { - # Redundant file. Remove it. - system ("rm", "-f", "$Dir/$FName"); - return; - } - - $AlreadyScanned{$digest} = 1; - - # At this point the report file is not world readable. Make it happen. - system ("chmod", "644", "$Dir/$FName"); - - # Scan the report file for tags. - open(IN, "$Dir/$FName") or DieDiag("Cannot open '$Dir/$FName'\n"); - - my $BugType = ""; - my $BugFile = ""; - my $BugCategory; - my $BugPathLength = 1; - my $BugLine = 0; - - while (<IN>) { - last if (/<!-- BUGMETAEND -->/); - - if (/<!-- BUGTYPE (.*) -->$/) { - $BugType = $1; - } - elsif (/<!-- BUGFILE (.*) -->$/) { - $BugFile = abs_path($1); - UpdatePrefix($BugFile); - } - elsif (/<!-- BUGPATHLENGTH (.*) -->$/) { - $BugPathLength = $1; - } - elsif (/<!-- BUGLINE (.*) -->$/) { - $BugLine = $1; - } - elsif (/<!-- BUGCATEGORY (.*) -->$/) { - $BugCategory = $1; - } - } - - close(IN); - - if (!defined $BugCategory) { - $BugCategory = "Other"; - } - - push @$Index,[ $FName, $BugCategory, $BugType, $BugFile, $BugLine, - $BugPathLength ]; -} - -##----------------------------------------------------------------------------## -# CopyFiles - Copy resource files to target directory. -##----------------------------------------------------------------------------## - -sub CopyFiles { - - my $Dir = shift; - - my $JS = Cwd::realpath("$RealBin/sorttable.js"); - - DieDiag("Cannot find 'sorttable.js'.\n") - if (! -r $JS); - - system ("cp", $JS, "$Dir"); - - DieDiag("Could not copy 'sorttable.js' to '$Dir'.\n") - if (! -r "$Dir/sorttable.js"); - - my $CSS = Cwd::realpath("$RealBin/scanview.css"); - - DieDiag("Cannot find 'scanview.css'.\n") - if (! -r $CSS); - - system ("cp", $CSS, "$Dir"); - - DieDiag("Could not copy 'scanview.css' to '$Dir'.\n") - if (! -r $CSS); -} - -##----------------------------------------------------------------------------## -# Postprocess - Postprocess the results of an analysis scan. -##----------------------------------------------------------------------------## - -sub Postprocess { - - my $Dir = shift; - my $BaseDir = shift; - - die "No directory specified." if (!defined $Dir); - - if (! -d $Dir) { - Diag("No bugs found.\n"); - return 0; - } - - opendir(DIR, $Dir); - my @files = grep { /^report-.*\.html$/ } readdir(DIR); - closedir(DIR); - - if (scalar(@files) == 0 and ! -e "$Dir/failures") { - Diag("Removing directory '$Dir' because it contains no reports.\n"); - system ("rm", "-fR", $Dir); - return 0; - } - - # Scan each report file and build an index. - my @Index; - foreach my $file (@files) { ScanFile(\@Index, $Dir, $file); } - - # Scan the failures directory and use the information in the .info files - # to update the common prefix directory. - my @failures; - my @attributes_ignored; - if (-d "$Dir/failures") { - opendir(DIR, "$Dir/failures"); - @failures = grep { /[.]info.txt$/ && !/attribute_ignored/; } readdir(DIR); - closedir(DIR); - opendir(DIR, "$Dir/failures"); - @attributes_ignored = grep { /^attribute_ignored/; } readdir(DIR); - closedir(DIR); - foreach my $file (@failures) { - open IN, "$Dir/failures/$file" or DieDiag("cannot open $file\n"); - my $Path = <IN>; - if (defined $Path) { UpdatePrefix($Path); } - close IN; - } - } - - # Generate an index.html file. - my $FName = "$Dir/index.html"; - open(OUT, ">", $FName) or DieDiag("Cannot create file '$FName'\n"); - - # Print out the header. - -print OUT <<ENDTEXT; -<html> -<head> -<title>${HtmlTitle}</title> -<link type="text/css" rel="stylesheet" href="scanview.css"/> -<script src="sorttable.js"></script> -<script language='javascript' type="text/javascript"> -function SetDisplay(RowClass, DisplayVal) -{ - var Rows = document.getElementsByTagName("tr"); - for ( var i = 0 ; i < Rows.length; ++i ) { - if (Rows[i].className == RowClass) { - Rows[i].style.display = DisplayVal; - } - } -} - -function CopyCheckedStateToCheckButtons(SummaryCheckButton) { - var Inputs = document.getElementsByTagName("input"); - for ( var i = 0 ; i < Inputs.length; ++i ) { - if (Inputs[i].type == "checkbox") { - if(Inputs[i] != SummaryCheckButton) { - Inputs[i].checked = SummaryCheckButton.checked; - Inputs[i].onclick(); - } - } - } -} - -function returnObjById( id ) { - if (document.getElementById) - var returnVar = document.getElementById(id); - else if (document.all) - var returnVar = document.all[id]; - else if (document.layers) - var returnVar = document.layers[id]; - return returnVar; -} - -var NumUnchecked = 0; - -function ToggleDisplay(CheckButton, ClassName) { - if (CheckButton.checked) { - SetDisplay(ClassName, ""); - if (--NumUnchecked == 0) { - returnObjById("AllBugsCheck").checked = true; - } - } - else { - SetDisplay(ClassName, "none"); - NumUnchecked++; - returnObjById("AllBugsCheck").checked = false; - } -} -</script> -<!-- SUMMARYENDHEAD --> -</head> -<body> -<h1>${HtmlTitle}</h1> - -<table> -<tr><th>User:</th><td>${UserName}\@${HostName}</td></tr> -<tr><th>Working Directory:</th><td>${CurrentDir}</td></tr> -<tr><th>Command Line:</th><td>${CmdArgs}</td></tr> -<tr><th>Date:</th><td>${Date}</td></tr> -ENDTEXT - -print OUT "<tr><th>Version:</th><td>${BuildName} (${BuildDate})</td></tr>\n" - if (defined($BuildName) && defined($BuildDate)); - -print OUT <<ENDTEXT; -</table> -ENDTEXT - - if (scalar(@files)) { - # Print out the summary table. - my %Totals; - - for my $row ( @Index ) { - my $bug_type = ($row->[2]); - my $bug_category = ($row->[1]); - my $key = "$bug_category:$bug_type"; - - if (!defined $Totals{$key}) { $Totals{$key} = [1,$bug_category,$bug_type]; } - else { $Totals{$key}->[0]++; } - } - - print OUT "<h2>Bug Summary</h2>"; - - if (defined $BuildName) { - print OUT "\n<p>Results in this analysis run are based on analyzer build <b>$BuildName</b>.</p>\n" - } - - my $TotalBugs = scalar(@Index); -print OUT <<ENDTEXT; -<table> -<thead><tr><td>Bug Type</td><td>Quantity</td><td class="sorttable_nosort">Display?</td></tr></thead> -<tr style="font-weight:bold"><td class="SUMM_DESC">All Bugs</td><td class="Q">$TotalBugs</td><td><center><input type="checkbox" id="AllBugsCheck" onClick="CopyCheckedStateToCheckButtons(this);" checked/></center></td></tr> -ENDTEXT - - my $last_category; - - for my $key ( - sort { - my $x = $Totals{$a}; - my $y = $Totals{$b}; - my $res = $x->[1] cmp $y->[1]; - $res = $x->[2] cmp $y->[2] if ($res == 0); - $res - } keys %Totals ) - { - my $val = $Totals{$key}; - my $category = $val->[1]; - if (!defined $last_category or $last_category ne $category) { - $last_category = $category; - print OUT "<tr><th>$category</th><th colspan=2></th></tr>\n"; - } - my $x = lc $key; - $x =~ s/[ ,'":\/()]+/_/g; - print OUT "<tr><td class=\"SUMM_DESC\">"; - print OUT $val->[2]; - print OUT "</td><td class=\"Q\">"; - print OUT $val->[0]; - print OUT "</td><td><center><input type=\"checkbox\" onClick=\"ToggleDisplay(this,'bt_$x');\" checked/></center></td></tr>\n"; - } - - # Print out the table of errors. - -print OUT <<ENDTEXT; -</table> -<h2>Reports</h2> - -<table class="sortable" style="table-layout:automatic"> -<thead><tr> - <td>Bug Group</td> - <td class="sorttable_sorted">Bug Type<span id="sorttable_sortfwdind"> ▾</span></td> - <td>File</td> - <td class="Q">Line</td> - <td class="Q">Path Length</td> - <td class="sorttable_nosort"></td> - <!-- REPORTBUGCOL --> -</tr></thead> -<tbody> -ENDTEXT - - my $prefix = GetPrefix(); - my $regex; - my $InFileRegex; - my $InFilePrefix = "File:</td><td>"; - - if (defined $prefix) { - $regex = qr/^\Q$prefix\E/is; - $InFileRegex = qr/\Q$InFilePrefix$prefix\E/is; - } - - for my $row ( sort { $a->[2] cmp $b->[2] } @Index ) { - my $x = "$row->[1]:$row->[2]"; - $x = lc $x; - $x =~ s/[ ,'":\/()]+/_/g; - - my $ReportFile = $row->[0]; - - print OUT "<tr class=\"bt_$x\">"; - print OUT "<td class=\"DESC\">"; - print OUT $row->[1]; - print OUT "</td>"; - print OUT "<td class=\"DESC\">"; - print OUT $row->[2]; - print OUT "</td>"; - - # Update the file prefix. - my $fname = $row->[3]; - - if (defined $regex) { - $fname =~ s/$regex//; - UpdateInFilePath("$Dir/$ReportFile", $InFileRegex, $InFilePrefix) - } - - print OUT "<td>"; - my @fname = split /\//,$fname; - if ($#fname > 0) { - while ($#fname >= 0) { - my $x = shift @fname; - print OUT $x; - if ($#fname >= 0) { - print OUT "<span class=\"W\"> </span>/"; - } - } - } - else { - print OUT $fname; - } - print OUT "</td>"; - - # Print out the quantities. - for my $j ( 4 .. 5 ) { - print OUT "<td class=\"Q\">$row->[$j]</td>"; - } - - # Print the rest of the columns. - for (my $j = 6; $j <= $#{$row}; ++$j) { - print OUT "<td>$row->[$j]</td>" - } - - # Emit the "View" link. - print OUT "<td><a href=\"$ReportFile#EndPath\">View Report</a></td>"; - - # Emit REPORTBUG markers. - print OUT "\n<!-- REPORTBUG id=\"$ReportFile\" -->\n"; - - # End the row. - print OUT "</tr>\n"; - } - - print OUT "</tbody>\n</table>\n\n"; - } - - if (scalar (@failures) || scalar(@attributes_ignored)) { - print OUT "<h2>Analyzer Failures</h2>\n"; - - if (scalar @attributes_ignored) { - print OUT "The analyzer's parser ignored the following attributes:<p>\n"; - print OUT "<table>\n"; - print OUT "<thead><tr><td>Attribute</td><td>Source File</td><td>Preprocessed File</td><td>STDERR Output</td></tr></thead>\n"; - foreach my $file (sort @attributes_ignored) { - die "cannot demangle attribute name\n" if (! ($file =~ /^attribute_ignored_(.+).txt/)); - my $attribute = $1; - # Open the attribute file to get the first file that failed. - next if (!open (ATTR, "$Dir/failures/$file")); - my $ppfile = <ATTR>; - chomp $ppfile; - close ATTR; - next if (! -e "$Dir/failures/$ppfile"); - # Open the info file and get the name of the source file. - open (INFO, "$Dir/failures/$ppfile.info.txt") or - die "Cannot open $Dir/failures/$ppfile.info.txt\n"; - my $srcfile = <INFO>; - chomp $srcfile; - close (INFO); - # Print the information in the table. - my $prefix = GetPrefix(); - if (defined $prefix) { $srcfile =~ s/^\Q$prefix//; } - print OUT "<tr><td>$attribute</td><td>$srcfile</td><td><a href=\"failures/$ppfile\">$ppfile</a></td><td><a href=\"failures/$ppfile.stderr.txt\">$ppfile.stderr.txt</a></td></tr>\n"; - my $ppfile_clang = $ppfile; - $ppfile_clang =~ s/[.](.+)$/.clang.$1/; - print OUT " <!-- REPORTPROBLEM src=\"$srcfile\" file=\"failures/$ppfile\" clangfile=\"failures/$ppfile_clang\" stderr=\"failures/$ppfile.stderr.txt\" info=\"failures/$ppfile.info.txt\" -->\n"; - } - print OUT "</table>\n"; - } - - if (scalar @failures) { - print OUT "<p>The analyzer had problems processing the following files:</p>\n"; - print OUT "<table>\n"; - print OUT "<thead><tr><td>Problem</td><td>Source File</td><td>Preprocessed File</td><td>STDERR Output</td></tr></thead>\n"; - foreach my $file (sort @failures) { - $file =~ /(.+).info.txt$/; - # Get the preprocessed file. - my $ppfile = $1; - # Open the info file and get the name of the source file. - open (INFO, "$Dir/failures/$file") or - die "Cannot open $Dir/failures/$file\n"; - my $srcfile = <INFO>; - chomp $srcfile; - my $problem = <INFO>; - chomp $problem; - close (INFO); - # Print the information in the table. - my $prefix = GetPrefix(); - if (defined $prefix) { $srcfile =~ s/^\Q$prefix//; } - print OUT "<tr><td>$problem</td><td>$srcfile</td><td><a href=\"failures/$ppfile\">$ppfile</a></td><td><a href=\"failures/$ppfile.stderr.txt\">$ppfile.stderr.txt</a></td></tr>\n"; - my $ppfile_clang = $ppfile; - $ppfile_clang =~ s/[.](.+)$/.clang.$1/; - print OUT " <!-- REPORTPROBLEM src=\"$srcfile\" file=\"failures/$ppfile\" clangfile=\"failures/$ppfile_clang\" stderr=\"failures/$ppfile.stderr.txt\" info=\"failures/$ppfile.info.txt\" -->\n"; - } - print OUT "</table>\n"; - } - print OUT "<p>Please consider submitting preprocessed files as <a href=\"http://clang.llvm.org/StaticAnalysisUsage.html#filingbugs\">bug reports</a>. <!-- REPORTCRASHES --> </p>\n"; - } - - print OUT "</body></html>\n"; - close(OUT); - CopyFiles($Dir); - - # Make sure $Dir and $BaseDir are world readable/executable. - system("chmod", "755", $Dir); - if (defined $BaseDir) { system("chmod", "755", $BaseDir); } - - my $Num = scalar(@Index); - Diag("$Num bugs found.\n"); - if ($Num > 0 && -r "$Dir/index.html") { - Diag("Run 'scan-view $Dir' to examine bug reports.\n"); - } - - DiagCrashes($Dir) if (scalar @failures || scalar @attributes_ignored); - - return $Num; -} - -##----------------------------------------------------------------------------## -# RunBuildCommand - Run the build command. -##----------------------------------------------------------------------------## - -sub AddIfNotPresent { - my $Args = shift; - my $Arg = shift; - my $found = 0; - - foreach my $k (@$Args) { - if ($k eq $Arg) { - $found = 1; - last; - } - } - - if ($found == 0) { - push @$Args, $Arg; - } -} - -sub RunBuildCommand { - - my $Args = shift; - my $IgnoreErrors = shift; - my $Cmd = $Args->[0]; - my $CCAnalyzer = shift; - my $CXXAnalyzer = shift; - - # Get only the part of the command after the last '/'. - if ($Cmd =~ /\/([^\/]+)$/) { - $Cmd = $1; - } - - if ($Cmd =~ /(.*\/?gcc[^\/]*$)/ or - $Cmd =~ /(.*\/?cc[^\/]*$)/ or - $Cmd =~ /(.*\/?llvm-gcc[^\/]*$)/ or - $Cmd =~ /(.*\/?ccc-analyzer[^\/]*$)/) { - - if (!($Cmd =~ /ccc-analyzer/) and !defined $ENV{"CCC_CC"}) { - $ENV{"CCC_CC"} = $1; - } - - shift @$Args; - unshift @$Args, $CCAnalyzer; - } - elsif ($Cmd =~ /(.*\/?g\+\+[^\/]*$)/ or - $Cmd =~ /(.*\/?c\+\+[^\/]*$)/ or - $Cmd =~ /(.*\/?llvm-g\+\+[^\/]*$)/ or - $Cmd =~ /(.*\/?c\+\+-analyzer[^\/]*$)/) { - if (!($Cmd =~ /c\+\+-analyzer/) and !defined $ENV{"CCC_CXX"}) { - $ENV{"CCC_CXX"} = $1; - } - shift @$Args; - unshift @$Args, $CXXAnalyzer; - } - elsif ($IgnoreErrors) { - if ($Cmd eq "make" or $Cmd eq "gmake") { - AddIfNotPresent($Args, "CC=$CCAnalyzer"); - AddIfNotPresent($Args, "CXX=$CXXAnalyzer"); - AddIfNotPresent($Args,"-k"); - AddIfNotPresent($Args,"-i"); - } - elsif ($Cmd eq "xcodebuild") { - AddIfNotPresent($Args,"-PBXBuildsContinueAfterErrors=YES"); - } - } - - if ($Cmd eq "xcodebuild") { - # Check if using iPhone SDK 3.0 (simulator). If so the compiler being - # used should be gcc-4.2. - if (!defined $ENV{"CCC_CC"}) { - for (my $i = 0 ; $i < scalar(@$Args); ++$i) { - if ($Args->[$i] eq "-sdk" && $i + 1 < scalar(@$Args)) { - if (@$Args[$i+1] =~ /^iphonesimulator3/) { - $ENV{"CCC_CC"} = "gcc-4.2"; - $ENV{"CCC_CXX"} = "g++-4.2"; - } - } - } - } - - # Disable distributed builds for xcodebuild. - AddIfNotPresent($Args,"-nodistribute"); - - # Disable PCH files until clang supports them. - AddIfNotPresent($Args,"GCC_PRECOMPILE_PREFIX_HEADER=NO"); - - # When 'CC' is set, xcodebuild uses it to do all linking, even if we are - # linking C++ object files. Set 'LDPLUSPLUS' so that xcodebuild uses 'g++' - # (via c++-analyzer) when linking such files. - $ENV{"LDPLUSPLUS"} = $CXXAnalyzer; - } - - return (system(@$Args) >> 8); -} - -##----------------------------------------------------------------------------## -# DisplayHelp - Utility function to display all help options. -##----------------------------------------------------------------------------## - -sub DisplayHelp { - -print <<ENDTEXT; -USAGE: $Prog [options] <build command> [build options] - -ENDTEXT - - if (defined $BuildName) { - print "ANALYZER BUILD: $BuildName ($BuildDate)\n\n"; - } - -print <<ENDTEXT; -OPTIONS: - - -analyze-headers - Also analyze functions in #included files. - - --experimental-checks - Enable experimental checks that are currently in heavy testing - - -o - Target directory for HTML report files. Subdirectories - will be created as needed to represent separate "runs" of - the analyzer. If this option is not specified, a directory - is created in /tmp (TMPDIR on Mac OS X) to store the reports. - - -h - Display this message. - --help - - -k - Add a "keep on going" option to the specified build command. - --keep-going This option currently supports make and xcodebuild. - This is a convenience option; one can specify this - behavior directly using build options. - - --html-title [title] - Specify the title used on generated HTML pages. - --html-title=[title] If not specified, a default title will be used. - - -plist - By default the output of scan-build is a set of HTML files. - This option outputs the results as a set of .plist files. - - --status-bugs - By default, the exit status of $Prog is the same as the - executed build command. Specifying this option causes the - exit status of $Prog to be 1 if it found potential bugs - and 0 otherwise. - - --use-cc [compiler path] - By default, $Prog uses 'gcc' to compile and link - --use-cc=[compiler path] your C and Objective-C code. Use this option - to specify an alternate compiler. - - --use-c++ [compiler path] - By default, $Prog uses 'g++' to compile and link - --use-c++=[compiler path] your C++ and Objective-C++ code. Use this option - to specify an alternate compiler. - - -v - Verbose output from $Prog and the analyzer. - A second and third '-v' increases verbosity. - - -V - View analysis results in a web browser when the build - --view completes. - -ADVANCED OPTIONS: - - -constraints [model] - Specify the contraint engine used by the analyzer. - By default the 'range' model is used. Specifying - 'basic' uses a simpler, less powerful constraint model - used by checker-0.160 and earlier. - - -store [model] - Specify the store model used by the analyzer. By default, - the 'region' store model is used. 'region' specifies a field- - sensitive store model. Users can also specify 'basic', which - is far less precise but can more quickly analyze code. - 'basic' was the default store model for checker-0.221 and - earlier. - - -no-failure-reports - Do not create a 'failures' subdirectory that includes - analyzer crash reports and preprocessed source files. - -AVAILABLE ANALYSES (multiple analyses may be specified): - -ENDTEXT - - foreach my $Analysis (sort keys %AvailableAnalyses) { - if (defined $AnalysesDefaultEnabled{$Analysis}) { - print " (+)"; - } - else { - print " "; - } - - print " $Analysis\n"; - } - -print <<ENDTEXT - - NOTE: "(+)" indicates that an analysis is enabled by default unless one - or more analysis options are specified - -BUILD OPTIONS - - You can specify any build option acceptable to the build command. - -EXAMPLE - - $Prog -o /tmp/myhtmldir make -j4 - - The above example causes analysis reports to be deposited into - a subdirectory of "/tmp/myhtmldir" and to run "make" with the "-j4" option. - A different subdirectory is created each time $Prog analyzes a project. - The analyzer should support most parallel builds, but not distributed builds. - -ENDTEXT -} - -##----------------------------------------------------------------------------## -# HtmlEscape - HTML entity encode characters that are special in HTML -##----------------------------------------------------------------------------## - -sub HtmlEscape { - # copy argument to new variable so we don't clobber the original - my $arg = shift || ''; - my $tmp = $arg; - $tmp =~ s/&/&/g; - $tmp =~ s/</</g; - $tmp =~ s/>/>/g; - return $tmp; -} - -##----------------------------------------------------------------------------## -# ShellEscape - backslash escape characters that are special to the shell -##----------------------------------------------------------------------------## - -sub ShellEscape { - # copy argument to new variable so we don't clobber the original - my $arg = shift || ''; - if ($arg =~ /["\s]/) { return "'" . $arg . "'"; } - return $arg; -} - -##----------------------------------------------------------------------------## -# Process command-line arguments. -##----------------------------------------------------------------------------## - -my $AnalyzeHeaders = 0; -my $HtmlDir; # Parent directory to store HTML files. -my $IgnoreErrors = 0; # Ignore build errors. -my $ViewResults = 0; # View results when the build terminates. -my $ExitStatusFoundBugs = 0; # Exit status reflects whether bugs were found -my @AnalysesToRun; -my $StoreModel; -my $ConstraintsModel; -my $OutputFormat = "html"; - -if (!@ARGV) { - DisplayHelp(); - exit 1; -} - -while (@ARGV) { - - # Scan for options we recognize. - - my $arg = $ARGV[0]; - - if ($arg eq "-h" or $arg eq "--help") { - DisplayHelp(); - exit 0; - } - - if ($arg eq '-analyze-headers') { - shift @ARGV; - $AnalyzeHeaders = 1; - next; - } - - if (defined $AvailableAnalyses{$arg}) { - shift @ARGV; - push @AnalysesToRun, $arg; - next; - } - - if ($arg eq "-o") { - shift @ARGV; - - if (!@ARGV) { - DieDiag("'-o' option requires a target directory name.\n"); - } - - # Construct an absolute path. Uses the current working directory - # as a base if the original path was not absolute. - $HtmlDir = abs_path(shift @ARGV); - - next; - } - - if ($arg =~ /^--html-title(=(.+))?$/) { - shift @ARGV; - - if (!defined $2 || $2 eq '') { - if (!@ARGV) { - DieDiag("'--html-title' option requires a string.\n"); - } - - $HtmlTitle = shift @ARGV; - } else { - $HtmlTitle = $2; - } - - next; - } - - if ($arg eq "-k" or $arg eq "--keep-going") { - shift @ARGV; - $IgnoreErrors = 1; - next; - } - - if ($arg eq "--experimental-checks") { - shift @ARGV; - $ENV{"CCC_EXPERIMENTAL_CHECKS"} = 1; - next; - } - - if ($arg =~ /^--use-cc(=(.+))?$/) { - shift @ARGV; - my $cc; - - if (!defined $2 || $2 eq "") { - if (!@ARGV) { - DieDiag("'--use-cc' option requires a compiler executable name.\n"); - } - $cc = shift @ARGV; - } - else { - $cc = $2; - } - - $ENV{"CCC_CC"} = $cc; - next; - } - - if ($arg =~ /^--use-c\+\+(=(.+))?$/) { - shift @ARGV; - my $cxx; - - if (!defined $2 || $2 eq "") { - if (!@ARGV) { - DieDiag("'--use-c++' option requires a compiler executable name.\n"); - } - $cxx = shift @ARGV; - } - else { - $cxx = $2; - } - - $ENV{"CCC_CXX"} = $cxx; - next; - } - - if ($arg eq "-v") { - shift @ARGV; - $Verbose++; - next; - } - - if ($arg eq "-V" or $arg eq "--view") { - shift @ARGV; - $ViewResults = 1; - next; - } - - if ($arg eq "--status-bugs") { - shift @ARGV; - $ExitStatusFoundBugs = 1; - next; - } - - if ($arg eq "-store") { - shift @ARGV; - $StoreModel = shift @ARGV; - next; - } - - if ($arg eq "-constraints") { - shift @ARGV; - $ConstraintsModel = shift @ARGV; - next; - } - - if ($arg eq "-plist") { - shift @ARGV; - $OutputFormat = "plist"; - next; - } - if ($arg eq "-plist-html") { - shift @ARGV; - $OutputFormat = "plist-html"; - next; - } - - if ($arg eq "-no-failure-reports") { - $ENV{"CCC_REPORT_FAILURES"} = 0; - next; - } - - DieDiag("unrecognized option '$arg'\n") if ($arg =~ /^-/); - - last; -} - -if (!@ARGV) { - Diag("No build command specified.\n\n"); - DisplayHelp(); - exit 1; -} - -$CmdArgs = HtmlEscape(join(' ', map(ShellEscape($_), @ARGV))); -$HtmlTitle = "${CurrentDirSuffix} - scan-build results" - unless (defined($HtmlTitle)); - -# Determine the output directory for the HTML reports. -my $BaseDir = $HtmlDir; -$HtmlDir = GetHTMLRunDir($HtmlDir); - -# Set the appropriate environment variables. -SetHtmlEnv(\@ARGV, $HtmlDir); - -my $AbsRealBin = Cwd::realpath($RealBin); -my $Cmd = "$AbsRealBin/libexec/ccc-analyzer"; -my $CmdCXX = "$AbsRealBin/libexec/c++-analyzer"; - -if (!defined $Cmd || ! -x $Cmd) { - $Cmd = "$AbsRealBin/ccc-analyzer"; - DieDiag("Executable 'ccc-analyzer' does not exist at '$Cmd'\n") if(! -x $Cmd); -} -if (!defined $CmdCXX || ! -x $CmdCXX) { - $CmdCXX = "$AbsRealBin/c++-analyzer"; - DieDiag("Executable 'c++-analyzer' does not exist at '$CmdCXX'\n") if(! -x $CmdCXX); -} - -if (!defined $ClangSB || ! -x $ClangSB) { - Diag("'clang' executable not found in '$RealBin/bin'.\n"); - Diag("Using 'clang' from path: $Clang\n"); -} - -$ENV{'CC'} = $Cmd; -$ENV{'CXX'} = $CmdCXX; -$ENV{'CLANG'} = $Clang; -$ENV{'CLANG_CXX'} = $ClangCXX; - -if ($Verbose >= 2) { - $ENV{'CCC_ANALYZER_VERBOSE'} = 1; -} - -if ($Verbose >= 3) { - $ENV{'CCC_ANALYZER_LOG'} = 1; -} - -if (scalar(@AnalysesToRun) == 0) { - foreach my $key (keys %AnalysesDefaultEnabled) { - push @AnalysesToRun,$key; - } -} - -if ($AnalyzeHeaders) { - push @AnalysesToRun,"-analyzer-opt-analyze-headers"; -} - -$ENV{'CCC_ANALYZER_ANALYSIS'} = join ' ',@AnalysesToRun; - -if (defined $StoreModel) { - $ENV{'CCC_ANALYZER_STORE_MODEL'} = $StoreModel; -} - -if (defined $ConstraintsModel) { - $ENV{'CCC_ANALYZER_CONSTRAINTS_MODEL'} = $ConstraintsModel; -} - -if (defined $OutputFormat) { - $ENV{'CCC_ANALYZER_OUTPUT_FORMAT'} = $OutputFormat; -} - -# Run the build. -my $ExitStatus = RunBuildCommand(\@ARGV, $IgnoreErrors, $Cmd, $CmdCXX); - -if (defined $OutputFormat) { - if ($OutputFormat =~ /plist/) { - Diag "Analysis run complete.\n"; - Diag "Analysis results (plist files) deposited in '$HtmlDir'\n"; - } - elsif ($OutputFormat =~ /html/) { - # Postprocess the HTML directory. - my $NumBugs = Postprocess($HtmlDir, $BaseDir); - - if ($ViewResults and -r "$HtmlDir/index.html") { - Diag "Analysis run complete.\n"; - Diag "Viewing analysis results in '$HtmlDir' using scan-view.\n"; - my $ScanView = Cwd::realpath("$RealBin/scan-view"); - if (! -x $ScanView) { $ScanView = "scan-view"; } - exec $ScanView, "$HtmlDir"; - } - - if ($ExitStatusFoundBugs) { - exit 1 if ($NumBugs > 0); - exit 0; - } - } -} - -exit $ExitStatus; - diff --git a/contrib/llvm/tools/clang/tools/scan-build/scanview.css b/contrib/llvm/tools/clang/tools/scan-build/scanview.css deleted file mode 100644 index a0406f3..0000000 --- a/contrib/llvm/tools/clang/tools/scan-build/scanview.css +++ /dev/null @@ -1,62 +0,0 @@ -body { color:#000000; background-color:#ffffff } -body { font-family: Helvetica, sans-serif; font-size:9pt } -h1 { font-size: 14pt; } -h2 { font-size: 12pt; } -table { font-size:9pt } -table { border-spacing: 0px; border: 1px solid black } -th, table thead { - background-color:#eee; color:#666666; - font-weight: bold; cursor: default; - text-align:center; - font-weight: bold; font-family: Verdana; - white-space:nowrap; -} -.W { font-size:0px } -th, td { padding:5px; padding-left:8px; text-align:left } -td.SUMM_DESC { padding-left:12px } -td.DESC { white-space:pre } -td.Q { text-align:right } -td { text-align:left } -tbody.scrollContent { overflow:auto } - -table.form_group { - background-color: #ccc; - border: 1px solid #333; - padding: 2px; -} - -table.form_inner_group { - background-color: #ccc; - border: 1px solid #333; - padding: 0px; -} - -table.form { - background-color: #999; - border: 1px solid #333; - padding: 2px; -} - -td.form_label { - text-align: right; - vertical-align: top; -} -/* For one line entires */ -td.form_clabel { - text-align: right; - vertical-align: center; -} -td.form_value { - text-align: left; - vertical-align: top; -} -td.form_submit { - text-align: right; - vertical-align: top; -} - -h1.SubmitFail { - color: #f00; -} -h1.SubmitOk { -} diff --git a/contrib/llvm/tools/clang/tools/scan-build/set-xcode-analyzer b/contrib/llvm/tools/clang/tools/scan-build/set-xcode-analyzer deleted file mode 100755 index cc068a5..0000000 --- a/contrib/llvm/tools/clang/tools/scan-build/set-xcode-analyzer +++ /dev/null @@ -1,77 +0,0 @@ -#!/usr/bin/env python - -import os -import sys -import re -import tempfile -import shutil -import stat -from AppKit import * - -def FindClangSpecs(path): - for root, dirs, files in os.walk(path): - for f in files: - if f.endswith(".xcspec") and f.startswith("Clang LLVM"): - yield os.path.join(root, f) - -def ModifySpec(path, pathToChecker): - t = tempfile.NamedTemporaryFile(delete=False) - foundAnalyzer = False - with open(path) as f: - for line in f: - if not foundAnalyzer: - if line.find("Static Analyzer") >= 0: - foundAnalyzer = True - else: - m = re.search('^(\s*ExecPath\s*=\s*")', line) - if m: - line = "".join([m.group(0), pathToChecker, '";\n']) - t.write(line) - t.close() - print "(+) processing:", path - try: - shutil.copy(t.name, path) - os.chmod(path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH) - except IOError, why: - print " (-) Cannot update file:", why, "\n" - except OSError, why: - print " (-) Cannot update file:", why, "\n" - os.unlink(t.name) - -def main(): - from optparse import OptionParser - parser = OptionParser('usage: %prog [options]') - parser.set_description(__doc__) - parser.add_option("--use-checker-build", dest="path", - help="Use the Clang located at the provided absolute path, e.g. /Users/foo/checker-1") - parser.add_option("--use-xcode-clang", action="store_const", - const="$(CLANG)", dest="default", - help="Use the Clang bundled with Xcode") - (options, args) = parser.parse_args() - if options.path is None and options.default is None: - parser.error("You must specify a version of Clang to use for static analysis. Specify '-h' for details") - - # determine if Xcode is running - for x in NSWorkspace.sharedWorkspace().runningApplications(): - if x.localizedName().find("Xcode") >= 0: - print "(-) You must quit Xcode first before modifying its configuration files." - return - - if options.path: - # Expand tildes. - path = os.path.expanduser(options.path) - if not path.endswith("clang"): - print "(+) Using Clang bundled with checker build:", path - path = os.path.join(path, "bin", "clang"); - else: - print "(+) Using Clang located at:", path - else: - print "(+) Using the Clang bundled with Xcode" - path = options.default - - for x in FindClangSpecs('/Developer'): - ModifySpec(x, path) - -if __name__ == '__main__': - main() - diff --git a/contrib/llvm/tools/clang/tools/scan-build/sorttable.js b/contrib/llvm/tools/clang/tools/scan-build/sorttable.js deleted file mode 100644 index 4352d3b..0000000 --- a/contrib/llvm/tools/clang/tools/scan-build/sorttable.js +++ /dev/null @@ -1,493 +0,0 @@ -/* - SortTable - version 2 - 7th April 2007 - Stuart Langridge, http://www.kryogenix.org/code/browser/sorttable/ - - Instructions: - Download this file - Add <script src="sorttable.js"></script> to your HTML - Add class="sortable" to any table you'd like to make sortable - Click on the headers to sort - - Thanks to many, many people for contributions and suggestions. - Licenced as X11: http://www.kryogenix.org/code/browser/licence.html - This basically means: do what you want with it. -*/ - - -var stIsIE = /*@cc_on!@*/false; - -sorttable = { - init: function() { - // quit if this function has already been called - if (arguments.callee.done) return; - // flag this function so we don't do the same thing twice - arguments.callee.done = true; - // kill the timer - if (_timer) clearInterval(_timer); - - if (!document.createElement || !document.getElementsByTagName) return; - - sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/; - - forEach(document.getElementsByTagName('table'), function(table) { - if (table.className.search(/\bsortable\b/) != -1) { - sorttable.makeSortable(table); - } - }); - - }, - - makeSortable: function(table) { - if (table.getElementsByTagName('thead').length == 0) { - // table doesn't have a tHead. Since it should have, create one and - // put the first table row in it. - the = document.createElement('thead'); - the.appendChild(table.rows[0]); - table.insertBefore(the,table.firstChild); - } - // Safari doesn't support table.tHead, sigh - if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0]; - - if (table.tHead.rows.length != 1) return; // can't cope with two header rows - - // Sorttable v1 put rows with a class of "sortbottom" at the bottom (as - // "total" rows, for example). This is B&R, since what you're supposed - // to do is put them in a tfoot. So, if there are sortbottom rows, - // for backwards compatibility, move them to tfoot (creating it if needed). - sortbottomrows = []; - for (var i=0; i<table.rows.length; i++) { - if (table.rows[i].className.search(/\bsortbottom\b/) != -1) { - sortbottomrows[sortbottomrows.length] = table.rows[i]; - } - } - if (sortbottomrows) { - if (table.tFoot == null) { - // table doesn't have a tfoot. Create one. - tfo = document.createElement('tfoot'); - table.appendChild(tfo); - } - for (var i=0; i<sortbottomrows.length; i++) { - tfo.appendChild(sortbottomrows[i]); - } - delete sortbottomrows; - } - - // work through each column and calculate its type - headrow = table.tHead.rows[0].cells; - for (var i=0; i<headrow.length; i++) { - // manually override the type with a sorttable_type attribute - if (!headrow[i].className.match(/\bsorttable_nosort\b/)) { // skip this col - mtch = headrow[i].className.match(/\bsorttable_([a-z0-9]+)\b/); - if (mtch) { override = mtch[1]; } - if (mtch && typeof sorttable["sort_"+override] == 'function') { - headrow[i].sorttable_sortfunction = sorttable["sort_"+override]; - } else { - headrow[i].sorttable_sortfunction = sorttable.guessType(table,i); - } - // make it clickable to sort - headrow[i].sorttable_columnindex = i; - headrow[i].sorttable_tbody = table.tBodies[0]; - dean_addEvent(headrow[i],"click", function(e) { - - if (this.className.search(/\bsorttable_sorted\b/) != -1) { - // if we're already sorted by this column, just - // reverse the table, which is quicker - sorttable.reverse(this.sorttable_tbody); - this.className = this.className.replace('sorttable_sorted', - 'sorttable_sorted_reverse'); - this.removeChild(document.getElementById('sorttable_sortfwdind')); - sortrevind = document.createElement('span'); - sortrevind.id = "sorttable_sortrevind"; - sortrevind.innerHTML = stIsIE ? ' <font face="webdings">5</font>' : ' ▴'; - this.appendChild(sortrevind); - return; - } - if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) { - // if we're already sorted by this column in reverse, just - // re-reverse the table, which is quicker - sorttable.reverse(this.sorttable_tbody); - this.className = this.className.replace('sorttable_sorted_reverse', - 'sorttable_sorted'); - this.removeChild(document.getElementById('sorttable_sortrevind')); - sortfwdind = document.createElement('span'); - sortfwdind.id = "sorttable_sortfwdind"; - sortfwdind.innerHTML = stIsIE ? ' <font face="webdings">6</font>' : ' ▾'; - this.appendChild(sortfwdind); - return; - } - - // remove sorttable_sorted classes - theadrow = this.parentNode; - forEach(theadrow.childNodes, function(cell) { - if (cell.nodeType == 1) { // an element - cell.className = cell.className.replace('sorttable_sorted_reverse',''); - cell.className = cell.className.replace('sorttable_sorted',''); - } - }); - sortfwdind = document.getElementById('sorttable_sortfwdind'); - if (sortfwdind) { sortfwdind.parentNode.removeChild(sortfwdind); } - sortrevind = document.getElementById('sorttable_sortrevind'); - if (sortrevind) { sortrevind.parentNode.removeChild(sortrevind); } - - this.className += ' sorttable_sorted'; - sortfwdind = document.createElement('span'); - sortfwdind.id = "sorttable_sortfwdind"; - sortfwdind.innerHTML = stIsIE ? ' <font face="webdings">6</font>' : ' ▾'; - this.appendChild(sortfwdind); - - // build an array to sort. This is a Schwartzian transform thing, - // i.e., we "decorate" each row with the actual sort key, - // sort based on the sort keys, and then put the rows back in order - // which is a lot faster because you only do getInnerText once per row - row_array = []; - col = this.sorttable_columnindex; - rows = this.sorttable_tbody.rows; - for (var j=0; j<rows.length; j++) { - row_array[row_array.length] = [sorttable.getInnerText(rows[j].cells[col]), rows[j]]; - } - /* If you want a stable sort, uncomment the following line */ - sorttable.shaker_sort(row_array, this.sorttable_sortfunction); - /* and comment out this one */ - //row_array.sort(this.sorttable_sortfunction); - - tb = this.sorttable_tbody; - for (var j=0; j<row_array.length; j++) { - tb.appendChild(row_array[j][1]); - } - - delete row_array; - }); - } - } - }, - - guessType: function(table, column) { - // guess the type of a column based on its first non-blank row - sortfn = sorttable.sort_alpha; - for (var i=0; i<table.tBodies[0].rows.length; i++) { - text = sorttable.getInnerText(table.tBodies[0].rows[i].cells[column]); - if (text != '') { - if (text.match(/^-?[£$¤]?[\d,.]+%?$/)) { - return sorttable.sort_numeric; - } - // check for a date: dd/mm/yyyy or dd/mm/yy - // can have / or . or - as separator - // can be mm/dd as well - possdate = text.match(sorttable.DATE_RE) - if (possdate) { - // looks like a date - first = parseInt(possdate[1]); - second = parseInt(possdate[2]); - if (first > 12) { - // definitely dd/mm - return sorttable.sort_ddmm; - } else if (second > 12) { - return sorttable.sort_mmdd; - } else { - // looks like a date, but we can't tell which, so assume - // that it's dd/mm (English imperialism!) and keep looking - sortfn = sorttable.sort_ddmm; - } - } - } - } - return sortfn; - }, - - getInnerText: function(node) { - // gets the text we want to use for sorting for a cell. - // strips leading and trailing whitespace. - // this is *not* a generic getInnerText function; it's special to sorttable. - // for example, you can override the cell text with a customkey attribute. - // it also gets .value for <input> fields. - - hasInputs = (typeof node.getElementsByTagName == 'function') && - node.getElementsByTagName('input').length; - - if (node.getAttribute("sorttable_customkey") != null) { - return node.getAttribute("sorttable_customkey"); - } - else if (typeof node.textContent != 'undefined' && !hasInputs) { - return node.textContent.replace(/^\s+|\s+$/g, ''); - } - else if (typeof node.innerText != 'undefined' && !hasInputs) { - return node.innerText.replace(/^\s+|\s+$/g, ''); - } - else if (typeof node.text != 'undefined' && !hasInputs) { - return node.text.replace(/^\s+|\s+$/g, ''); - } - else { - switch (node.nodeType) { - case 3: - if (node.nodeName.toLowerCase() == 'input') { - return node.value.replace(/^\s+|\s+$/g, ''); - } - case 4: - return node.nodeValue.replace(/^\s+|\s+$/g, ''); - break; - case 1: - case 11: - var innerText = ''; - for (var i = 0; i < node.childNodes.length; i++) { - innerText += sorttable.getInnerText(node.childNodes[i]); - } - return innerText.replace(/^\s+|\s+$/g, ''); - break; - default: - return ''; - } - } - }, - - reverse: function(tbody) { - // reverse the rows in a tbody - newrows = []; - for (var i=0; i<tbody.rows.length; i++) { - newrows[newrows.length] = tbody.rows[i]; - } - for (var i=newrows.length-1; i>=0; i--) { - tbody.appendChild(newrows[i]); - } - delete newrows; - }, - - /* sort functions - each sort function takes two parameters, a and b - you are comparing a[0] and b[0] */ - sort_numeric: function(a,b) { - aa = parseFloat(a[0].replace(/[^0-9.-]/g,'')); - if (isNaN(aa)) aa = 0; - bb = parseFloat(b[0].replace(/[^0-9.-]/g,'')); - if (isNaN(bb)) bb = 0; - return aa-bb; - }, - sort_alpha: function(a,b) { - if (a[0]==b[0]) return 0; - if (a[0]<b[0]) return -1; - return 1; - }, - sort_ddmm: function(a,b) { - mtch = a[0].match(sorttable.DATE_RE); - y = mtch[3]; m = mtch[2]; d = mtch[1]; - if (m.length == 1) m = '0'+m; - if (d.length == 1) d = '0'+d; - dt1 = y+m+d; - mtch = b[0].match(sorttable.DATE_RE); - y = mtch[3]; m = mtch[2]; d = mtch[1]; - if (m.length == 1) m = '0'+m; - if (d.length == 1) d = '0'+d; - dt2 = y+m+d; - if (dt1==dt2) return 0; - if (dt1<dt2) return -1; - return 1; - }, - sort_mmdd: function(a,b) { - mtch = a[0].match(sorttable.DATE_RE); - y = mtch[3]; d = mtch[2]; m = mtch[1]; - if (m.length == 1) m = '0'+m; - if (d.length == 1) d = '0'+d; - dt1 = y+m+d; - mtch = b[0].match(sorttable.DATE_RE); - y = mtch[3]; d = mtch[2]; m = mtch[1]; - if (m.length == 1) m = '0'+m; - if (d.length == 1) d = '0'+d; - dt2 = y+m+d; - if (dt1==dt2) return 0; - if (dt1<dt2) return -1; - return 1; - }, - - shaker_sort: function(list, comp_func) { - // A stable sort function to allow multi-level sorting of data - // see: http://en.wikipedia.org/wiki/Cocktail_sort - // thanks to Joseph Nahmias - var b = 0; - var t = list.length - 1; - var swap = true; - - while(swap) { - swap = false; - for(var i = b; i < t; ++i) { - if ( comp_func(list[i], list[i+1]) > 0 ) { - var q = list[i]; list[i] = list[i+1]; list[i+1] = q; - swap = true; - } - } // for - t--; - - if (!swap) break; - - for(var i = t; i > b; --i) { - if ( comp_func(list[i], list[i-1]) < 0 ) { - var q = list[i]; list[i] = list[i-1]; list[i-1] = q; - swap = true; - } - } // for - b++; - - } // while(swap) - } -} - -/* ****************************************************************** - Supporting functions: bundled here to avoid depending on a library - ****************************************************************** */ - -// Dean Edwards/Matthias Miller/John Resig - -/* for Mozilla/Opera9 */ -if (document.addEventListener) { - document.addEventListener("DOMContentLoaded", sorttable.init, false); -} - -/* for Internet Explorer */ -/*@cc_on @*/ -/*@if (@_win32) - document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>"); - var script = document.getElementById("__ie_onload"); - script.onreadystatechange = function() { - if (this.readyState == "complete") { - sorttable.init(); // call the onload handler - } - }; -/*@end @*/ - -/* for Safari */ -if (/WebKit/i.test(navigator.userAgent)) { // sniff - var _timer = setInterval(function() { - if (/loaded|complete/.test(document.readyState)) { - sorttable.init(); // call the onload handler - } - }, 10); -} - -/* for other browsers */ -window.onload = sorttable.init; - -// written by Dean Edwards, 2005 -// with input from Tino Zijdel, Matthias Miller, Diego Perini - -// http://dean.edwards.name/weblog/2005/10/add-event/ - -function dean_addEvent(element, type, handler) { - if (element.addEventListener) { - element.addEventListener(type, handler, false); - } else { - // assign each event handler a unique ID - if (!handler.$$guid) handler.$$guid = dean_addEvent.guid++; - // create a hash table of event types for the element - if (!element.events) element.events = {}; - // create a hash table of event handlers for each element/event pair - var handlers = element.events[type]; - if (!handlers) { - handlers = element.events[type] = {}; - // store the existing event handler (if there is one) - if (element["on" + type]) { - handlers[0] = element["on" + type]; - } - } - // store the event handler in the hash table - handlers[handler.$$guid] = handler; - // assign a global event handler to do all the work - element["on" + type] = handleEvent; - } -}; -// a counter used to create unique IDs -dean_addEvent.guid = 1; - -function removeEvent(element, type, handler) { - if (element.removeEventListener) { - element.removeEventListener(type, handler, false); - } else { - // delete the event handler from the hash table - if (element.events && element.events[type]) { - delete element.events[type][handler.$$guid]; - } - } -}; - -function handleEvent(event) { - var returnValue = true; - // grab the event object (IE uses a global event object) - event = event || fixEvent(((this.ownerDocument || this.document || this).parentWindow || window).event); - // get a reference to the hash table of event handlers - var handlers = this.events[event.type]; - // execute each event handler - for (var i in handlers) { - this.$$handleEvent = handlers[i]; - if (this.$$handleEvent(event) === false) { - returnValue = false; - } - } - return returnValue; -}; - -function fixEvent(event) { - // add W3C standard event methods - event.preventDefault = fixEvent.preventDefault; - event.stopPropagation = fixEvent.stopPropagation; - return event; -}; -fixEvent.preventDefault = function() { - this.returnValue = false; -}; -fixEvent.stopPropagation = function() { - this.cancelBubble = true; -} - -// Dean's forEach: http://dean.edwards.name/base/forEach.js -/* - forEach, version 1.0 - Copyright 2006, Dean Edwards - License: http://www.opensource.org/licenses/mit-license.php -*/ - -// array-like enumeration -if (!Array.forEach) { // mozilla already supports this - Array.forEach = function(array, block, context) { - for (var i = 0; i < array.length; i++) { - block.call(context, array[i], i, array); - } - }; -} - -// generic enumeration -Function.prototype.forEach = function(object, block, context) { - for (var key in object) { - if (typeof this.prototype[key] == "undefined") { - block.call(context, object[key], key, object); - } - } -}; - -// character enumeration -String.forEach = function(string, block, context) { - Array.forEach(string.split(""), function(chr, index) { - block.call(context, chr, index, string); - }); -}; - -// globally resolve forEach enumeration -var forEach = function(object, block, context) { - if (object) { - var resolve = Object; // default - if (object instanceof Function) { - // functions have a "length" property - resolve = Function; - } else if (object.forEach instanceof Function) { - // the object implements a custom forEach method so use that - object.forEach(block, context); - return; - } else if (typeof object == "string") { - // the object is a string - resolve = String; - } else if (typeof object.length == "number") { - // the object is array-like - resolve = Array; - } - resolve.forEach(object, block, context); - } -}; - diff --git a/contrib/llvm/tools/clang/tools/scan-view/Reporter.py b/contrib/llvm/tools/clang/tools/scan-view/Reporter.py deleted file mode 100644 index 9560fc1..0000000 --- a/contrib/llvm/tools/clang/tools/scan-view/Reporter.py +++ /dev/null @@ -1,248 +0,0 @@ -"""Methods for reporting bugs.""" - -import subprocess, sys, os - -__all__ = ['ReportFailure', 'BugReport', 'getReporters'] - -# - -class ReportFailure(Exception): - """Generic exception for failures in bug reporting.""" - def __init__(self, value): - self.value = value - -# Collect information about a bug. - -class BugReport: - def __init__(self, title, description, files): - self.title = title - self.description = description - self.files = files - -# Reporter interfaces. - -import os - -import email, mimetypes, smtplib -from email import encoders -from email.message import Message -from email.mime.base import MIMEBase -from email.mime.multipart import MIMEMultipart -from email.mime.text import MIMEText - -#===------------------------------------------------------------------------===# -# ReporterParameter -#===------------------------------------------------------------------------===# - -class ReporterParameter: - def __init__(self, n): - self.name = n - def getName(self): - return self.name - def getValue(self,r,bugtype,getConfigOption): - return getConfigOption(r.getName(),self.getName()) - def saveConfigValue(self): - return True - -class TextParameter (ReporterParameter): - def getHTML(self,r,bugtype,getConfigOption): - return """\ -<tr> -<td class="form_clabel">%s:</td> -<td class="form_value"><input type="text" name="%s_%s" value="%s"></td> -</tr>"""%(self.getName(),r.getName(),self.getName(),self.getValue(r,bugtype,getConfigOption)) - -class SelectionParameter (ReporterParameter): - def __init__(self, n, values): - ReporterParameter.__init__(self,n) - self.values = values - - def getHTML(self,r,bugtype,getConfigOption): - default = self.getValue(r,bugtype,getConfigOption) - return """\ -<tr> -<td class="form_clabel">%s:</td><td class="form_value"><select name="%s_%s"> -%s -</select></td>"""%(self.getName(),r.getName(),self.getName(),'\n'.join(["""\ -<option value="%s"%s>%s</option>"""%(o[0], - o[0] == default and ' selected="selected"' or '', - o[1]) for o in self.values])) - -#===------------------------------------------------------------------------===# -# Reporters -#===------------------------------------------------------------------------===# - -class EmailReporter: - def getName(self): - return 'Email' - - def getParameters(self): - return map(lambda x:TextParameter(x),['To', 'From', 'SMTP Server', 'SMTP Port']) - - # Lifted from python email module examples. - def attachFile(self, outer, path): - # Guess the content type based on the file's extension. Encoding - # will be ignored, although we should check for simple things like - # gzip'd or compressed files. - ctype, encoding = mimetypes.guess_type(path) - if ctype is None or encoding is not None: - # No guess could be made, or the file is encoded (compressed), so - # use a generic bag-of-bits type. - ctype = 'application/octet-stream' - maintype, subtype = ctype.split('/', 1) - if maintype == 'text': - fp = open(path) - # Note: we should handle calculating the charset - msg = MIMEText(fp.read(), _subtype=subtype) - fp.close() - else: - fp = open(path, 'rb') - msg = MIMEBase(maintype, subtype) - msg.set_payload(fp.read()) - fp.close() - # Encode the payload using Base64 - encoders.encode_base64(msg) - # Set the filename parameter - msg.add_header('Content-Disposition', 'attachment', filename=os.path.basename(path)) - outer.attach(msg) - - def fileReport(self, report, parameters): - mainMsg = """\ -BUG REPORT ---- -Title: %s -Description: %s -"""%(report.title, report.description) - - if not parameters.get('To'): - raise ReportFailure('No "To" address specified.') - if not parameters.get('From'): - raise ReportFailure('No "From" address specified.') - - msg = MIMEMultipart() - msg['Subject'] = 'BUG REPORT: %s'%(report.title) - # FIXME: Get config parameters - msg['To'] = parameters.get('To') - msg['From'] = parameters.get('From') - msg.preamble = mainMsg - - msg.attach(MIMEText(mainMsg, _subtype='text/plain')) - for file in report.files: - self.attachFile(msg, file) - - try: - s = smtplib.SMTP(host=parameters.get('SMTP Server'), - port=parameters.get('SMTP Port')) - s.sendmail(msg['From'], msg['To'], msg.as_string()) - s.close() - except: - raise ReportFailure('Unable to send message via SMTP.') - - return "Message sent!" - -class BugzillaReporter: - def getName(self): - return 'Bugzilla' - - def getParameters(self): - return map(lambda x:TextParameter(x),['URL','Product']) - - def fileReport(self, report, parameters): - raise NotImplementedError - - -class RadarClassificationParameter(SelectionParameter): - def __init__(self): - SelectionParameter.__init__(self,"Classification", - [['1', 'Security'], ['2', 'Crash/Hang/Data Loss'], - ['3', 'Performance'], ['4', 'UI/Usability'], - ['6', 'Serious Bug'], ['7', 'Other']]) - - def saveConfigValue(self): - return False - - def getValue(self,r,bugtype,getConfigOption): - if bugtype.find("leak") != -1: - return '3' - elif bugtype.find("dereference") != -1: - return '2' - elif bugtype.find("missing ivar release") != -1: - return '3' - else: - return '7' - -class RadarReporter: - @staticmethod - def isAvailable(): - # FIXME: Find this .scpt better - path = os.path.join(os.path.dirname(__file__),'Resources/GetRadarVersion.scpt') - try: - p = subprocess.Popen(['osascript',path], - stdout=subprocess.PIPE, stderr=subprocess.PIPE) - except: - return False - data,err = p.communicate() - res = p.wait() - # FIXME: Check version? Check for no errors? - return res == 0 - - def getName(self): - return 'Radar' - - def getParameters(self): - return [ TextParameter('Component'), TextParameter('Component Version'), - RadarClassificationParameter() ] - - def fileReport(self, report, parameters): - component = parameters.get('Component', '') - componentVersion = parameters.get('Component Version', '') - classification = parameters.get('Classification', '') - personID = "" - diagnosis = "" - config = "" - - if not component.strip(): - component = 'Bugs found by clang Analyzer' - if not componentVersion.strip(): - componentVersion = 'X' - - script = os.path.join(os.path.dirname(__file__),'Resources/FileRadar.scpt') - args = ['osascript', script, component, componentVersion, classification, personID, report.title, - report.description, diagnosis, config] + map(os.path.abspath, report.files) -# print >>sys.stderr, args - try: - p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - except: - raise ReportFailure("Unable to file radar (AppleScript failure).") - data, err = p.communicate() - res = p.wait() - - if res: - raise ReportFailure("Unable to file radar (AppleScript failure).") - - try: - values = eval(data) - except: - raise ReportFailure("Unable to process radar results.") - - # We expect (int: bugID, str: message) - if len(values) != 2 or not isinstance(values[0], int): - raise ReportFailure("Unable to process radar results.") - - bugID,message = values - bugID = int(bugID) - - if not bugID: - raise ReportFailure(message) - - return "Filed: <a href=\"rdar://%d/\">%d</a>"%(bugID,bugID) - -### - -def getReporters(): - reporters = [] - if RadarReporter.isAvailable(): - reporters.append(RadarReporter()) - reporters.append(EmailReporter()) - return reporters - diff --git a/contrib/llvm/tools/clang/tools/scan-view/Resources/FileRadar.scpt b/contrib/llvm/tools/clang/tools/scan-view/Resources/FileRadar.scpt Binary files differdeleted file mode 100644 index 1c74552..0000000 --- a/contrib/llvm/tools/clang/tools/scan-view/Resources/FileRadar.scpt +++ /dev/null diff --git a/contrib/llvm/tools/clang/tools/scan-view/Resources/GetRadarVersion.scpt b/contrib/llvm/tools/clang/tools/scan-view/Resources/GetRadarVersion.scpt deleted file mode 100644 index e69de29..0000000 --- a/contrib/llvm/tools/clang/tools/scan-view/Resources/GetRadarVersion.scpt +++ /dev/null diff --git a/contrib/llvm/tools/clang/tools/scan-view/Resources/bugcatcher.ico b/contrib/llvm/tools/clang/tools/scan-view/Resources/bugcatcher.ico Binary files differdeleted file mode 100644 index 22d39b5..0000000 --- a/contrib/llvm/tools/clang/tools/scan-view/Resources/bugcatcher.ico +++ /dev/null diff --git a/contrib/llvm/tools/clang/tools/scan-view/ScanView.py b/contrib/llvm/tools/clang/tools/scan-view/ScanView.py deleted file mode 100644 index 837adae..0000000 --- a/contrib/llvm/tools/clang/tools/scan-view/ScanView.py +++ /dev/null @@ -1,770 +0,0 @@ -import BaseHTTPServer -import SimpleHTTPServer -import os -import sys -import urllib, urlparse -import posixpath -import StringIO -import re -import shutil -import threading -import time -import socket -import itertools - -import Reporter -import ConfigParser - -### -# Various patterns matched or replaced by server. - -kReportFileRE = re.compile('(.*/)?report-(.*)\\.html') - -kBugKeyValueRE = re.compile('<!-- BUG([^ ]*) (.*) -->') - -# <!-- REPORTPROBLEM file="crashes/clang_crash_ndSGF9.mi" stderr="crashes/clang_crash_ndSGF9.mi.stderr.txt" info="crashes/clang_crash_ndSGF9.mi.info" --> - -kReportCrashEntryRE = re.compile('<!-- REPORTPROBLEM (.*?)-->') -kReportCrashEntryKeyValueRE = re.compile(' ?([^=]+)="(.*?)"') - -kReportReplacements = [] - -# Add custom javascript. -kReportReplacements.append((re.compile('<!-- SUMMARYENDHEAD -->'), """\ -<script language="javascript" type="text/javascript"> -function load(url) { - if (window.XMLHttpRequest) { - req = new XMLHttpRequest(); - } else if (window.ActiveXObject) { - req = new ActiveXObject("Microsoft.XMLHTTP"); - } - if (req != undefined) { - req.open("GET", url, true); - req.send(""); - } -} -</script>""")) - -# Insert additional columns. -kReportReplacements.append((re.compile('<!-- REPORTBUGCOL -->'), - '<td></td><td></td>')) - -# Insert report bug and open file links. -kReportReplacements.append((re.compile('<!-- REPORTBUG id="report-(.*)\\.html" -->'), - ('<td class="Button"><a href="report/\\1">Report Bug</a></td>' + - '<td class="Button"><a href="javascript:load(\'open/\\1\')">Open File</a></td>'))) - -kReportReplacements.append((re.compile('<!-- REPORTHEADER -->'), - '<h3><a href="/">Summary</a> > Report %(report)s</h3>')) - -kReportReplacements.append((re.compile('<!-- REPORTSUMMARYEXTRA -->'), - '<td class="Button"><a href="report/%(report)s">Report Bug</a></td>')) - -# Insert report crashes link. - -# Disabled for the time being until we decide exactly when this should -# be enabled. Also the radar reporter needs to be fixed to report -# multiple files. - -#kReportReplacements.append((re.compile('<!-- REPORTCRASHES -->'), -# '<br>These files will automatically be attached to ' + -# 'reports filed here: <a href="report_crashes">Report Crashes</a>.')) - -### -# Other simple parameters - -kResources = posixpath.join(posixpath.dirname(__file__), 'Resources') -kConfigPath = os.path.expanduser('~/.scanview.cfg') - -### - -__version__ = "0.1" - -__all__ = ["create_server"] - -class ReporterThread(threading.Thread): - def __init__(self, report, reporter, parameters, server): - threading.Thread.__init__(self) - self.report = report - self.server = server - self.reporter = reporter - self.parameters = parameters - self.success = False - self.status = None - - def run(self): - result = None - try: - if self.server.options.debug: - print >>sys.stderr, "%s: SERVER: submitting bug."%(sys.argv[0],) - self.status = self.reporter.fileReport(self.report, self.parameters) - self.success = True - time.sleep(3) - if self.server.options.debug: - print >>sys.stderr, "%s: SERVER: submission complete."%(sys.argv[0],) - except Reporter.ReportFailure,e: - self.status = e.value - except Exception,e: - s = StringIO.StringIO() - import traceback - print >>s,'<b>Unhandled Exception</b><br><pre>' - traceback.print_exc(e,file=s) - print >>s,'</pre>' - self.status = s.getvalue() - -class ScanViewServer(BaseHTTPServer.HTTPServer): - def __init__(self, address, handler, root, reporters, options): - BaseHTTPServer.HTTPServer.__init__(self, address, handler) - self.root = root - self.reporters = reporters - self.options = options - self.halted = False - self.config = None - self.load_config() - - def load_config(self): - self.config = ConfigParser.RawConfigParser() - - # Add defaults - self.config.add_section('ScanView') - for r in self.reporters: - self.config.add_section(r.getName()) - for p in r.getParameters(): - if p.saveConfigValue(): - self.config.set(r.getName(), p.getName(), '') - - # Ignore parse errors - try: - self.config.read([kConfigPath]) - except: - pass - - # Save on exit - import atexit - atexit.register(lambda: self.save_config()) - - def save_config(self): - # Ignore errors (only called on exit). - try: - f = open(kConfigPath,'w') - self.config.write(f) - f.close() - except: - pass - - def halt(self): - self.halted = True - if self.options.debug: - print >>sys.stderr, "%s: SERVER: halting." % (sys.argv[0],) - - def serve_forever(self): - while not self.halted: - if self.options.debug > 1: - print >>sys.stderr, "%s: SERVER: waiting..." % (sys.argv[0],) - try: - self.handle_request() - except OSError,e: - print 'OSError',e.errno - - def finish_request(self, request, client_address): - if self.options.autoReload: - import ScanView - self.RequestHandlerClass = reload(ScanView).ScanViewRequestHandler - BaseHTTPServer.HTTPServer.finish_request(self, request, client_address) - - def handle_error(self, request, client_address): - # Ignore socket errors - info = sys.exc_info() - if info and isinstance(info[1], socket.error): - if self.options.debug > 1: - print >>sys.stderr, "%s: SERVER: ignored socket error." % (sys.argv[0],) - return - BaseHTTPServer.HTTPServer.handle_error(self, request, client_address) - -# Borrowed from Quixote, with simplifications. -def parse_query(qs, fields=None): - if fields is None: - fields = {} - for chunk in filter(None, qs.split('&')): - if '=' not in chunk: - name = chunk - value = '' - else: - name, value = chunk.split('=', 1) - name = urllib.unquote(name.replace('+', ' ')) - value = urllib.unquote(value.replace('+', ' ')) - item = fields.get(name) - if item is None: - fields[name] = [value] - else: - item.append(value) - return fields - -class ScanViewRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): - server_version = "ScanViewServer/" + __version__ - dynamic_mtime = time.time() - - def do_HEAD(self): - try: - SimpleHTTPServer.SimpleHTTPRequestHandler.do_HEAD(self) - except Exception,e: - self.handle_exception(e) - - def do_GET(self): - try: - SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self) - except Exception,e: - self.handle_exception(e) - - def do_POST(self): - """Serve a POST request.""" - try: - length = self.headers.getheader('content-length') or "0" - try: - length = int(length) - except: - length = 0 - content = self.rfile.read(length) - fields = parse_query(content) - f = self.send_head(fields) - if f: - self.copyfile(f, self.wfile) - f.close() - except Exception,e: - self.handle_exception(e) - - def log_message(self, format, *args): - if self.server.options.debug: - sys.stderr.write("%s: SERVER: %s - - [%s] %s\n" % - (sys.argv[0], - self.address_string(), - self.log_date_time_string(), - format%args)) - - def load_report(self, report): - path = os.path.join(self.server.root, 'report-%s.html'%report) - data = open(path).read() - keys = {} - for item in kBugKeyValueRE.finditer(data): - k,v = item.groups() - keys[k] = v - return keys - - def load_crashes(self): - path = posixpath.join(self.server.root, 'index.html') - data = open(path).read() - problems = [] - for item in kReportCrashEntryRE.finditer(data): - fieldData = item.group(1) - fields = dict([i.groups() for i in - kReportCrashEntryKeyValueRE.finditer(fieldData)]) - problems.append(fields) - return problems - - def handle_exception(self, exc): - import traceback - s = StringIO.StringIO() - print >>s, "INTERNAL ERROR\n" - traceback.print_exc(exc, s) - f = self.send_string(s.getvalue(), 'text/plain') - if f: - self.copyfile(f, self.wfile) - f.close() - - def get_scalar_field(self, name): - if name in self.fields: - return self.fields[name][0] - else: - return None - - def submit_bug(self, c): - title = self.get_scalar_field('title') - description = self.get_scalar_field('description') - report = self.get_scalar_field('report') - reporterIndex = self.get_scalar_field('reporter') - files = [] - for fileID in self.fields.get('files',[]): - try: - i = int(fileID) - except: - i = None - if i is None or i<0 or i>=len(c.files): - return (False, 'Invalid file ID') - files.append(c.files[i]) - - if not title: - return (False, "Missing title.") - if not description: - return (False, "Missing description.") - try: - reporterIndex = int(reporterIndex) - except: - return (False, "Invalid report method.") - - # Get the reporter and parameters. - reporter = self.server.reporters[reporterIndex] - parameters = {} - for o in reporter.getParameters(): - name = '%s_%s'%(reporter.getName(),o.getName()) - if name not in self.fields: - return (False, - 'Missing field "%s" for %s report method.'%(name, - reporter.getName())) - parameters[o.getName()] = self.get_scalar_field(name) - - # Update config defaults. - if report != 'None': - self.server.config.set('ScanView', 'reporter', reporterIndex) - for o in reporter.getParameters(): - if o.saveConfigValue(): - name = o.getName() - self.server.config.set(reporter.getName(), name, parameters[name]) - - # Create the report. - bug = Reporter.BugReport(title, description, files) - - # Kick off a reporting thread. - t = ReporterThread(bug, reporter, parameters, self.server) - t.start() - - # Wait for thread to die... - while t.isAlive(): - time.sleep(.25) - submitStatus = t.status - - return (t.success, t.status) - - def send_report_submit(self): - report = self.get_scalar_field('report') - c = self.get_report_context(report) - if c.reportSource is None: - reportingFor = "Report Crashes > " - fileBug = """\ -<a href="/report_crashes">File Bug</a> > """%locals() - else: - reportingFor = '<a href="/%s">Report %s</a> > ' % (c.reportSource, - report) - fileBug = '<a href="/report/%s">File Bug</a> > ' % report - title = self.get_scalar_field('title') - description = self.get_scalar_field('description') - - res,message = self.submit_bug(c) - - if res: - statusClass = 'SubmitOk' - statusName = 'Succeeded' - else: - statusClass = 'SubmitFail' - statusName = 'Failed' - - result = """ -<head> - <title>Bug Submission</title> - <link rel="stylesheet" type="text/css" href="/scanview.css" /> -</head> -<body> -<h3> -<a href="/">Summary</a> > -%(reportingFor)s -%(fileBug)s -Submit</h3> -<form name="form" action=""> -<table class="form"> -<tr><td> -<table class="form_group"> -<tr> - <td class="form_clabel">Title:</td> - <td class="form_value"> - <input type="text" name="title" size="50" value="%(title)s" disabled> - </td> -</tr> -<tr> - <td class="form_label">Description:</td> - <td class="form_value"> -<textarea rows="10" cols="80" name="description" disabled> -%(description)s -</textarea> - </td> -</table> -</td></tr> -</table> -</form> -<h1 class="%(statusClass)s">Submission %(statusName)s</h1> -%(message)s -<p> -<hr> -<a href="/">Return to Summary</a> -</body> -</html>"""%locals() - return self.send_string(result) - - def send_open_report(self, report): - try: - keys = self.load_report(report) - except IOError: - return self.send_error(400, 'Invalid report.') - - file = keys.get('FILE') - if not file or not posixpath.exists(file): - return self.send_error(400, 'File does not exist: "%s"' % file) - - import startfile - if self.server.options.debug: - print >>sys.stderr, '%s: SERVER: opening "%s"'%(sys.argv[0], - file) - - status = startfile.open(file) - if status: - res = 'Opened: "%s"' % file - else: - res = 'Open failed: "%s"' % file - - return self.send_string(res, 'text/plain') - - def get_report_context(self, report): - class Context: - pass - if report is None or report == 'None': - data = self.load_crashes() - # Don't allow empty reports. - if not data: - raise ValueError, 'No crashes detected!' - c = Context() - c.title = 'clang static analyzer failures' - - stderrSummary = "" - for item in data: - if 'stderr' in item: - path = posixpath.join(self.server.root, item['stderr']) - if os.path.exists(path): - lns = itertools.islice(open(path), 0, 10) - stderrSummary += '%s\n--\n%s' % (item.get('src', - '<unknown>'), - ''.join(lns)) - - c.description = """\ -The clang static analyzer failed on these inputs: -%s - -STDERR Summary --------------- -%s -""" % ('\n'.join([item.get('src','<unknown>') for item in data]), - stderrSummary) - c.reportSource = None - c.navMarkup = "Report Crashes > " - c.files = [] - for item in data: - c.files.append(item.get('src','')) - c.files.append(posixpath.join(self.server.root, - item.get('file',''))) - c.files.append(posixpath.join(self.server.root, - item.get('clangfile',''))) - c.files.append(posixpath.join(self.server.root, - item.get('stderr',''))) - c.files.append(posixpath.join(self.server.root, - item.get('info',''))) - # Just in case something failed, ignore files which don't - # exist. - c.files = [f for f in c.files - if os.path.exists(f) and os.path.isfile(f)] - else: - # Check that this is a valid report. - path = posixpath.join(self.server.root, 'report-%s.html' % report) - if not posixpath.exists(path): - raise ValueError, 'Invalid report ID' - keys = self.load_report(report) - c = Context() - c.title = keys.get('DESC','clang error (unrecognized') - c.description = """\ -Bug reported by the clang static analyzer. - -Description: %s -File: %s -Line: %s -"""%(c.title, keys.get('FILE','<unknown>'), keys.get('LINE', '<unknown>')) - c.reportSource = 'report-%s.html' % report - c.navMarkup = """<a href="/%s">Report %s</a> > """ % (c.reportSource, - report) - - c.files = [path] - return c - - def send_report(self, report, configOverrides=None): - def getConfigOption(section, field): - if (configOverrides is not None and - section in configOverrides and - field in configOverrides[section]): - return configOverrides[section][field] - return self.server.config.get(section, field) - - # report is None is used for crashes - try: - c = self.get_report_context(report) - except ValueError, e: - return self.send_error(400, e.message) - - title = c.title - description= c.description - reportingFor = c.navMarkup - if c.reportSource is None: - extraIFrame = "" - else: - extraIFrame = """\ -<iframe src="/%s" width="100%%" height="40%%" - scrolling="auto" frameborder="1"> - <a href="/%s">View Bug Report</a> -</iframe>""" % (c.reportSource, c.reportSource) - - reporterSelections = [] - reporterOptions = [] - - try: - active = int(getConfigOption('ScanView','reporter')) - except: - active = 0 - for i,r in enumerate(self.server.reporters): - selected = (i == active) - if selected: - selectedStr = ' selected' - else: - selectedStr = '' - reporterSelections.append('<option value="%d"%s>%s</option>'%(i,selectedStr,r.getName())) - options = '\n'.join([ o.getHTML(r,title,getConfigOption) for o in r.getParameters()]) - display = ('none','')[selected] - reporterOptions.append("""\ -<tr id="%sReporterOptions" style="display:%s"> - <td class="form_label">%s Options</td> - <td class="form_value"> - <table class="form_inner_group"> -%s - </table> - </td> -</tr> -"""%(r.getName(),display,r.getName(),options)) - reporterSelections = '\n'.join(reporterSelections) - reporterOptionsDivs = '\n'.join(reporterOptions) - reportersArray = '[%s]'%(','.join([`r.getName()` for r in self.server.reporters])) - - if c.files: - fieldSize = min(5, len(c.files)) - attachFileOptions = '\n'.join(["""\ -<option value="%d" selected>%s</option>""" % (i,v) for i,v in enumerate(c.files)]) - attachFileRow = """\ -<tr> - <td class="form_label">Attach:</td> - <td class="form_value"> -<select style="width:100%%" name="files" multiple size=%d> -%s -</select> - </td> -</tr> -""" % (min(5, len(c.files)), attachFileOptions) - else: - attachFileRow = "" - - result = """<html> -<head> - <title>File Bug</title> - <link rel="stylesheet" type="text/css" href="/scanview.css" /> -</head> -<script language="javascript" type="text/javascript"> -var reporters = %(reportersArray)s; -function updateReporterOptions() { - index = document.getElementById('reporter').selectedIndex; - for (var i=0; i < reporters.length; ++i) { - o = document.getElementById(reporters[i] + "ReporterOptions"); - if (i == index) { - o.style.display = ""; - } else { - o.style.display = "none"; - } - } -} -</script> -<body onLoad="updateReporterOptions()"> -<h3> -<a href="/">Summary</a> > -%(reportingFor)s -File Bug</h3> -<form name="form" action="/report_submit" method="post"> -<input type="hidden" name="report" value="%(report)s"> - -<table class="form"> -<tr><td> -<table class="form_group"> -<tr> - <td class="form_clabel">Title:</td> - <td class="form_value"> - <input type="text" name="title" size="50" value="%(title)s"> - </td> -</tr> -<tr> - <td class="form_label">Description:</td> - <td class="form_value"> -<textarea rows="10" cols="80" name="description"> -%(description)s -</textarea> - </td> -</tr> - -%(attachFileRow)s - -</table> -<br> -<table class="form_group"> -<tr> - <td class="form_clabel">Method:</td> - <td class="form_value"> - <select id="reporter" name="reporter" onChange="updateReporterOptions()"> - %(reporterSelections)s - </select> - </td> -</tr> -%(reporterOptionsDivs)s -</table> -<br> -</td></tr> -<tr><td class="form_submit"> - <input align="right" type="submit" name="Submit" value="Submit"> -</td></tr> -</table> -</form> - -%(extraIFrame)s - -</body> -</html>"""%locals() - - return self.send_string(result) - - def send_head(self, fields=None): - if (self.server.options.onlyServeLocal and - self.client_address[0] != '127.0.0.1'): - return self.send_error('401', 'Unauthorized host.') - - if fields is None: - fields = {} - self.fields = fields - - o = urlparse.urlparse(self.path) - self.fields = parse_query(o.query, fields) - path = posixpath.normpath(urllib.unquote(o.path)) - - # Split the components and strip the root prefix. - components = path.split('/')[1:] - - # Special case some top-level entries. - if components: - name = components[0] - if len(components)==2: - if name=='report': - return self.send_report(components[1]) - elif name=='open': - return self.send_open_report(components[1]) - elif len(components)==1: - if name=='quit': - self.server.halt() - return self.send_string('Goodbye.', 'text/plain') - elif name=='report_submit': - return self.send_report_submit() - elif name=='report_crashes': - overrides = { 'ScanView' : {}, - 'Radar' : {}, - 'Email' : {} } - for i,r in enumerate(self.server.reporters): - if r.getName() == 'Radar': - overrides['ScanView']['reporter'] = i - break - overrides['Radar']['Component'] = 'llvm - checker' - overrides['Radar']['Component Version'] = 'X' - return self.send_report(None, overrides) - elif name=='favicon.ico': - return self.send_path(posixpath.join(kResources,'bugcatcher.ico')) - - # Match directory entries. - if components[-1] == '': - components[-1] = 'index.html' - - suffix = '/'.join(components) - - # The summary may reference source files on disk using rooted - # paths. Make sure these resolve correctly for now. - # FIXME: This isn't a very good idea... we should probably - # mark rooted paths somehow. - if os.path.exists(posixpath.join('/', suffix)): - path = posixpath.join('/', suffix) - else: - path = posixpath.join(self.server.root, suffix) - - if self.server.options.debug > 1: - print >>sys.stderr, '%s: SERVER: sending path "%s"'%(sys.argv[0], - path) - return self.send_path(path) - - def send_404(self): - self.send_error(404, "File not found") - return None - - def send_path(self, path): - ctype = self.guess_type(path) - if ctype.startswith('text/'): - # Patch file instead - return self.send_patched_file(path, ctype) - else: - mode = 'rb' - try: - f = open(path, mode) - except IOError: - return self.send_404() - return self.send_file(f, ctype) - - def send_file(self, f, ctype): - # Patch files to add links, but skip binary files. - self.send_response(200) - self.send_header("Content-type", ctype) - fs = os.fstat(f.fileno()) - self.send_header("Content-Length", str(fs[6])) - self.send_header("Last-Modified", self.date_time_string(fs.st_mtime)) - self.end_headers() - return f - - def send_string(self, s, ctype='text/html', headers=True, mtime=None): - if headers: - self.send_response(200) - self.send_header("Content-type", ctype) - self.send_header("Content-Length", str(len(s))) - if mtime is None: - mtime = self.dynamic_mtime - self.send_header("Last-Modified", self.date_time_string(mtime)) - self.end_headers() - return StringIO.StringIO(s) - - def send_patched_file(self, path, ctype): - # Allow a very limited set of variables. This is pretty gross. - variables = {} - variables['report'] = '' - m = kReportFileRE.match(path) - if m: - variables['report'] = m.group(2) - - try: - f = open(path,'r') - except IOError: - return self.send_404() - fs = os.fstat(f.fileno()) - data = f.read() - for a,b in kReportReplacements: - data = a.sub(b % variables, data) - return self.send_string(data, ctype, mtime=fs.st_mtime) - - -def create_server(address, options, root): - import Reporter - - reporters = Reporter.getReporters() - - return ScanViewServer(address, ScanViewRequestHandler, - root, - reporters, - options) diff --git a/contrib/llvm/tools/clang/tools/scan-view/scan-view b/contrib/llvm/tools/clang/tools/scan-view/scan-view deleted file mode 100755 index fb27da6..0000000 --- a/contrib/llvm/tools/clang/tools/scan-view/scan-view +++ /dev/null @@ -1,131 +0,0 @@ -#!/usr/bin/env python - -"""The clang static analyzer results viewer. -""" - -import sys -import posixpath -import thread -import time -import urllib -import webbrowser - -# How long to wait for server to start. -kSleepTimeout = .05 -kMaxSleeps = int(60 / kSleepTimeout) - -# Default server parameters - -kDefaultHost = '127.0.0.1' -kDefaultPort = 8181 -kMaxPortsToTry = 100 - -### - -def url_is_up(url): - try: - o = urllib.urlopen(url) - except IOError: - return False - o.close() - return True - -def start_browser(port, options): - import urllib, webbrowser - - url = 'http://%s:%d'%(options.host, port) - - # Wait for server to start... - if options.debug: - sys.stderr.write('%s: Waiting for server.' % sys.argv[0]) - sys.stderr.flush() - for i in range(kMaxSleeps): - if url_is_up(url): - break - if options.debug: - sys.stderr.write('.') - sys.stderr.flush() - time.sleep(kSleepTimeout) - else: - print >>sys.stderr,'WARNING: Unable to detect that server started.' - - if options.debug: - print >>sys.stderr,'%s: Starting webbrowser...' % sys.argv[0] - webbrowser.open(url) - -def run(port, options, root): - import ScanView - try: - print 'Starting scan-view at: http://%s:%d'%(options.host, - port) - print ' Use Ctrl-C to exit.' - httpd = ScanView.create_server((options.host, port), - options, root) - httpd.serve_forever() - except KeyboardInterrupt: - pass - -def port_is_open(port): - import SocketServer - try: - t = SocketServer.TCPServer((kDefaultHost,port),None) - except: - return False - t.server_close() - return True - -def main(): - from optparse import OptionParser - parser = OptionParser('usage: %prog [options] <results directory>') - parser.set_description(__doc__) - parser.add_option( - '--host', dest="host", default=kDefaultHost, type="string", - help="Host interface to listen on. (default=%s)" % kDefaultHost) - parser.add_option( - '--port', dest="port", default=None, type="int", - help="Port to listen on. (default=%s)" % kDefaultPort) - parser.add_option("--debug", dest="debug", default=0, - action="count", - help="Print additional debugging information.") - parser.add_option("--auto-reload", dest="autoReload", default=False, - action="store_true", - help="Automatically update module for each request.") - parser.add_option("--no-browser", dest="startBrowser", default=True, - action="store_false", - help="Don't open a webbrowser on startup.") - parser.add_option("--allow-all-hosts", dest="onlyServeLocal", default=True, - action="store_false", - help='Allow connections from any host (access restricted to "127.0.0.1" by default)') - (options, args) = parser.parse_args() - - if len(args) != 1: - parser.error('No results directory specified.') - root, = args - - # Make sure this directory is in a reasonable state to view. - if not posixpath.exists(posixpath.join(root,'index.html')): - parser.error('Invalid directory, analysis results not found!') - - # Find an open port. We aren't particularly worried about race - # conditions here. Note that if the user specified a port we only - # use that one. - if options.port is not None: - port = options.port - else: - for i in range(kMaxPortsToTry): - if port_is_open(kDefaultPort + i): - port = kDefaultPort + i - break - else: - parser.error('Unable to find usable port in [%d,%d)'%(kDefaultPort, - kDefaultPort+kMaxPortsToTry)) - - # Kick off thread to wait for server and start web browser, if - # requested. - if options.startBrowser: - t = thread.start_new_thread(start_browser, (port,options)) - - run(port, options, root) - -if __name__ == '__main__': - main() diff --git a/contrib/llvm/tools/clang/tools/scan-view/startfile.py b/contrib/llvm/tools/clang/tools/scan-view/startfile.py deleted file mode 100644 index e8fbe2d..0000000 --- a/contrib/llvm/tools/clang/tools/scan-view/startfile.py +++ /dev/null @@ -1,203 +0,0 @@ -"""Utility for opening a file using the default application in a cross-platform -manner. Modified from http://code.activestate.com/recipes/511443/. -""" - -__version__ = '1.1x' -__all__ = ['open'] - -import os -import sys -import webbrowser -import subprocess - -_controllers = {} -_open = None - - -class BaseController(object): - '''Base class for open program controllers.''' - - def __init__(self, name): - self.name = name - - def open(self, filename): - raise NotImplementedError - - -class Controller(BaseController): - '''Controller for a generic open program.''' - - def __init__(self, *args): - super(Controller, self).__init__(os.path.basename(args[0])) - self.args = list(args) - - def _invoke(self, cmdline): - if sys.platform[:3] == 'win': - closefds = False - startupinfo = subprocess.STARTUPINFO() - startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW - else: - closefds = True - startupinfo = None - - if (os.environ.get('DISPLAY') or sys.platform[:3] == 'win' or - sys.platform == 'darwin'): - inout = file(os.devnull, 'r+') - else: - # for TTY programs, we need stdin/out - inout = None - - # if possible, put the child precess in separate process group, - # so keyboard interrupts don't affect child precess as well as - # Python - setsid = getattr(os, 'setsid', None) - if not setsid: - setsid = getattr(os, 'setpgrp', None) - - pipe = subprocess.Popen(cmdline, stdin=inout, stdout=inout, - stderr=inout, close_fds=closefds, - preexec_fn=setsid, startupinfo=startupinfo) - - # It is assumed that this kind of tools (gnome-open, kfmclient, - # exo-open, xdg-open and open for OSX) immediately exit after lauching - # the specific application - returncode = pipe.wait() - if hasattr(self, 'fixreturncode'): - returncode = self.fixreturncode(returncode) - return not returncode - - def open(self, filename): - if isinstance(filename, basestring): - cmdline = self.args + [filename] - else: - # assume it is a sequence - cmdline = self.args + filename - try: - return self._invoke(cmdline) - except OSError: - return False - - -# Platform support for Windows -if sys.platform[:3] == 'win': - - class Start(BaseController): - '''Controller for the win32 start progam through os.startfile.''' - - def open(self, filename): - try: - os.startfile(filename) - except WindowsError: - # [Error 22] No application is associated with the specified - # file for this operation: '<URL>' - return False - else: - return True - - _controllers['windows-default'] = Start('start') - _open = _controllers['windows-default'].open - - -# Platform support for MacOS -elif sys.platform == 'darwin': - _controllers['open']= Controller('open') - _open = _controllers['open'].open - - -# Platform support for Unix -else: - - import commands - - # @WARNING: use the private API of the webbrowser module - from webbrowser import _iscommand - - class KfmClient(Controller): - '''Controller for the KDE kfmclient program.''' - - def __init__(self, kfmclient='kfmclient'): - super(KfmClient, self).__init__(kfmclient, 'exec') - self.kde_version = self.detect_kde_version() - - def detect_kde_version(self): - kde_version = None - try: - info = commands.getoutput('kde-config --version') - - for line in info.splitlines(): - if line.startswith('KDE'): - kde_version = line.split(':')[-1].strip() - break - except (OSError, RuntimeError): - pass - - return kde_version - - def fixreturncode(self, returncode): - if returncode is not None and self.kde_version > '3.5.4': - return returncode - else: - return os.EX_OK - - def detect_desktop_environment(): - '''Checks for known desktop environments - - Return the desktop environments name, lowercase (kde, gnome, xfce) - or "generic" - - ''' - - desktop_environment = 'generic' - - if os.environ.get('KDE_FULL_SESSION') == 'true': - desktop_environment = 'kde' - elif os.environ.get('GNOME_DESKTOP_SESSION_ID'): - desktop_environment = 'gnome' - else: - try: - info = commands.getoutput('xprop -root _DT_SAVE_MODE') - if ' = "xfce4"' in info: - desktop_environment = 'xfce' - except (OSError, RuntimeError): - pass - - return desktop_environment - - - def register_X_controllers(): - if _iscommand('kfmclient'): - _controllers['kde-open'] = KfmClient() - - for command in ('gnome-open', 'exo-open', 'xdg-open'): - if _iscommand(command): - _controllers[command] = Controller(command) - - def get(): - controllers_map = { - 'gnome': 'gnome-open', - 'kde': 'kde-open', - 'xfce': 'exo-open', - } - - desktop_environment = detect_desktop_environment() - - try: - controller_name = controllers_map[desktop_environment] - return _controllers[controller_name].open - - except KeyError: - if _controllers.has_key('xdg-open'): - return _controllers['xdg-open'].open - else: - return webbrowser.open - - - if os.environ.get("DISPLAY"): - register_X_controllers() - _open = get() - - -def open(filename): - '''Open a file or an URL in the registered default application.''' - - return _open(filename) diff --git a/contrib/llvm/tools/clang/utils/ABITest/ABITestGen.py b/contrib/llvm/tools/clang/utils/ABITest/ABITestGen.py deleted file mode 100755 index c45a0c3..0000000 --- a/contrib/llvm/tools/clang/utils/ABITest/ABITestGen.py +++ /dev/null @@ -1,653 +0,0 @@ -#!/usr/bin/env python - -from pprint import pprint -import random, atexit, time -from random import randrange -import re - -from Enumeration import * -from TypeGen import * - -#### - -class TypePrinter: - def __init__(self, output, outputHeader=None, - outputTests=None, outputDriver=None, - headerName=None, info=None): - self.output = output - self.outputHeader = outputHeader - self.outputTests = outputTests - self.outputDriver = outputDriver - self.writeBody = outputHeader or outputTests or outputDriver - self.types = {} - self.testValues = {} - self.testReturnValues = {} - self.layoutTests = [] - - if info: - for f in (self.output,self.outputHeader,self.outputTests,self.outputDriver): - if f: - print >>f,info - - if self.writeBody: - print >>self.output, '#include <stdio.h>\n' - if self.outputTests: - print >>self.outputTests, '#include <stdio.h>' - print >>self.outputTests, '#include <string.h>' - print >>self.outputTests, '#include <assert.h>\n' - - if headerName: - for f in (self.output,self.outputTests,self.outputDriver): - if f is not None: - print >>f, '#include "%s"\n'%(headerName,) - - if self.outputDriver: - print >>self.outputDriver, '#include <stdio.h>' - print >>self.outputDriver, '#include <stdlib.h>\n' - print >>self.outputDriver, 'int main(int argc, char **argv) {' - print >>self.outputDriver, ' int index = -1;' - print >>self.outputDriver, ' if (argc > 1) index = atoi(argv[1]);' - - def finish(self): - if self.layoutTests: - print >>self.output, 'int main(int argc, char **argv) {' - print >>self.output, ' int index = -1;' - print >>self.output, ' if (argc > 1) index = atoi(argv[1]);' - for i,f in self.layoutTests: - print >>self.output, ' if (index == -1 || index == %d)' % i - print >>self.output, ' %s();' % f - print >>self.output, ' return 0;' - print >>self.output, '}' - - if self.outputDriver: - print >>self.outputDriver, ' printf("DONE\\n");' - print >>self.outputDriver, ' return 0;' - print >>self.outputDriver, '}' - - def getTypeName(self, T): - if isinstance(T,BuiltinType): - return T.name - name = self.types.get(T) - if name is None: - name = 'T%d'%(len(self.types),) - # Reserve slot - self.types[T] = None - if self.outputHeader: - print >>self.outputHeader,T.getTypedefDef(name, self) - else: - print >>self.output,T.getTypedefDef(name, self) - if self.outputTests: - print >>self.outputTests,T.getTypedefDef(name, self) - self.types[T] = name - return name - - def writeLayoutTest(self, i, ty): - tyName = self.getTypeName(ty) - tyNameClean = tyName.replace(' ','_').replace('*','star') - fnName = 'test_%s' % tyNameClean - - print >>self.output,'void %s(void) {' % fnName - self.printSizeOfType(' %s'%fnName, tyName, ty, self.output) - self.printAlignOfType(' %s'%fnName, tyName, ty, self.output) - self.printOffsetsOfType(' %s'%fnName, tyName, ty, self.output) - print >>self.output,'}' - print >>self.output - - self.layoutTests.append((i,fnName)) - - def writeFunction(self, i, FT): - args = ', '.join(['%s arg%d'%(self.getTypeName(t),i) for i,t in enumerate(FT.argTypes)]) - if not args: - args = 'void' - - if FT.returnType is None: - retvalName = None - retvalTypeName = 'void' - else: - retvalTypeName = self.getTypeName(FT.returnType) - if self.writeBody or self.outputTests: - retvalName = self.getTestReturnValue(FT.returnType) - - fnName = 'fn%d'%(FT.index,) - if self.outputHeader: - print >>self.outputHeader,'%s %s(%s);'%(retvalTypeName, fnName, args) - elif self.outputTests: - print >>self.outputTests,'%s %s(%s);'%(retvalTypeName, fnName, args) - - print >>self.output,'%s %s(%s)'%(retvalTypeName, fnName, args), - if self.writeBody: - print >>self.output, '{' - - for i,t in enumerate(FT.argTypes): - self.printValueOfType(' %s'%fnName, 'arg%d'%i, t) - - if retvalName is not None: - print >>self.output, ' return %s;'%(retvalName,) - print >>self.output, '}' - else: - print >>self.output, '{}' - print >>self.output - - if self.outputDriver: - print >>self.outputDriver, ' if (index == -1 || index == %d) {' % i - print >>self.outputDriver, ' extern void test_%s(void);' % fnName - print >>self.outputDriver, ' test_%s();' % fnName - print >>self.outputDriver, ' }' - - if self.outputTests: - if self.outputHeader: - print >>self.outputHeader, 'void test_%s(void);'%(fnName,) - - if retvalName is None: - retvalTests = None - else: - retvalTests = self.getTestValuesArray(FT.returnType) - tests = map(self.getTestValuesArray, FT.argTypes) - print >>self.outputTests, 'void test_%s(void) {'%(fnName,) - - if retvalTests is not None: - print >>self.outputTests, ' printf("%s: testing return.\\n");'%(fnName,) - print >>self.outputTests, ' for (int i=0; i<%d; ++i) {'%(retvalTests[1],) - args = ', '.join(['%s[%d]'%(t,randrange(l)) for t,l in tests]) - print >>self.outputTests, ' %s RV;'%(retvalTypeName,) - print >>self.outputTests, ' %s = %s[i];'%(retvalName, retvalTests[0]) - print >>self.outputTests, ' RV = %s(%s);'%(fnName, args) - self.printValueOfType(' %s_RV'%fnName, 'RV', FT.returnType, output=self.outputTests, indent=4) - self.checkTypeValues('RV', '%s[i]' % retvalTests[0], FT.returnType, output=self.outputTests, indent=4) - print >>self.outputTests, ' }' - - if tests: - print >>self.outputTests, ' printf("%s: testing arguments.\\n");'%(fnName,) - for i,(array,length) in enumerate(tests): - for j in range(length): - args = ['%s[%d]'%(t,randrange(l)) for t,l in tests] - args[i] = '%s[%d]'%(array,j) - print >>self.outputTests, ' %s(%s);'%(fnName, ', '.join(args),) - print >>self.outputTests, '}' - - def getTestReturnValue(self, type): - typeName = self.getTypeName(type) - info = self.testReturnValues.get(typeName) - if info is None: - name = '%s_retval'%(typeName.replace(' ','_').replace('*','star'),) - print >>self.output, '%s %s;'%(typeName,name) - if self.outputHeader: - print >>self.outputHeader, 'extern %s %s;'%(typeName,name) - elif self.outputTests: - print >>self.outputTests, 'extern %s %s;'%(typeName,name) - info = self.testReturnValues[typeName] = name - return info - - def getTestValuesArray(self, type): - typeName = self.getTypeName(type) - info = self.testValues.get(typeName) - if info is None: - name = '%s_values'%(typeName.replace(' ','_').replace('*','star'),) - print >>self.outputTests, 'static %s %s[] = {'%(typeName,name) - length = 0 - for item in self.getTestValues(type): - print >>self.outputTests, '\t%s,'%(item,) - length += 1 - print >>self.outputTests,'};' - info = self.testValues[typeName] = (name,length) - return info - - def getTestValues(self, t): - if isinstance(t, BuiltinType): - if t.name=='float': - for i in ['0.0','-1.0','1.0']: - yield i+'f' - elif t.name=='double': - for i in ['0.0','-1.0','1.0']: - yield i - elif t.name in ('void *'): - yield '(void*) 0' - yield '(void*) -1' - else: - yield '(%s) 0'%(t.name,) - yield '(%s) -1'%(t.name,) - yield '(%s) 1'%(t.name,) - elif isinstance(t, EnumType): - for i in range(0, len(t.enumerators)): - yield 'enum%dval%d' % (t.index, i) - elif isinstance(t, RecordType): - nonPadding = [f for f in t.fields - if not f.isPaddingBitField()] - - if not nonPadding: - yield '{ }' - return - - # FIXME: Use designated initializers to access non-first - # fields of unions. - if t.isUnion: - for v in self.getTestValues(nonPadding[0]): - yield '{ %s }' % v - return - - fieldValues = map(list, map(self.getTestValues, nonPadding)) - for i,values in enumerate(fieldValues): - for v in values: - elements = map(random.choice,fieldValues) - elements[i] = v - yield '{ %s }'%(', '.join(elements)) - - elif isinstance(t, ComplexType): - for t in self.getTestValues(t.elementType): - yield '%s + %s * 1i'%(t,t) - elif isinstance(t, ArrayType): - values = list(self.getTestValues(t.elementType)) - if not values: - yield '{ }' - for i in range(t.numElements): - for v in values: - elements = [random.choice(values) for i in range(t.numElements)] - elements[i] = v - yield '{ %s }'%(', '.join(elements)) - else: - raise NotImplementedError,'Cannot make tests values of type: "%s"'%(t,) - - def printSizeOfType(self, prefix, name, t, output=None, indent=2): - print >>output, '%*sprintf("%s: sizeof(%s) = %%ld\\n", (long)sizeof(%s));'%(indent, '', prefix, name, name) - def printAlignOfType(self, prefix, name, t, output=None, indent=2): - print >>output, '%*sprintf("%s: __alignof__(%s) = %%ld\\n", (long)__alignof__(%s));'%(indent, '', prefix, name, name) - def printOffsetsOfType(self, prefix, name, t, output=None, indent=2): - if isinstance(t, RecordType): - for i,f in enumerate(t.fields): - if f.isBitField(): - continue - fname = 'field%d' % i - print >>output, '%*sprintf("%s: __builtin_offsetof(%s, %s) = %%ld\\n", (long)__builtin_offsetof(%s, %s));'%(indent, '', prefix, name, fname, name, fname) - - def printValueOfType(self, prefix, name, t, output=None, indent=2): - if output is None: - output = self.output - if isinstance(t, BuiltinType): - if t.name.endswith('long long'): - code = 'lld' - elif t.name.endswith('long'): - code = 'ld' - elif t.name.split(' ')[-1] in ('_Bool','char','short','int'): - code = 'd' - elif t.name in ('float','double'): - code = 'f' - elif t.name == 'long double': - code = 'Lf' - else: - code = 'p' - print >>output, '%*sprintf("%s: %s = %%%s\\n", %s);'%(indent, '', prefix, name, code, name) - elif isinstance(t, EnumType): - print >>output, '%*sprintf("%s: %s = %%d\\n", %s);'%(indent, '', prefix, name, name) - elif isinstance(t, RecordType): - if not t.fields: - print >>output, '%*sprintf("%s: %s (empty)\\n");'%(indent, '', prefix, name) - for i,f in enumerate(t.fields): - if f.isPaddingBitField(): - continue - fname = '%s.field%d'%(name,i) - self.printValueOfType(prefix, fname, f, output=output, indent=indent) - elif isinstance(t, ComplexType): - self.printValueOfType(prefix, '(__real %s)'%name, t.elementType, output=output,indent=indent) - self.printValueOfType(prefix, '(__imag %s)'%name, t.elementType, output=output,indent=indent) - elif isinstance(t, ArrayType): - for i in range(t.numElements): - # Access in this fashion as a hackish way to portably - # access vectors. - if t.isVector: - self.printValueOfType(prefix, '((%s*) &%s)[%d]'%(t.elementType,name,i), t.elementType, output=output,indent=indent) - else: - self.printValueOfType(prefix, '%s[%d]'%(name,i), t.elementType, output=output,indent=indent) - else: - raise NotImplementedError,'Cannot print value of type: "%s"'%(t,) - - def checkTypeValues(self, nameLHS, nameRHS, t, output=None, indent=2): - prefix = 'foo' - if output is None: - output = self.output - if isinstance(t, BuiltinType): - print >>output, '%*sassert(%s == %s);' % (indent, '', nameLHS, nameRHS) - elif isinstance(t, EnumType): - print >>output, '%*sassert(%s == %s);' % (indent, '', nameLHS, nameRHS) - elif isinstance(t, RecordType): - for i,f in enumerate(t.fields): - if f.isPaddingBitField(): - continue - self.checkTypeValues('%s.field%d'%(nameLHS,i), '%s.field%d'%(nameRHS,i), - f, output=output, indent=indent) - if t.isUnion: - break - elif isinstance(t, ComplexType): - self.checkTypeValues('(__real %s)'%nameLHS, '(__real %s)'%nameRHS, t.elementType, output=output,indent=indent) - self.checkTypeValues('(__imag %s)'%nameLHS, '(__imag %s)'%nameRHS, t.elementType, output=output,indent=indent) - elif isinstance(t, ArrayType): - for i in range(t.numElements): - # Access in this fashion as a hackish way to portably - # access vectors. - if t.isVector: - self.checkTypeValues('((%s*) &%s)[%d]'%(t.elementType,nameLHS,i), - '((%s*) &%s)[%d]'%(t.elementType,nameRHS,i), - t.elementType, output=output,indent=indent) - else: - self.checkTypeValues('%s[%d]'%(nameLHS,i), '%s[%d]'%(nameRHS,i), - t.elementType, output=output,indent=indent) - else: - raise NotImplementedError,'Cannot print value of type: "%s"'%(t,) - -import sys - -def main(): - from optparse import OptionParser, OptionGroup - parser = OptionParser("%prog [options] {indices}") - parser.add_option("", "--mode", dest="mode", - help="autogeneration mode (random or linear) [default %default]", - type='choice', choices=('random','linear'), default='linear') - parser.add_option("", "--count", dest="count", - help="autogenerate COUNT functions according to MODE", - type=int, default=0) - parser.add_option("", "--min", dest="minIndex", metavar="N", - help="start autogeneration with the Nth function type [default %default]", - type=int, default=0) - parser.add_option("", "--max", dest="maxIndex", metavar="N", - help="maximum index for random autogeneration [default %default]", - type=int, default=10000000) - parser.add_option("", "--seed", dest="seed", - help="random number generator seed [default %default]", - type=int, default=1) - parser.add_option("", "--use-random-seed", dest="useRandomSeed", - help="use random value for initial random number generator seed", - action='store_true', default=False) - parser.add_option("-o", "--output", dest="output", metavar="FILE", - help="write output to FILE [default %default]", - type=str, default='-') - parser.add_option("-O", "--output-header", dest="outputHeader", metavar="FILE", - help="write header file for output to FILE [default %default]", - type=str, default=None) - parser.add_option("-T", "--output-tests", dest="outputTests", metavar="FILE", - help="write function tests to FILE [default %default]", - type=str, default=None) - parser.add_option("-D", "--output-driver", dest="outputDriver", metavar="FILE", - help="write test driver to FILE [default %default]", - type=str, default=None) - parser.add_option("", "--test-layout", dest="testLayout", metavar="FILE", - help="test structure layout", - action='store_true', default=False) - - group = OptionGroup(parser, "Type Enumeration Options") - # Builtins - Ints - group.add_option("", "--no-char", dest="useChar", - help="do not generate char types", - action="store_false", default=True) - group.add_option("", "--no-short", dest="useShort", - help="do not generate short types", - action="store_false", default=True) - group.add_option("", "--no-int", dest="useInt", - help="do not generate int types", - action="store_false", default=True) - group.add_option("", "--no-long", dest="useLong", - help="do not generate long types", - action="store_false", default=True) - group.add_option("", "--no-long-long", dest="useLongLong", - help="do not generate long long types", - action="store_false", default=True) - group.add_option("", "--no-unsigned", dest="useUnsigned", - help="do not generate unsigned integer types", - action="store_false", default=True) - - # Other builtins - group.add_option("", "--no-bool", dest="useBool", - help="do not generate bool types", - action="store_false", default=True) - group.add_option("", "--no-float", dest="useFloat", - help="do not generate float types", - action="store_false", default=True) - group.add_option("", "--no-double", dest="useDouble", - help="do not generate double types", - action="store_false", default=True) - group.add_option("", "--no-long-double", dest="useLongDouble", - help="do not generate long double types", - action="store_false", default=True) - group.add_option("", "--no-void-pointer", dest="useVoidPointer", - help="do not generate void* types", - action="store_false", default=True) - - # Enumerations - group.add_option("", "--no-enums", dest="useEnum", - help="do not generate enum types", - action="store_false", default=True) - - # Derived types - group.add_option("", "--no-array", dest="useArray", - help="do not generate record types", - action="store_false", default=True) - group.add_option("", "--no-complex", dest="useComplex", - help="do not generate complex types", - action="store_false", default=True) - group.add_option("", "--no-record", dest="useRecord", - help="do not generate record types", - action="store_false", default=True) - group.add_option("", "--no-union", dest="recordUseUnion", - help="do not generate union types", - action="store_false", default=True) - group.add_option("", "--no-vector", dest="useVector", - help="do not generate vector types", - action="store_false", default=True) - group.add_option("", "--no-bit-field", dest="useBitField", - help="do not generate bit-field record members", - action="store_false", default=True) - group.add_option("", "--no-builtins", dest="useBuiltins", - help="do not use any types", - action="store_false", default=True) - - # Tuning - group.add_option("", "--no-function-return", dest="functionUseReturn", - help="do not generate return types for functions", - action="store_false", default=True) - group.add_option("", "--vector-types", dest="vectorTypes", - help="comma separated list of vector types (e.g., v2i32) [default %default]", - action="store", type=str, default='v2i16, v1i64, v2i32, v4i16, v8i8, v2f32, v2i64, v4i32, v8i16, v16i8, v2f64, v4f32, v16f32', metavar="N") - group.add_option("", "--bit-fields", dest="bitFields", - help="comma separated list 'type:width' bit-field specifiers [default %default]", - action="store", type=str, default="char:0,char:4,unsigned:0,unsigned:4,unsigned:13,unsigned:24") - group.add_option("", "--max-args", dest="functionMaxArgs", - help="maximum number of arguments per function [default %default]", - action="store", type=int, default=4, metavar="N") - group.add_option("", "--max-array", dest="arrayMaxSize", - help="maximum array size [default %default]", - action="store", type=int, default=4, metavar="N") - group.add_option("", "--max-record", dest="recordMaxSize", - help="maximum number of fields per record [default %default]", - action="store", type=int, default=4, metavar="N") - group.add_option("", "--max-record-depth", dest="recordMaxDepth", - help="maximum nested structure depth [default %default]", - action="store", type=int, default=None, metavar="N") - parser.add_option_group(group) - (opts, args) = parser.parse_args() - - if not opts.useRandomSeed: - random.seed(opts.seed) - - # Contruct type generator - builtins = [] - if opts.useBuiltins: - ints = [] - if opts.useChar: ints.append(('char',1)) - if opts.useShort: ints.append(('short',2)) - if opts.useInt: ints.append(('int',4)) - # FIXME: Wrong size. - if opts.useLong: ints.append(('long',4)) - if opts.useLongLong: ints.append(('long long',8)) - if opts.useUnsigned: - ints = ([('unsigned %s'%i,s) for i,s in ints] + - [('signed %s'%i,s) for i,s in ints]) - builtins.extend(ints) - - if opts.useBool: builtins.append(('_Bool',1)) - if opts.useFloat: builtins.append(('float',4)) - if opts.useDouble: builtins.append(('double',8)) - if opts.useLongDouble: builtins.append(('long double',16)) - # FIXME: Wrong size. - if opts.useVoidPointer: builtins.append(('void*',4)) - - btg = FixedTypeGenerator([BuiltinType(n,s) for n,s in builtins]) - - bitfields = [] - for specifier in opts.bitFields.split(','): - if not specifier.strip(): - continue - name,width = specifier.strip().split(':', 1) - bitfields.append(BuiltinType(name,None,int(width))) - bftg = FixedTypeGenerator(bitfields) - - charType = BuiltinType('char',1) - shortType = BuiltinType('short',2) - intType = BuiltinType('int',4) - longlongType = BuiltinType('long long',8) - floatType = BuiltinType('float',4) - doubleType = BuiltinType('double',8) - sbtg = FixedTypeGenerator([charType, intType, floatType, doubleType]) - - atg = AnyTypeGenerator() - artg = AnyTypeGenerator() - def makeGenerator(atg, subgen, subfieldgen, useRecord, useArray, useBitField): - atg.addGenerator(btg) - if useBitField and opts.useBitField: - atg.addGenerator(bftg) - if useRecord and opts.useRecord: - assert subgen - atg.addGenerator(RecordTypeGenerator(subfieldgen, opts.recordUseUnion, - opts.recordMaxSize)) - if opts.useComplex: - # FIXME: Allow overriding builtins here - atg.addGenerator(ComplexTypeGenerator(sbtg)) - if useArray and opts.useArray: - assert subgen - atg.addGenerator(ArrayTypeGenerator(subgen, opts.arrayMaxSize)) - if opts.useVector: - vTypes = [] - for i,t in enumerate(opts.vectorTypes.split(',')): - m = re.match('v([1-9][0-9]*)([if][1-9][0-9]*)', t.strip()) - if not m: - parser.error('Invalid vector type: %r' % t) - count,kind = m.groups() - count = int(count) - type = { 'i8' : charType, - 'i16' : shortType, - 'i32' : intType, - 'i64' : longlongType, - 'f32' : floatType, - 'f64' : doubleType, - }.get(kind) - if not type: - parser.error('Invalid vector type: %r' % t) - vTypes.append(ArrayType(i, True, type, count * type.size)) - - atg.addGenerator(FixedTypeGenerator(vTypes)) - if opts.useEnum: - atg.addGenerator(EnumTypeGenerator([None, '-1', '1', '1u'], 1, 4)) - - if opts.recordMaxDepth is None: - # Fully recursive, just avoid top-level arrays. - subFTG = AnyTypeGenerator() - subTG = AnyTypeGenerator() - atg = AnyTypeGenerator() - makeGenerator(subFTG, atg, atg, True, True, True) - makeGenerator(subTG, atg, subFTG, True, True, False) - makeGenerator(atg, subTG, subFTG, True, False, False) - else: - # Make a chain of type generators, each builds smaller - # structures. - base = AnyTypeGenerator() - fbase = AnyTypeGenerator() - makeGenerator(base, None, None, False, False, False) - makeGenerator(fbase, None, None, False, False, True) - for i in range(opts.recordMaxDepth): - n = AnyTypeGenerator() - fn = AnyTypeGenerator() - makeGenerator(n, base, fbase, True, True, False) - makeGenerator(fn, base, fbase, True, True, True) - base = n - fbase = fn - atg = AnyTypeGenerator() - makeGenerator(atg, base, fbase, True, False, False) - - if opts.testLayout: - ftg = atg - else: - ftg = FunctionTypeGenerator(atg, opts.functionUseReturn, opts.functionMaxArgs) - - # Override max,min,count if finite - if opts.maxIndex is None: - if ftg.cardinality is aleph0: - opts.maxIndex = 10000000 - else: - opts.maxIndex = ftg.cardinality - opts.maxIndex = min(opts.maxIndex, ftg.cardinality) - opts.minIndex = max(0,min(opts.maxIndex-1, opts.minIndex)) - if not opts.mode=='random': - opts.count = min(opts.count, opts.maxIndex-opts.minIndex) - - if opts.output=='-': - output = sys.stdout - else: - output = open(opts.output,'w') - atexit.register(lambda: output.close()) - - outputHeader = None - if opts.outputHeader: - outputHeader = open(opts.outputHeader,'w') - atexit.register(lambda: outputHeader.close()) - - outputTests = None - if opts.outputTests: - outputTests = open(opts.outputTests,'w') - atexit.register(lambda: outputTests.close()) - - outputDriver = None - if opts.outputDriver: - outputDriver = open(opts.outputDriver,'w') - atexit.register(lambda: outputDriver.close()) - - info = '' - info += '// %s\n'%(' '.join(sys.argv),) - info += '// Generated: %s\n'%(time.strftime('%Y-%m-%d %H:%M'),) - info += '// Cardinality of function generator: %s\n'%(ftg.cardinality,) - info += '// Cardinality of type generator: %s\n'%(atg.cardinality,) - - if opts.testLayout: - info += '\n#include <stdio.h>' - - P = TypePrinter(output, - outputHeader=outputHeader, - outputTests=outputTests, - outputDriver=outputDriver, - headerName=opts.outputHeader, - info=info) - - def write(N): - try: - FT = ftg.get(N) - except RuntimeError,e: - if e.args[0]=='maximum recursion depth exceeded': - print >>sys.stderr,'WARNING: Skipped %d, recursion limit exceeded (bad arguments?)'%(N,) - return - raise - if opts.testLayout: - P.writeLayoutTest(N, FT) - else: - P.writeFunction(N, FT) - - if args: - [write(int(a)) for a in args] - - for i in range(opts.count): - if opts.mode=='linear': - index = opts.minIndex + i - else: - index = opts.minIndex + int((opts.maxIndex-opts.minIndex) * random.random()) - write(index) - - P.finish() - -if __name__=='__main__': - main() - diff --git a/contrib/llvm/tools/clang/utils/ABITest/Enumeration.py b/contrib/llvm/tools/clang/utils/ABITest/Enumeration.py deleted file mode 100644 index 47e4702..0000000 --- a/contrib/llvm/tools/clang/utils/ABITest/Enumeration.py +++ /dev/null @@ -1,276 +0,0 @@ -"""Utilities for enumeration of finite and countably infinite sets. -""" -### -# Countable iteration - -# Simplifies some calculations -class Aleph0(int): - _singleton = None - def __new__(type): - if type._singleton is None: - type._singleton = int.__new__(type) - return type._singleton - def __repr__(self): return '<aleph0>' - def __str__(self): return 'inf' - - def __cmp__(self, b): - return 1 - - def __sub__(self, b): - raise ValueError,"Cannot subtract aleph0" - __rsub__ = __sub__ - - def __add__(self, b): - return self - __radd__ = __add__ - - def __mul__(self, b): - if b == 0: return b - return self - __rmul__ = __mul__ - - def __floordiv__(self, b): - if b == 0: raise ZeroDivisionError - return self - __rfloordiv__ = __floordiv__ - __truediv__ = __floordiv__ - __rtuediv__ = __floordiv__ - __div__ = __floordiv__ - __rdiv__ = __floordiv__ - - def __pow__(self, b): - if b == 0: return 1 - return self -aleph0 = Aleph0() - -def base(line): - return line*(line+1)//2 - -def pairToN((x,y)): - line,index = x+y,y - return base(line)+index - -def getNthPairInfo(N): - # Avoid various singularities - if N==0: - return (0,0) - - # Gallop to find bounds for line - line = 1 - next = 2 - while base(next)<=N: - line = next - next = line << 1 - - # Binary search for starting line - lo = line - hi = line<<1 - while lo + 1 != hi: - #assert base(lo) <= N < base(hi) - mid = (lo + hi)>>1 - if base(mid)<=N: - lo = mid - else: - hi = mid - - line = lo - return line, N - base(line) - -def getNthPair(N): - line,index = getNthPairInfo(N) - return (line - index, index) - -def getNthPairBounded(N,W=aleph0,H=aleph0,useDivmod=False): - """getNthPairBounded(N, W, H) -> (x, y) - - Return the N-th pair such that 0 <= x < W and 0 <= y < H.""" - - if W <= 0 or H <= 0: - raise ValueError,"Invalid bounds" - elif N >= W*H: - raise ValueError,"Invalid input (out of bounds)" - - # Simple case... - if W is aleph0 and H is aleph0: - return getNthPair(N) - - # Otherwise simplify by assuming W < H - if H < W: - x,y = getNthPairBounded(N,H,W,useDivmod=useDivmod) - return y,x - - if useDivmod: - return N%W,N//W - else: - # Conceptually we want to slide a diagonal line across a - # rectangle. This gives more interesting results for large - # bounds than using divmod. - - # If in lower left, just return as usual - cornerSize = base(W) - if N < cornerSize: - return getNthPair(N) - - # Otherwise if in upper right, subtract from corner - if H is not aleph0: - M = W*H - N - 1 - if M < cornerSize: - x,y = getNthPair(M) - return (W-1-x,H-1-y) - - # Otherwise, compile line and index from number of times we - # wrap. - N = N - cornerSize - index,offset = N%W,N//W - # p = (W-1, 1+offset) + (-1,1)*index - return (W-1-index, 1+offset+index) -def getNthPairBoundedChecked(N,W=aleph0,H=aleph0,useDivmod=False,GNP=getNthPairBounded): - x,y = GNP(N,W,H,useDivmod) - assert 0 <= x < W and 0 <= y < H - return x,y - -def getNthNTuple(N, W, H=aleph0, useLeftToRight=False): - """getNthNTuple(N, W, H) -> (x_0, x_1, ..., x_W) - - Return the N-th W-tuple, where for 0 <= x_i < H.""" - - if useLeftToRight: - elts = [None]*W - for i in range(W): - elts[i],N = getNthPairBounded(N, H) - return tuple(elts) - else: - if W==0: - return () - elif W==1: - return (N,) - elif W==2: - return getNthPairBounded(N, H, H) - else: - LW,RW = W//2, W - (W//2) - L,R = getNthPairBounded(N, H**LW, H**RW) - return (getNthNTuple(L,LW,H=H,useLeftToRight=useLeftToRight) + - getNthNTuple(R,RW,H=H,useLeftToRight=useLeftToRight)) -def getNthNTupleChecked(N, W, H=aleph0, useLeftToRight=False, GNT=getNthNTuple): - t = GNT(N,W,H,useLeftToRight) - assert len(t) == W - for i in t: - assert i < H - return t - -def getNthTuple(N, maxSize=aleph0, maxElement=aleph0, useDivmod=False, useLeftToRight=False): - """getNthTuple(N, maxSize, maxElement) -> x - - Return the N-th tuple where len(x) < maxSize and for y in x, 0 <= - y < maxElement.""" - - # All zero sized tuples are isomorphic, don't ya know. - if N == 0: - return () - N -= 1 - if maxElement is not aleph0: - if maxSize is aleph0: - raise NotImplementedError,'Max element size without max size unhandled' - bounds = [maxElement**i for i in range(1, maxSize+1)] - S,M = getNthPairVariableBounds(N, bounds) - else: - S,M = getNthPairBounded(N, maxSize, useDivmod=useDivmod) - return getNthNTuple(M, S+1, maxElement, useLeftToRight=useLeftToRight) -def getNthTupleChecked(N, maxSize=aleph0, maxElement=aleph0, - useDivmod=False, useLeftToRight=False, GNT=getNthTuple): - # FIXME: maxsize is inclusive - t = GNT(N,maxSize,maxElement,useDivmod,useLeftToRight) - assert len(t) <= maxSize - for i in t: - assert i < maxElement - return t - -def getNthPairVariableBounds(N, bounds): - """getNthPairVariableBounds(N, bounds) -> (x, y) - - Given a finite list of bounds (which may be finite or aleph0), - return the N-th pair such that 0 <= x < len(bounds) and 0 <= y < - bounds[x].""" - - if not bounds: - raise ValueError,"Invalid bounds" - if not (0 <= N < sum(bounds)): - raise ValueError,"Invalid input (out of bounds)" - - level = 0 - active = range(len(bounds)) - active.sort(key=lambda i: bounds[i]) - prevLevel = 0 - for i,index in enumerate(active): - level = bounds[index] - W = len(active) - i - if level is aleph0: - H = aleph0 - else: - H = level - prevLevel - levelSize = W*H - if N<levelSize: # Found the level - idelta,delta = getNthPairBounded(N, W, H) - return active[i+idelta],prevLevel+delta - else: - N -= levelSize - prevLevel = level - else: - raise RuntimError,"Unexpected loop completion" - -def getNthPairVariableBoundsChecked(N, bounds, GNVP=getNthPairVariableBounds): - x,y = GNVP(N,bounds) - assert 0 <= x < len(bounds) and 0 <= y < bounds[x] - return (x,y) - -### - -def testPairs(): - W = 3 - H = 6 - a = [[' ' for x in range(10)] for y in range(10)] - b = [[' ' for x in range(10)] for y in range(10)] - for i in range(min(W*H,40)): - x,y = getNthPairBounded(i,W,H) - x2,y2 = getNthPairBounded(i,W,H,useDivmod=True) - print i,(x,y),(x2,y2) - a[y][x] = '%2d'%i - b[y2][x2] = '%2d'%i - - print '-- a --' - for ln in a[::-1]: - if ''.join(ln).strip(): - print ' '.join(ln) - print '-- b --' - for ln in b[::-1]: - if ''.join(ln).strip(): - print ' '.join(ln) - -def testPairsVB(): - bounds = [2,2,4,aleph0,5,aleph0] - a = [[' ' for x in range(15)] for y in range(15)] - b = [[' ' for x in range(15)] for y in range(15)] - for i in range(min(sum(bounds),40)): - x,y = getNthPairVariableBounds(i, bounds) - print i,(x,y) - a[y][x] = '%2d'%i - - print '-- a --' - for ln in a[::-1]: - if ''.join(ln).strip(): - print ' '.join(ln) - -### - -# Toggle to use checked versions of enumeration routines. -if False: - getNthPairVariableBounds = getNthPairVariableBoundsChecked - getNthPairBounded = getNthPairBoundedChecked - getNthNTuple = getNthNTupleChecked - getNthTuple = getNthTupleChecked - -if __name__ == '__main__': - testPairs() - - testPairsVB() - diff --git a/contrib/llvm/tools/clang/utils/ABITest/Makefile.test.common b/contrib/llvm/tools/clang/utils/ABITest/Makefile.test.common deleted file mode 100644 index 3c208ad..0000000 --- a/contrib/llvm/tools/clang/utils/ABITest/Makefile.test.common +++ /dev/null @@ -1,170 +0,0 @@ -# -*- Makefile -*- - -# Usage: make test.N.report -# -# COUNT can be over-ridden to change the number of tests generated per -# file, and TESTARGS is used to change the type generation. Make sure -# to 'make clean' after changing either of these parameters. - -TESTARGS := --no-unsigned --no-vector --no-complex --no-bool - -COUNT := 1 -TIMEOUT := 5 - -CFLAGS := -std=gnu99 - -X_COMPILER := gcc -X_LL_CFLAGS := -emit-llvm -S -Y_COMPILER := clang -Y_LL_CFLAGS := -emit-llvm -S -CC := gcc - -### - -ABITESTGEN := ../ABITestGen.py - -ifndef VERBOSE - Verb := @ -endif - -.PHONY: test.%.report -test.%.report: temps/test.%.xx.diff temps/test.%.xy.diff temps/test.%.yx.diff temps/test.%.yy.diff - @ok=1;\ - for t in $^; do \ - if [ -s $$t ]; then \ - echo "TEST $*: $$t failed"; \ - ok=0;\ - fi; \ - done; \ - if [ $$ok -eq 1 ]; then \ - true; \ - else \ - false; \ - fi - - -.PHONY: test.%.defs-report -test.%.defs-report: temps/test.%.defs.diff - @for t in $^; do \ - if [ -s $$t ]; then \ - echo "TEST $*: $$t failed"; \ - cat $$t; \ - fi; \ - done - -.PHONY: test.%.build -test.%.build: temps/test.%.ref temps/test.%.xx temps/test.%.xy temps/test.%.yx temps/test.%.yy temps/test.%.x.defs temps/test.%.y.defs - @true - -### - -# Diffs and output - -.PRECIOUS: temps/.dir - -.PRECIOUS: temps/test.%.xx.diff -temps/test.%.xx.diff: temps/test.%.ref.out temps/test.%.xx.out - $(Verb) diff $^ > $@ || true -.PRECIOUS: temps/test.%.xy.diff -temps/test.%.xy.diff: temps/test.%.ref.out temps/test.%.xy.out - $(Verb) diff $^ > $@ || true -.PRECIOUS: temps/test.%.yx.diff -temps/test.%.yx.diff: temps/test.%.ref.out temps/test.%.yx.out - $(Verb) diff $^ > $@ || true -.PRECIOUS: temps/test.%.yy.diff -temps/test.%.yy.diff: temps/test.%.ref.out temps/test.%.yy.out - $(Verb) diff $^ > $@ || true -.PRECIOUS: temps/test.%.defs.diff -temps/test.%.defs.diff: temps/test.%.x.defs temps/test.%.y.defs - $(Verb) zipdifflines \ - --replace "%struct.T[0-9]+" "%struct.s" \ - --replace "%union.T[0-9]+" "%struct.s" \ - --replace "byval align [0-9]+" "byval" \ - $^ > $@ - -.PRECIOUS: temps/test.%.out -temps/test.%.out: temps/test.% - -$(Verb) ./$< > $@ - -# Executables - -.PRECIOUS: temps/test.%.ref -temps/test.%.ref: temps/test.%.driver.ref.o temps/test.%.a.ref.o temps/test.%.b.ref.o - $(Verb) $(CC) $(CFLAGS) $(CC_CFLAGS) -O3 -o $@ $^ -.PRECIOUS: temps/test.%.xx -temps/test.%.xx: temps/test.%.driver.ref.o temps/test.%.a.x.o temps/test.%.b.x.o - $(Verb) $(CC) $(CFLAGS) $(CC_CFLAGS) -O3 -o $@ $^ -.PRECIOUS: temps/test.%.xy -temps/test.%.xy: temps/test.%.driver.ref.o temps/test.%.a.x.o temps/test.%.b.y.o - $(Verb) $(CC) $(CFLAGS) $(CC_CFLAGS) -O3 -o $@ $^ -.PRECIOUS: temps/test.%.yx -temps/test.%.yx: temps/test.%.driver.ref.o temps/test.%.a.y.o temps/test.%.b.x.o - $(Verb) $(CC) $(CFLAGS) $(CC_CFLAGS) -O3 -o $@ $^ -.PRECIOUS: temps/test.%.yy -temps/test.%.yy: temps/test.%.driver.ref.o temps/test.%.a.y.o temps/test.%.b.y.o - $(Verb) $(CC) $(CFLAGS) $(CC_CFLAGS) -O3 -o $@ $^ - -# Object files - -.PRECIOUS: temps/test.%.ref.o -temps/test.%.ref.o: inputs/test.%.c temps/.dir - $(Verb) $(CC) -c $(CFLAGS) $(CC_CFLAGS) -o $@ $< -.PRECIOUS: temps/test.%.x.o -temps/test.%.x.o: inputs/test.%.c temps/.dir - $(Verb) $(X_COMPILER) -c $(CFLAGS) $(X_CFLAGS) -o $@ $< -.PRECIOUS: temps/test.%.y.o -temps/test.%.y.o: inputs/test.%.c temps/.dir - $(Verb) $(Y_COMPILER) -c $(CFLAGS) $(Y_CFLAGS) -o $@ $< - -.PRECIOUS: temps/test.%.x.defs -temps/test.%.x.defs: temps/test.%.a.x.ll temps/.dir - -$(Verb) -grep '^define ' $< > $@ -.PRECIOUS: temps/test.%.y.defs -temps/test.%.y.defs: temps/test.%.a.y.ll temps/.dir - -$(Verb) -grep '^define ' $< > $@ - -.PRECIOUS: temps/test.%.a.x.ll -temps/test.%.a.x.ll: inputs/test.%.a.c temps/.dir - $(Verb) $(X_COMPILER) $(CFLAGS) $(X_LL_CFLAGS) $(X_CFLAGS) -o $@ $< -.PRECIOUS: temps/test.%.b.x.ll -temps/test.%.b.x.ll: inputs/test.%.b.c temps/.dir - $(Verb) $(X_COMPILER) $(CFLAGS) $(X_LL_CFLAGS) $(X_CFLAGS) -o $@ $< -.PRECIOUS: temps/test.%.a.y.ll -temps/test.%.a.y.ll: inputs/test.%.a.c temps/.dir - $(Verb) $(Y_COMPILER) $(CFLAGS) $(Y_LL_CFLAGS) $(Y_CFLAGS) -o $@ $< -.PRECIOUS: temps/test.%.b.y.ll -temps/test.%.b.y.ll: inputs/test.%.b.c temps/.dir - $(Verb) $(Y_COMPILER) $(CFLAGS) $(Y_LL_CFLAGS) $(Y_CFLAGS) -o $@ $< - -# Input generation - -.PHONY: test.%.top -test.%.top: inputs/test.%.a.c inputs/test.%.b.c inputs/test.%.driver.c - @true - -.PRECIOUS: inputs/test.%.a.c inputs/test.%.b.c inputs/test.%.driver.c -inputs/test.%.a.c: test.%.generate - @true -inputs/test.%.b.c: test.%.generate - @true -inputs/test.%.driver.c: test.%.generate - @true - -.PHONY: test.%.generate -.PRECIOUS: inputs/.dir -test.%.generate: $(ABITESTGEN) inputs/.dir - $(Verb) $(ABITESTGEN) $(TESTARGS) -o inputs/test.$*.a.c -T inputs/test.$*.b.c -D inputs/test.$*.driver.c --min=$(shell expr $* '*' $(COUNT)) --count=$(COUNT) - -# Cleaning - -clean-temps: - $(Verb) rm -rf temps - -clean: - $(Verb) rm -rf temps inputs - -# Etc. - -%/.dir: - $(Verb) mkdir -p $* > /dev/null - $(Verb) $(DATE) > $@ diff --git a/contrib/llvm/tools/clang/utils/ABITest/TypeGen.py b/contrib/llvm/tools/clang/utils/ABITest/TypeGen.py deleted file mode 100644 index 40ea791..0000000 --- a/contrib/llvm/tools/clang/utils/ABITest/TypeGen.py +++ /dev/null @@ -1,462 +0,0 @@ -"""Flexible enumeration of C types.""" - -from Enumeration import * - -# TODO: - -# - struct improvements (flexible arrays, packed & -# unpacked, alignment) -# - objective-c qualified id -# - anonymous / transparent unions -# - VLAs -# - block types -# - K&R functions -# - pass arguments of different types (test extension, transparent union) -# - varargs - -### -# Actual type types - -class Type: - def isBitField(self): - return False - - def isPaddingBitField(self): - return False - -class BuiltinType(Type): - def __init__(self, name, size, bitFieldSize=None): - self.name = name - self.size = size - self.bitFieldSize = bitFieldSize - - def isBitField(self): - return self.bitFieldSize is not None - - def isPaddingBitField(self): - return self.bitFieldSize is 0 - - def getBitFieldSize(self): - assert self.isBitField() - return self.bitFieldSize - - def sizeof(self): - return self.size - - def __str__(self): - return self.name - -class EnumType(Type): - def __init__(self, index, enumerators): - self.index = index - self.enumerators = enumerators - - def getEnumerators(self): - result = '' - for i, init in enumerate(self.enumerators): - if i > 0: - result = result + ', ' - result = result + 'enum%dval%d' % (self.index, i) - if init: - result = result + ' = %s' % (init) - - return result - - def __str__(self): - return 'enum { %s }' % (self.getEnumerators()) - - def getTypedefDef(self, name, printer): - return 'typedef enum %s { %s } %s;'%(name, self.getEnumerators(), name) - -class RecordType(Type): - def __init__(self, index, isUnion, fields): - self.index = index - self.isUnion = isUnion - self.fields = fields - self.name = None - - def __str__(self): - def getField(t): - if t.isBitField(): - return "%s : %d;" % (t, t.getBitFieldSize()) - else: - return "%s;" % t - - return '%s { %s }'%(('struct','union')[self.isUnion], - ' '.join(map(getField, self.fields))) - - def getTypedefDef(self, name, printer): - def getField((i, t)): - if t.isBitField(): - if t.isPaddingBitField(): - return '%s : 0;'%(printer.getTypeName(t),) - else: - return '%s field%d : %d;'%(printer.getTypeName(t),i, - t.getBitFieldSize()) - else: - return '%s field%d;'%(printer.getTypeName(t),i) - fields = map(getField, enumerate(self.fields)) - # Name the struct for more readable LLVM IR. - return 'typedef %s %s { %s } %s;'%(('struct','union')[self.isUnion], - name, ' '.join(fields), name) - -class ArrayType(Type): - def __init__(self, index, isVector, elementType, size): - if isVector: - # Note that for vectors, this is the size in bytes. - assert size > 0 - else: - assert size is None or size >= 0 - self.index = index - self.isVector = isVector - self.elementType = elementType - self.size = size - if isVector: - eltSize = self.elementType.sizeof() - assert not (self.size % eltSize) - self.numElements = self.size // eltSize - else: - self.numElements = self.size - - def __str__(self): - if self.isVector: - return 'vector (%s)[%d]'%(self.elementType,self.size) - elif self.size is not None: - return '(%s)[%d]'%(self.elementType,self.size) - else: - return '(%s)[]'%(self.elementType,) - - def getTypedefDef(self, name, printer): - elementName = printer.getTypeName(self.elementType) - if self.isVector: - return 'typedef %s %s __attribute__ ((vector_size (%d)));'%(elementName, - name, - self.size) - else: - if self.size is None: - sizeStr = '' - else: - sizeStr = str(self.size) - return 'typedef %s %s[%s];'%(elementName, name, sizeStr) - -class ComplexType(Type): - def __init__(self, index, elementType): - self.index = index - self.elementType = elementType - - def __str__(self): - return '_Complex (%s)'%(self.elementType) - - def getTypedefDef(self, name, printer): - return 'typedef _Complex %s %s;'%(printer.getTypeName(self.elementType), name) - -class FunctionType(Type): - def __init__(self, index, returnType, argTypes): - self.index = index - self.returnType = returnType - self.argTypes = argTypes - - def __str__(self): - if self.returnType is None: - rt = 'void' - else: - rt = str(self.returnType) - if not self.argTypes: - at = 'void' - else: - at = ', '.join(map(str, self.argTypes)) - return '%s (*)(%s)'%(rt, at) - - def getTypedefDef(self, name, printer): - if self.returnType is None: - rt = 'void' - else: - rt = str(self.returnType) - if not self.argTypes: - at = 'void' - else: - at = ', '.join(map(str, self.argTypes)) - return 'typedef %s (*%s)(%s);'%(rt, name, at) - -### -# Type enumerators - -class TypeGenerator(object): - def __init__(self): - self.cache = {} - - def setCardinality(self): - abstract - - def get(self, N): - T = self.cache.get(N) - if T is None: - assert 0 <= N < self.cardinality - T = self.cache[N] = self.generateType(N) - return T - - def generateType(self, N): - abstract - -class FixedTypeGenerator(TypeGenerator): - def __init__(self, types): - TypeGenerator.__init__(self) - self.types = types - self.setCardinality() - - def setCardinality(self): - self.cardinality = len(self.types) - - def generateType(self, N): - return self.types[N] - -# Factorial -def fact(n): - result = 1 - while n > 0: - result = result * n - n = n - 1 - return result - -# Compute the number of combinations (n choose k) -def num_combinations(n, k): - return fact(n) / (fact(k) * fact(n - k)) - -# Enumerate the combinations choosing k elements from the list of values -def combinations(values, k): - # From ActiveState Recipe 190465: Generator for permutations, - # combinations, selections of a sequence - if k==0: yield [] - else: - for i in xrange(len(values)-k+1): - for cc in combinations(values[i+1:],k-1): - yield [values[i]]+cc - -class EnumTypeGenerator(TypeGenerator): - def __init__(self, values, minEnumerators, maxEnumerators): - TypeGenerator.__init__(self) - self.values = values - self.minEnumerators = minEnumerators - self.maxEnumerators = maxEnumerators - self.setCardinality() - - def setCardinality(self): - self.cardinality = 0 - for num in range(self.minEnumerators, self.maxEnumerators + 1): - self.cardinality += num_combinations(len(self.values), num) - - def generateType(self, n): - # Figure out the number of enumerators in this type - numEnumerators = self.minEnumerators - valuesCovered = 0 - while numEnumerators < self.maxEnumerators: - comb = num_combinations(len(self.values), numEnumerators) - if valuesCovered + comb > n: - break - numEnumerators = numEnumerators + 1 - valuesCovered += comb - - # Find the requested combination of enumerators and build a - # type from it. - i = 0 - for enumerators in combinations(self.values, numEnumerators): - if i == n - valuesCovered: - return EnumType(n, enumerators) - - i = i + 1 - - assert False - -class ComplexTypeGenerator(TypeGenerator): - def __init__(self, typeGen): - TypeGenerator.__init__(self) - self.typeGen = typeGen - self.setCardinality() - - def setCardinality(self): - self.cardinality = self.typeGen.cardinality - - def generateType(self, N): - return ComplexType(N, self.typeGen.get(N)) - -class VectorTypeGenerator(TypeGenerator): - def __init__(self, typeGen, sizes): - TypeGenerator.__init__(self) - self.typeGen = typeGen - self.sizes = tuple(map(int,sizes)) - self.setCardinality() - - def setCardinality(self): - self.cardinality = len(self.sizes)*self.typeGen.cardinality - - def generateType(self, N): - S,T = getNthPairBounded(N, len(self.sizes), self.typeGen.cardinality) - return ArrayType(N, True, self.typeGen.get(T), self.sizes[S]) - -class FixedArrayTypeGenerator(TypeGenerator): - def __init__(self, typeGen, sizes): - TypeGenerator.__init__(self) - self.typeGen = typeGen - self.sizes = tuple(size) - self.setCardinality() - - def setCardinality(self): - self.cardinality = len(self.sizes)*self.typeGen.cardinality - - def generateType(self, N): - S,T = getNthPairBounded(N, len(self.sizes), self.typeGen.cardinality) - return ArrayType(N, false, self.typeGen.get(T), self.sizes[S]) - -class ArrayTypeGenerator(TypeGenerator): - def __init__(self, typeGen, maxSize, useIncomplete=False, useZero=False): - TypeGenerator.__init__(self) - self.typeGen = typeGen - self.useIncomplete = useIncomplete - self.useZero = useZero - self.maxSize = int(maxSize) - self.W = useIncomplete + useZero + self.maxSize - self.setCardinality() - - def setCardinality(self): - self.cardinality = self.W * self.typeGen.cardinality - - def generateType(self, N): - S,T = getNthPairBounded(N, self.W, self.typeGen.cardinality) - if self.useIncomplete: - if S==0: - size = None - S = None - else: - S = S - 1 - if S is not None: - if self.useZero: - size = S - else: - size = S + 1 - return ArrayType(N, False, self.typeGen.get(T), size) - -class RecordTypeGenerator(TypeGenerator): - def __init__(self, typeGen, useUnion, maxSize): - TypeGenerator.__init__(self) - self.typeGen = typeGen - self.useUnion = bool(useUnion) - self.maxSize = int(maxSize) - self.setCardinality() - - def setCardinality(self): - M = 1 + self.useUnion - if self.maxSize is aleph0: - S = aleph0 * self.typeGen.cardinality - else: - S = 0 - for i in range(self.maxSize+1): - S += M * (self.typeGen.cardinality ** i) - self.cardinality = S - - def generateType(self, N): - isUnion,I = False,N - if self.useUnion: - isUnion,I = (I&1),I>>1 - fields = map(self.typeGen.get,getNthTuple(I,self.maxSize,self.typeGen.cardinality)) - return RecordType(N, isUnion, fields) - -class FunctionTypeGenerator(TypeGenerator): - def __init__(self, typeGen, useReturn, maxSize): - TypeGenerator.__init__(self) - self.typeGen = typeGen - self.useReturn = useReturn - self.maxSize = maxSize - self.setCardinality() - - def setCardinality(self): - if self.maxSize is aleph0: - S = aleph0 * self.typeGen.cardinality() - elif self.useReturn: - S = 0 - for i in range(1,self.maxSize+1+1): - S += self.typeGen.cardinality ** i - else: - S = 0 - for i in range(self.maxSize+1): - S += self.typeGen.cardinality ** i - self.cardinality = S - - def generateType(self, N): - if self.useReturn: - # Skip the empty tuple - argIndices = getNthTuple(N+1, self.maxSize+1, self.typeGen.cardinality) - retIndex,argIndices = argIndices[0],argIndices[1:] - retTy = self.typeGen.get(retIndex) - else: - retTy = None - argIndices = getNthTuple(N, self.maxSize, self.typeGen.cardinality) - args = map(self.typeGen.get, argIndices) - return FunctionType(N, retTy, args) - -class AnyTypeGenerator(TypeGenerator): - def __init__(self): - TypeGenerator.__init__(self) - self.generators = [] - self.bounds = [] - self.setCardinality() - self._cardinality = None - - def getCardinality(self): - if self._cardinality is None: - return aleph0 - else: - return self._cardinality - def setCardinality(self): - self.bounds = [g.cardinality for g in self.generators] - self._cardinality = sum(self.bounds) - cardinality = property(getCardinality, None) - - def addGenerator(self, g): - self.generators.append(g) - for i in range(100): - prev = self._cardinality - self._cardinality = None - for g in self.generators: - g.setCardinality() - self.setCardinality() - if (self._cardinality is aleph0) or prev==self._cardinality: - break - else: - raise RuntimeError,"Infinite loop in setting cardinality" - - def generateType(self, N): - index,M = getNthPairVariableBounds(N, self.bounds) - return self.generators[index].get(M) - -def test(): - fbtg = FixedTypeGenerator([BuiltinType('char', 4), - BuiltinType('char', 4, 0), - BuiltinType('int', 4, 5)]) - - fields1 = AnyTypeGenerator() - fields1.addGenerator( fbtg ) - - fields0 = AnyTypeGenerator() - fields0.addGenerator( fbtg ) -# fields0.addGenerator( RecordTypeGenerator(fields1, False, 4) ) - - btg = FixedTypeGenerator([BuiltinType('char', 4), - BuiltinType('int', 4)]) - etg = EnumTypeGenerator([None, '-1', '1', '1u'], 0, 3) - - atg = AnyTypeGenerator() - atg.addGenerator( btg ) - atg.addGenerator( RecordTypeGenerator(fields0, False, 4) ) - atg.addGenerator( etg ) - print 'Cardinality:',atg.cardinality - for i in range(100): - if i == atg.cardinality: - try: - atg.get(i) - raise RuntimeError,"Cardinality was wrong" - except AssertionError: - break - print '%4d: %s'%(i, atg.get(i)) - -if __name__ == '__main__': - test() diff --git a/contrib/llvm/tools/clang/utils/ABITest/build-and-summarize-all.sh b/contrib/llvm/tools/clang/utils/ABITest/build-and-summarize-all.sh deleted file mode 100755 index 23e34a4..0000000 --- a/contrib/llvm/tools/clang/utils/ABITest/build-and-summarize-all.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -set -eu - -if [ $# != 1 ]; then - echo "usage: $0 <num-tests>" - exit 1 -fi - -for bits in 32 64; do - for kind in return-types single-args; do - echo "-- $kind-$bits --" - (cd $kind-$bits && ../build-and-summarize.sh $1) - done -done diff --git a/contrib/llvm/tools/clang/utils/ABITest/build-and-summarize.sh b/contrib/llvm/tools/clang/utils/ABITest/build-and-summarize.sh deleted file mode 100755 index 602728b..0000000 --- a/contrib/llvm/tools/clang/utils/ABITest/build-and-summarize.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -set -eu - -if [ $# != 1 ]; then - echo "usage: $0 <num-tests>" - exit 1 -fi - -dir=$(dirname $0) -$dir/build.sh $1 &> /dev/null || true -../summarize.sh $1 &> fails-x.txt -cat fails-x.txt -wc -l fails-x.txt diff --git a/contrib/llvm/tools/clang/utils/ABITest/build.sh b/contrib/llvm/tools/clang/utils/ABITest/build.sh deleted file mode 100755 index a50d14a..0000000 --- a/contrib/llvm/tools/clang/utils/ABITest/build.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh - -set -eu - -if [ $# != 1 ]; then - echo "usage: $0 <num-tests>" - exit 1 -fi - -CPUS=2 -make -j $CPUS \ - $(for i in $(seq 0 $1); do echo test.$i.report; done) -k diff --git a/contrib/llvm/tools/clang/utils/ABITest/layout/Makefile b/contrib/llvm/tools/clang/utils/ABITest/layout/Makefile deleted file mode 100644 index 0520625..0000000 --- a/contrib/llvm/tools/clang/utils/ABITest/layout/Makefile +++ /dev/null @@ -1,68 +0,0 @@ -# Usage: make test.N.report -# -# COUNT can be over-ridden to change the number of tests generated per -# file, and TESTARGS is used to change the type generation. Make sure -# to 'make clean' after changing either of these parameters. - -ABITESTGEN := ../ABITestGen.py -TESTARGS := --max-args 0 --test-layout -COUNT := 1000 -TIMEOUT := 5 - -CFLAGS := -std=gnu99 - -X_COMPILER := llvm-gcc -Y_COMPILER := clang -CC := gcc - -ifeq (0, 0) -X_CFLAGS := -m32 -Y_CFLAGS := -m32 -CC_CFLAGS := -m32 -else -X_CFLAGS := -m64 -Y_CFLAGS := -m64 -CC_CFLAGS := -m64 -endif - -.PHONY: test.%.report -test.%.report: test.%.x.diff test.%.y.diff - @for t in $^; do \ - if [ -s $$t ]; then \ - echo "TEST $*: $$t failed"; \ - fi; \ - done - -.PHONY: test.%.build -test.%.build: test.%.ref test.%.x test.%.y - @true - -### - -.PRECIOUS: test.%.x.diff -test.%.x.diff: test.%.ref.out test.%.x.out - -diff $^ > $@ -.PRECIOUS: test.%.y.diff -test.%.y.diff: test.%.ref.out test.%.y.out - -diff $^ > $@ - -.PRECIOUS: test.%.out -test.%.out: test.% - -./$< > $@ - -.PRECIOUS: test.%.ref -test.%.ref: test.%.c - $(CC) $(CFLAGS) $(CC_CFLAGS) -o $@ $^ -.PRECIOUS: test.%.x -test.%.x: test.%.c - $(X_COMPILER) $(CFLAGS) $(X_CFLAGS) -o $@ $^ -.PRECIOUS: test.%.y -test.%.y: test.%.c - $(Y_COMPILER) $(CFLAGS) $(Y_CFLAGS) -o $@ $^ - -.PRECIOUS: test.%.c -test.%.c: $(ABITESTGEN) - $(ABITESTGEN) $(TESTARGS) -o $@ --min=$(shell expr $* '*' $(COUNT)) --count=$(COUNT) - -clean: - rm -f test.* *~ diff --git a/contrib/llvm/tools/clang/utils/ABITest/return-types-32/Makefile b/contrib/llvm/tools/clang/utils/ABITest/return-types-32/Makefile deleted file mode 100644 index df1c53f..0000000 --- a/contrib/llvm/tools/clang/utils/ABITest/return-types-32/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -X_CFLAGS := -m32 -Y_CFLAGS := -m32 -CC_CFLAGS := -m32 - -include ../Makefile.test.common - -TESTARGS += --max-args 0 diff --git a/contrib/llvm/tools/clang/utils/ABITest/return-types-64/Makefile b/contrib/llvm/tools/clang/utils/ABITest/return-types-64/Makefile deleted file mode 100644 index 9616e45..0000000 --- a/contrib/llvm/tools/clang/utils/ABITest/return-types-64/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -X_CFLAGS := -m64 -Y_CFLAGS := -m64 -CC_CFLAGS := -m64 - -include ../Makefile.test.common - -TESTARGS += --max-args 0 diff --git a/contrib/llvm/tools/clang/utils/ABITest/single-args-32/Makefile b/contrib/llvm/tools/clang/utils/ABITest/single-args-32/Makefile deleted file mode 100644 index 9ff417f..0000000 --- a/contrib/llvm/tools/clang/utils/ABITest/single-args-32/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -X_CFLAGS := -m32 -Y_CFLAGS := -m32 -CC_CFLAGS := -m32 - -include ../Makefile.test.common - -TESTARGS += --no-function-return --max-args 1 diff --git a/contrib/llvm/tools/clang/utils/ABITest/single-args-64/Makefile b/contrib/llvm/tools/clang/utils/ABITest/single-args-64/Makefile deleted file mode 100644 index b8acb70..0000000 --- a/contrib/llvm/tools/clang/utils/ABITest/single-args-64/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# Usage: make test.N.report -# -# COUNT can be over-ridden to change the number of tests generated per -# file, and TESTARGS is used to change the type generation. Make sure -# to 'make clean' after changing either of these parameters. - -X_CFLAGS := -m64 -Y_CFLAGS := -m64 -CC_CFLAGS := -m64 - -include ../Makefile.test.common - -TESTARGS += --no-function-return --max-args 1 diff --git a/contrib/llvm/tools/clang/utils/ABITest/summarize.sh b/contrib/llvm/tools/clang/utils/ABITest/summarize.sh deleted file mode 100755 index 3efb52b..0000000 --- a/contrib/llvm/tools/clang/utils/ABITest/summarize.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -set -eu - -if [ $# != 1 ]; then - echo "usage: $0 <num-tests>" - exit 1 -fi - -for i in $(seq 0 $1); do - if (! make test.$i.report &> /dev/null); then - echo "FAIL: $i"; - fi; -done - diff --git a/contrib/llvm/tools/clang/utils/C++Tests/Clang-Code-Compile/lit.local.cfg b/contrib/llvm/tools/clang/utils/C++Tests/Clang-Code-Compile/lit.local.cfg deleted file mode 100644 index 59d3466..0000000 --- a/contrib/llvm/tools/clang/utils/C++Tests/Clang-Code-Compile/lit.local.cfg +++ /dev/null @@ -1,26 +0,0 @@ -# -*- Python -*- - -# Configuration file for the 'lit' test runner. - -def getRoot(config): - if not config.parent: - return config - return getRoot(config.parent) - -root = getRoot(config) - -# testFormat: The test format to use to interpret tests. -cxxflags = ['-D__STDC_LIMIT_MACROS', - '-D__STDC_CONSTANT_MACROS', - '-Wno-sign-compare', - '-I%s/include' % root.llvm_src_root, - '-I%s/include' % root.llvm_obj_root, - '-I%s/tools/clang/include' % root.llvm_src_root, - '-I%s/tools/clang/include' % root.llvm_obj_root] -config.test_format = \ - lit.formats.OneCommandPerFileTest(command=[root.clang, '-emit-llvm', '-c', - '-o', '/dev/null'] + cxxflags, - dir='%s/tools/clang/lib' % root.llvm_src_root, - recursive=True, - pattern='^(.*\\.cpp)$') - diff --git a/contrib/llvm/tools/clang/utils/C++Tests/Clang-Code-Syntax/lit.local.cfg b/contrib/llvm/tools/clang/utils/C++Tests/Clang-Code-Syntax/lit.local.cfg deleted file mode 100644 index 8f00c8d..0000000 --- a/contrib/llvm/tools/clang/utils/C++Tests/Clang-Code-Syntax/lit.local.cfg +++ /dev/null @@ -1,25 +0,0 @@ -# -*- Python -*- - -# Configuration file for the 'lit' test runner. - -def getRoot(config): - if not config.parent: - return config - return getRoot(config.parent) - -root = getRoot(config) - -# testFormat: The test format to use to interpret tests. -cxxflags = ['-D__STDC_LIMIT_MACROS', - '-D__STDC_CONSTANT_MACROS', - '-Wno-sign-compare', - '-I%s/include' % root.llvm_src_root, - '-I%s/include' % root.llvm_obj_root, - '-I%s/tools/clang/include' % root.llvm_src_root, - '-I%s/tools/clang/include' % root.llvm_obj_root] -config.test_format = \ - lit.formats.OneCommandPerFileTest(command=[root.clang, - '-fsyntax-only'] + cxxflags, - dir='%s/tools/clang/lib' % root.llvm_src_root, - recursive=True, - pattern='^(.*\\.cpp)$') diff --git a/contrib/llvm/tools/clang/utils/C++Tests/Clang-Syntax/lit.local.cfg b/contrib/llvm/tools/clang/utils/C++Tests/Clang-Syntax/lit.local.cfg deleted file mode 100644 index 89fdd8e..0000000 --- a/contrib/llvm/tools/clang/utils/C++Tests/Clang-Syntax/lit.local.cfg +++ /dev/null @@ -1,24 +0,0 @@ -# -*- Python -*- - -# Configuration file for the 'lit' test runner. - -def getRoot(config): - if not config.parent: - return config - return getRoot(config.parent) - -root = getRoot(config) - -# testFormat: The test format to use to interpret tests. -config.test_format = lit.formats.SyntaxCheckTest(compiler=root.clang, - dir='%s/tools/clang/include/clang' % root.llvm_src_root, - recursive=True, - pattern='^(.*\\.h)$', - extra_cxx_args=['-D__STDC_LIMIT_MACROS', - '-D__STDC_CONSTANT_MACROS', - '-Wno-sign-compare', - '-Werror', - '-I%s/include' % root.llvm_src_root, - '-I%s/include' % root.llvm_obj_root, - '-I%s/tools/clang/include' % root.llvm_src_root, - '-I%s/tools/clang/include' % root.llvm_obj_root]) diff --git a/contrib/llvm/tools/clang/utils/C++Tests/LLVM-Code-Compile/lit.local.cfg b/contrib/llvm/tools/clang/utils/C++Tests/LLVM-Code-Compile/lit.local.cfg deleted file mode 100644 index 6676e31..0000000 --- a/contrib/llvm/tools/clang/utils/C++Tests/LLVM-Code-Compile/lit.local.cfg +++ /dev/null @@ -1,56 +0,0 @@ -# -*- Python -*- - -# Configuration file for the 'lit' test runner. - -def getRoot(config): - if not config.parent: - return config - return getRoot(config.parent) - -root = getRoot(config) - -# testFormat: The test format to use to interpret tests. -target_obj_root = root.llvm_obj_root -cxxflags = ['-D__STDC_LIMIT_MACROS', - '-D__STDC_CONSTANT_MACROS', - '-Wno-sign-compare', - '-I%s/include' % root.llvm_src_root, - '-I%s/include' % root.llvm_obj_root, - '-I%s/lib/Target/Alpha' % root.llvm_src_root, - '-I%s/lib/Target/ARM' % root.llvm_src_root, - '-I%s/lib/Target/Blackfin' % root.llvm_src_root, - '-I%s/lib/Target/CBackend' % root.llvm_src_root, - '-I%s/lib/Target/CellSPU' % root.llvm_src_root, - '-I%s/lib/Target/CppBackend' % root.llvm_src_root, - '-I%s/lib/Target/Mips' % root.llvm_src_root, - '-I%s/lib/Target/MSIL' % root.llvm_src_root, - '-I%s/lib/Target/MSP430' % root.llvm_src_root, - '-I%s/lib/Target/PIC16' % root.llvm_src_root, - '-I%s/lib/Target/PowerPC' % root.llvm_src_root, - '-I%s/lib/Target/Sparc' % root.llvm_src_root, - '-I%s/lib/Target/SystemZ' % root.llvm_src_root, - '-I%s/lib/Target/X86' % root.llvm_src_root, - '-I%s/lib/Target/XCore' % root.llvm_src_root, - '-I%s/lib/Target/Alpha' % target_obj_root, - '-I%s/lib/Target/ARM' % target_obj_root, - '-I%s/lib/Target/Blackfin' % target_obj_root, - '-I%s/lib/Target/CBackend' % target_obj_root, - '-I%s/lib/Target/CellSPU' % target_obj_root, - '-I%s/lib/Target/CppBackend' % target_obj_root, - '-I%s/lib/Target/Mips' % target_obj_root, - '-I%s/lib/Target/MSIL' % target_obj_root, - '-I%s/lib/Target/MSP430' % target_obj_root, - '-I%s/lib/Target/PIC16' % target_obj_root, - '-I%s/lib/Target/PowerPC' % target_obj_root, - '-I%s/lib/Target/Sparc' % target_obj_root, - '-I%s/lib/Target/SystemZ' % target_obj_root, - '-I%s/lib/Target/X86' % target_obj_root, - '-I%s/lib/Target/XCore' % target_obj_root]; - -config.test_format = \ - lit.formats.OneCommandPerFileTest(command=[root.clang, '-emit-llvm', '-c', - '-o', '/dev/null'] + cxxflags, - dir='%s/lib' % root.llvm_src_root, - recursive=True, - pattern='^(.*\\.cpp)$') - diff --git a/contrib/llvm/tools/clang/utils/C++Tests/LLVM-Code-Symbols/check-symbols b/contrib/llvm/tools/clang/utils/C++Tests/LLVM-Code-Symbols/check-symbols deleted file mode 100755 index cd54eed..0000000 --- a/contrib/llvm/tools/clang/utils/C++Tests/LLVM-Code-Symbols/check-symbols +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env python - -import subprocess -import difflib - -def capture_2(args0, args1): - import subprocess - p0 = subprocess.Popen(args0, stdin=None, stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - p1 = subprocess.Popen(args1, stdin=p0.stdout, stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - out,_ = p1.communicate() - return out - -def normalize_nm(data): - lines = data.split('\n') - lines.sort() - - # FIXME: Ignore common symbols for now. - lines = [ln for ln in lines - if not ln.startswith(' C')] - - return lines - -def main(): - import sys - clang = sys.argv[1] - flags = sys.argv[2:] - - # FIXME: Relax to include undefined symbols. - nm_args = ["llvm-nm", "-extern-only", "-defined-only"] - - llvmgcc_args = ["llvm-gcc"] + flags + ["-emit-llvm","-c","-o","-"] - clang_args = [clang] + flags + ["-emit-llvm","-c","-o","-"] - - llvmgcc_nm = capture_2(llvmgcc_args, nm_args) - clang_nm = capture_2(clang_args, nm_args) - - llvmgcc_nm = normalize_nm(llvmgcc_nm) - clang_nm = normalize_nm(clang_nm) - - if llvmgcc_nm == clang_nm: - sys.exit(0) - - print ' '.join(llvmgcc_args), '|', ' '.join(nm_args) - print ' '.join(clang_args), '|', ' '.join(nm_args) - for line in difflib.unified_diff(llvmgcc_nm, clang_nm, - fromfile="llvm-gcc symbols", - tofile="clang symbols"): - print line - sys.exit(1) - -if __name__ == '__main__': - main() diff --git a/contrib/llvm/tools/clang/utils/C++Tests/LLVM-Code-Symbols/lit.local.cfg b/contrib/llvm/tools/clang/utils/C++Tests/LLVM-Code-Symbols/lit.local.cfg deleted file mode 100644 index c328a25..0000000 --- a/contrib/llvm/tools/clang/utils/C++Tests/LLVM-Code-Symbols/lit.local.cfg +++ /dev/null @@ -1,56 +0,0 @@ -# -*- Python -*- - -# Configuration file for the 'lit' test runner. - -def getRoot(config): - if not config.parent: - return config - return getRoot(config.parent) - -root = getRoot(config) - -# testFormat: The test format to use to interpret tests. -target_obj_root = root.llvm_obj_root -cxxflags = ['-D__STDC_LIMIT_MACROS', - '-D__STDC_CONSTANT_MACROS', - '-Wno-sign-compare', - '-I%s/include' % root.llvm_src_root, - '-I%s/include' % root.llvm_obj_root, - '-I%s/lib/Target/Alpha' % root.llvm_src_root, - '-I%s/lib/Target/ARM' % root.llvm_src_root, - '-I%s/lib/Target/Blackfin' % root.llvm_src_root, - '-I%s/lib/Target/CBackend' % root.llvm_src_root, - '-I%s/lib/Target/CellSPU' % root.llvm_src_root, - '-I%s/lib/Target/CppBackend' % root.llvm_src_root, - '-I%s/lib/Target/Mips' % root.llvm_src_root, - '-I%s/lib/Target/MSIL' % root.llvm_src_root, - '-I%s/lib/Target/MSP430' % root.llvm_src_root, - '-I%s/lib/Target/PIC16' % root.llvm_src_root, - '-I%s/lib/Target/PowerPC' % root.llvm_src_root, - '-I%s/lib/Target/Sparc' % root.llvm_src_root, - '-I%s/lib/Target/SystemZ' % root.llvm_src_root, - '-I%s/lib/Target/X86' % root.llvm_src_root, - '-I%s/lib/Target/XCore' % root.llvm_src_root, - '-I%s/lib/Target/Alpha' % target_obj_root, - '-I%s/lib/Target/ARM' % target_obj_root, - '-I%s/lib/Target/Blackfin' % target_obj_root, - '-I%s/lib/Target/CBackend' % target_obj_root, - '-I%s/lib/Target/CellSPU' % target_obj_root, - '-I%s/lib/Target/CppBackend' % target_obj_root, - '-I%s/lib/Target/Mips' % target_obj_root, - '-I%s/lib/Target/MSIL' % target_obj_root, - '-I%s/lib/Target/MSP430' % target_obj_root, - '-I%s/lib/Target/PIC16' % target_obj_root, - '-I%s/lib/Target/PowerPC' % target_obj_root, - '-I%s/lib/Target/Sparc' % target_obj_root, - '-I%s/lib/Target/SystemZ' % target_obj_root, - '-I%s/lib/Target/X86' % target_obj_root, - '-I%s/lib/Target/XCore' % target_obj_root]; - -kScript = os.path.join(os.path.dirname(__file__), "check-symbols") -config.test_format = \ - lit.formats.OneCommandPerFileTest(command=[kScript, root.clang] + cxxflags, - dir='%s/lib' % root.llvm_src_root, - recursive=True, - pattern='^(.*\\.cpp)$') - diff --git a/contrib/llvm/tools/clang/utils/C++Tests/LLVM-Code-Syntax/lit.local.cfg b/contrib/llvm/tools/clang/utils/C++Tests/LLVM-Code-Syntax/lit.local.cfg deleted file mode 100644 index 6e67965..0000000 --- a/contrib/llvm/tools/clang/utils/C++Tests/LLVM-Code-Syntax/lit.local.cfg +++ /dev/null @@ -1,54 +0,0 @@ -# -*- Python -*- - -# Configuration file for the 'lit' test runner. - -def getRoot(config): - if not config.parent: - return config - return getRoot(config.parent) - -root = getRoot(config) - -# testFormat: The test format to use to interpret tests. -target_obj_root = root.llvm_obj_root -cxxflags = ['-D__STDC_LIMIT_MACROS', - '-D__STDC_CONSTANT_MACROS', - '-I%s/include' % root.llvm_src_root, - '-I%s/include' % root.llvm_obj_root, - '-I%s/lib/Target/Alpha' % root.llvm_src_root, - '-I%s/lib/Target/ARM' % root.llvm_src_root, - '-I%s/lib/Target/Blackfin' % root.llvm_src_root, - '-I%s/lib/Target/CBackend' % root.llvm_src_root, - '-I%s/lib/Target/CellSPU' % root.llvm_src_root, - '-I%s/lib/Target/CppBackend' % root.llvm_src_root, - '-I%s/lib/Target/Mips' % root.llvm_src_root, - '-I%s/lib/Target/MSIL' % root.llvm_src_root, - '-I%s/lib/Target/MSP430' % root.llvm_src_root, - '-I%s/lib/Target/PIC16' % root.llvm_src_root, - '-I%s/lib/Target/PowerPC' % root.llvm_src_root, - '-I%s/lib/Target/Sparc' % root.llvm_src_root, - '-I%s/lib/Target/SystemZ' % root.llvm_src_root, - '-I%s/lib/Target/X86' % root.llvm_src_root, - '-I%s/lib/Target/XCore' % root.llvm_src_root, - '-I%s/lib/Target/Alpha' % target_obj_root, - '-I%s/lib/Target/ARM' % target_obj_root, - '-I%s/lib/Target/Blackfin' % target_obj_root, - '-I%s/lib/Target/CBackend' % target_obj_root, - '-I%s/lib/Target/CellSPU' % target_obj_root, - '-I%s/lib/Target/CppBackend' % target_obj_root, - '-I%s/lib/Target/Mips' % target_obj_root, - '-I%s/lib/Target/MSIL' % target_obj_root, - '-I%s/lib/Target/MSP430' % target_obj_root, - '-I%s/lib/Target/PIC16' % target_obj_root, - '-I%s/lib/Target/PowerPC' % target_obj_root, - '-I%s/lib/Target/Sparc' % target_obj_root, - '-I%s/lib/Target/SystemZ' % target_obj_root, - '-I%s/lib/Target/X86' % target_obj_root, - '-I%s/lib/Target/XCore' % target_obj_root]; - -config.test_format = \ - lit.formats.OneCommandPerFileTest(command=[root.clang, - '-fsyntax-only'] + cxxflags, - dir='%s/lib' % root.llvm_src_root, - recursive=True, - pattern='^(.*\\.cpp)$') diff --git a/contrib/llvm/tools/clang/utils/C++Tests/LLVM-Syntax/lit.local.cfg b/contrib/llvm/tools/clang/utils/C++Tests/LLVM-Syntax/lit.local.cfg deleted file mode 100644 index cb0e566..0000000 --- a/contrib/llvm/tools/clang/utils/C++Tests/LLVM-Syntax/lit.local.cfg +++ /dev/null @@ -1,24 +0,0 @@ -# -*- Python -*- - -# Configuration file for the 'lit' test runner. - -def getRoot(config): - if not config.parent: - return config - return getRoot(config.parent) - -root = getRoot(config) - -# testFormat: The test format to use to interpret tests. -config.test_format = lit.formats.SyntaxCheckTest(compiler=root.clang, - dir='%s/include/llvm' % root.llvm_src_root, - recursive=True, - pattern='^(.*\\.h|[^.]*)$', - extra_cxx_args=['-D__STDC_LIMIT_MACROS', - '-D__STDC_CONSTANT_MACROS', - '-Werror', - '-I%s/include' % root.llvm_src_root, - '-I%s/include' % root.llvm_obj_root]) - -config.excludes = ['AbstractTypeUser.h', 'DAGISelHeader.h', - 'AIXDataTypesFix.h', 'Solaris.h'] diff --git a/contrib/llvm/tools/clang/utils/C++Tests/lit.cfg b/contrib/llvm/tools/clang/utils/C++Tests/lit.cfg deleted file mode 100644 index 274ca10..0000000 --- a/contrib/llvm/tools/clang/utils/C++Tests/lit.cfg +++ /dev/null @@ -1,27 +0,0 @@ -# -*- Python -*- - -# Configuration file for the 'lit' test runner. - -# Load the main clang test config so we can leech its clang finding logic. -lit.load_config(config, os.path.join(os.path.dirname(__file__), - '..', '..', 'test', 'lit.cfg')) -assert config.clang, "Failed to set clang!?" - -# name: The name of this test suite. -config.name = 'Clang++' - -# suffixes: A list of file extensions to treat as test files, this is actually -# set by on_clone(). -config.suffixes = [] - -# Reset these from the Clang config. -config.test_source_root = config.test_exec_root = None - -# Don't run Clang and LLVM code checks by default. -config.excludes = [] -if not lit.params.get('run_clang_all'): - config.excludes.append('Clang-Code-Syntax') - config.excludes.append('Clang-Code-Compile') - config.excludes.append('LLVM-Code-Syntax') - config.excludes.append('LLVM-Code-Compile') - config.excludes.append('LLVM-Code-Symbols') diff --git a/contrib/llvm/tools/clang/utils/C++Tests/stdc++-Syntax/lit.local.cfg b/contrib/llvm/tools/clang/utils/C++Tests/stdc++-Syntax/lit.local.cfg deleted file mode 100644 index eb04866..0000000 --- a/contrib/llvm/tools/clang/utils/C++Tests/stdc++-Syntax/lit.local.cfg +++ /dev/null @@ -1,17 +0,0 @@ -# -*- Python -*- - -# Configuration file for the 'lit' test runner. - -def getRoot(config): - if not config.parent: - return config - return getRoot(config.parent) - -root = getRoot(config) - -# testFormat: The test format to use to interpret tests. -config.test_format = lit.formats.SyntaxCheckTest(compiler=root.clang, - dir='/usr/include/c++/4.2.1', - recursive=False, - pattern='^(.*\\.h|[^.]*)$') - diff --git a/contrib/llvm/tools/clang/utils/CIndex/completion_logger_server.py b/contrib/llvm/tools/clang/utils/CIndex/completion_logger_server.py deleted file mode 100755 index 0652b1f..0000000 --- a/contrib/llvm/tools/clang/utils/CIndex/completion_logger_server.py +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env python -import sys -from socket import * -from time import strftime -import datetime - -def main(): - if len(sys.argv) < 4: - print "completion_logger_server.py <listen address> <listen port> <log file>" - exit(1) - - host = sys.argv[1] - port = int(sys.argv[2]) - buf = 1024 * 8 - addr = (host,port) - - # Create socket and bind to address - UDPSock = socket(AF_INET,SOCK_DGRAM) - UDPSock.bind(addr) - - print "Listing on {0}:{1} and logging to '{2}'".format(host, port, sys.argv[3]) - - # Open the logging file. - f = open(sys.argv[3], "a") - - # Receive messages - while 1: - data,addr = UDPSock.recvfrom(buf) - if not data: - break - else: - f.write("{ "); - f.write("\"time\": \"{0}\"".format(datetime.datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S'))) - f.write(", \"sender\": \"{0}\" ".format(addr[0])) - f.write(", \"data\": ") - f.write(data) - f.write(" }\n") - f.flush() - - # Close socket - UDPSock.close() - -if __name__ == '__main__': - main() diff --git a/contrib/llvm/tools/clang/utils/CaptureCmd b/contrib/llvm/tools/clang/utils/CaptureCmd deleted file mode 100755 index 705585c..0000000 --- a/contrib/llvm/tools/clang/utils/CaptureCmd +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env python - -"""CaptureCmd - A generic tool for capturing information about the -invocations of another program. - -Usage --- -1. Move the original tool to a safe known location. - -2. Link CaptureCmd to the original tool's location. - -3. Define CAPTURE_CMD_PROGRAM to the known location of the original -tool; this must be an absolute path. - -4. Define CAPTURE_CMD_DIR to a directory to write invocation -information to. -""" - -import hashlib -import os -import sys -import time - -def saveCaptureData(prefix, dir, object): - string = repr(object) + '\n' - key = hashlib.sha1(string).hexdigest() - path = os.path.join(dir, - prefix + key) - if not os.path.exists(path): - f = open(path, 'wb') - f.write(string) - f.close() - return prefix + key - -def main(): - program = os.getenv('CAPTURE_CMD_PROGRAM') - dir = os.getenv('CAPTURE_CMD_DIR') - fallback = os.getenv('CAPTURE_CMD_FALLBACK') - if not program: - raise ValueError('CAPTURE_CMD_PROGRAM is not defined!') - if not dir: - raise ValueError('CAPTURE_CMD_DIR is not defined!') - - # Make the output directory if it doesn't already exist. - if not os.path.exists(dir): - os.mkdir(dir, 0700) - - # Get keys for various data. - env = os.environ.items() - env.sort() - envKey = saveCaptureData('env-', dir, env) - cwdKey = saveCaptureData('cwd-', dir, os.getcwd()) - argvKey = saveCaptureData('argv-', dir, sys.argv) - entry = (time.time(), envKey, cwdKey, argvKey) - saveCaptureData('cmd-', dir, entry) - - if fallback: - pid = os.fork() - if not pid: - os.execv(program, sys.argv) - os._exit(1) - else: - res = os.waitpid(pid, 0) - if not res: - os.execv(fallback, sys.argv) - os._exit(1) - os._exit(res) - else: - os.execv(program, sys.argv) - os._exit(1) - -if __name__ == '__main__': - main() diff --git a/contrib/llvm/tools/clang/utils/CmpDriver b/contrib/llvm/tools/clang/utils/CmpDriver deleted file mode 100755 index 16b1081..0000000 --- a/contrib/llvm/tools/clang/utils/CmpDriver +++ /dev/null @@ -1,210 +0,0 @@ -#!/usr/bin/env python - -import subprocess - -def splitArgs(s): - it = iter(s) - current = '' - inQuote = False - for c in it: - if c == '"': - if inQuote: - inQuote = False - yield current + '"' - else: - inQuote = True - current = '"' - elif inQuote: - if c == '\\': - current += c - current += it.next() - else: - current += c - elif not c.isspace(): - yield c - -def insertMinimumPadding(a, b, dist): - """insertMinimumPadding(a,b) -> (a',b') - - Return two lists of equal length, where some number of Nones have - been inserted into the shorter list such that sum(map(dist, a', - b')) is minimized. - - Assumes dist(X, Y) -> int and non-negative. - """ - - def cost(a, b): - return sum(map(dist, a + [None] * (len(b) - len(a)), b)) - - # Normalize so a is shortest. - if len(b) < len(a): - b, a = insertMinimumPadding(b, a, dist) - return a,b - - # For each None we have to insert... - for i in range(len(b) - len(a)): - # For each position we could insert it... - current = cost(a, b) - best = None - for j in range(len(a) + 1): - a_0 = a[:j] + [None] + a[j:] - candidate = cost(a_0, b) - if best is None or candidate < best[0]: - best = (candidate, a_0, j) - a = best[1] - return a,b - -class ZipperDiff(object): - """ZipperDiff - Simple (slow) diff only accomodating inserts.""" - - def __init__(self, a, b): - self.a = a - self.b = b - - def dist(self, a, b): - return a != b - - def getDiffs(self): - a,b = insertMinimumPadding(self.a, self.b, self.dist) - for aElt,bElt in zip(a,b): - if self.dist(aElt, bElt): - yield aElt,bElt - -class DriverZipperDiff(ZipperDiff): - def isTempFile(self, filename): - if filename[0] != '"' or filename[-1] != '"': - return False - return (filename.startswith('/tmp/', 1) or - filename.startswith('/var/', 1)) - - def dist(self, a, b): - if a and b and self.isTempFile(a) and self.isTempFile(b): - return 0 - return super(DriverZipperDiff, self).dist(a,b) - -class CompileInfo: - def __init__(self, out, err, res): - self.commands = [] - - # Standard out isn't used for much. - self.stdout = out - self.stderr = '' - - # FIXME: Compare error messages as well. - for ln in err.split('\n'): - if (ln == 'Using built-in specs.' or - ln.startswith('Target: ') or - ln.startswith('Configured with: ') or - ln.startswith('Thread model: ') or - ln.startswith('gcc version') or - ln.startswith('clang version')): - pass - elif ln.strip().startswith('"'): - self.commands.append(list(splitArgs(ln))) - else: - self.stderr += ln + '\n' - - self.stderr = self.stderr.strip() - self.exitCode = res - -def captureDriverInfo(cmd, args): - p = subprocess.Popen([cmd,'-###'] + args, - stdin=None, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - out,err = p.communicate() - res = p.wait() - return CompileInfo(out,err,res) - -def main(): - import os, sys - - args = sys.argv[1:] - driverA = os.getenv('DRIVER_A') or 'gcc' - driverB = os.getenv('DRIVER_B') or 'clang' - - infoA = captureDriverInfo(driverA, args) - infoB = captureDriverInfo(driverB, args) - - differ = False - - # Compare stdout. - if infoA.stdout != infoB.stdout: - print '-- STDOUT DIFFERS -' - print 'A OUTPUT: ',infoA.stdout - print 'B OUTPUT: ',infoB.stdout - print - - diff = ZipperDiff(infoA.stdout.split('\n'), - infoB.stdout.split('\n')) - for i,(aElt,bElt) in enumerate(diff.getDiffs()): - if aElt is None: - print 'A missing: %s' % bElt - elif bElt is None: - print 'B missing: %s' % aElt - else: - print 'mismatch: A: %s' % aElt - print ' B: %s' % bElt - - differ = True - - # Compare stderr. - if infoA.stderr != infoB.stderr: - print '-- STDERR DIFFERS -' - print 'A STDERR: ',infoA.stderr - print 'B STDERR: ',infoB.stderr - print - - diff = ZipperDiff(infoA.stderr.split('\n'), - infoB.stderr.split('\n')) - for i,(aElt,bElt) in enumerate(diff.getDiffs()): - if aElt is None: - print 'A missing: %s' % bElt - elif bElt is None: - print 'B missing: %s' % aElt - else: - print 'mismatch: A: %s' % aElt - print ' B: %s' % bElt - - differ = True - - # Compare commands. - for i,(a,b) in enumerate(map(None, infoA.commands, infoB.commands)): - if a is None: - print 'A MISSING:',' '.join(b) - differ = True - continue - elif b is None: - print 'B MISSING:',' '.join(a) - differ = True - continue - - diff = DriverZipperDiff(a,b) - diffs = list(diff.getDiffs()) - if diffs: - print '-- COMMAND %d DIFFERS -' % i - print 'A COMMAND:',' '.join(a) - print 'B COMMAND:',' '.join(b) - print - for i,(aElt,bElt) in enumerate(diffs): - if aElt is None: - print 'A missing: %s' % bElt - elif bElt is None: - print 'B missing: %s' % aElt - else: - print 'mismatch: A: %s' % aElt - print ' B: %s' % bElt - differ = True - - # Compare result codes. - if infoA.exitCode != infoB.exitCode: - print '-- EXIT CODES DIFFER -' - print 'A: ',infoA.exitCode - print 'B: ',infoB.exitCode - differ = True - - if differ: - sys.exit(1) - -if __name__ == '__main__': - main() diff --git a/contrib/llvm/tools/clang/utils/FindSpecRefs b/contrib/llvm/tools/clang/utils/FindSpecRefs deleted file mode 100755 index 9097f93..0000000 --- a/contrib/llvm/tools/clang/utils/FindSpecRefs +++ /dev/null @@ -1,910 +0,0 @@ -#!/usr/bin/env python - -import os -import re -import time -from pprint import pprint - -### - -c99URL = 'http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf' -c99TOC = [('Foreword', 'xi'), -('Introduction', 'xiv'), -('1. Scope', '1'), -('2. Normative references', '2'), -('3. Terms, definitions, and symbols', '3'), -('4. Conformance', '7'), -('5. Environment', '9'), -('5.1 Conceptual models', '9'), -('5.1.1 Translation environment', '9'), -('5.1.2 Execution environments', '11'), -('5.2 Environmental considerations', '17'), -('5.2.1 Character sets', '17'), -('5.2.2 Character display semantics', '19'), -('5.2.3 Signals and interrupts', '20'), -('5.2.4 Environmental limits', '20'), -('6. Language', '29'), -('6.1 Notation', '29'), -('6.2 Concepts', '29'), -('6.2.1 Scopes of identifiers', '29'), -('6.2.2 Linkages of identifiers', '30'), -('6.2.3 Name spaces of identifiers', '31'), -('6.2.4 Storage durations of objects', '32'), -('6.2.5 Types', '33'), -('6.2.6 Representations of types', '37'), -('6.2.7 Compatible type and composite type', '40'), -('6.3 Conversions', '42'), -('6.3.1 Arithmetic operands', '42'), -('6.3.2 Other operands', '46'), -('6.4 Lexical elements', '49'), -('6.4.1 Keywords', '50'), -('6.4.2 Identifiers', '51'), -('6.4.3 Universal character names', '53'), -('6.4.4 Constants', '54'), -('6.4.5 String literals', '62'), -('6.4.6 Punctuators', '63'), -('6.4.7 Header names', '64'), -('6.4.8 Preprocessing numbers', '65'), -('6.4.9 Comments', '66'), -('6.5 Expressions', '67'), -('6.5.1 Primary expressions', '69'), -('6.5.2 Postfix operators', '69'), -('6.5.3 Unary operators', '78'), -('6.5.4 Cast operators', '81'), -('6.5.5 Multiplicative operators', '82'), -('6.5.6 Additive operators', '82'), -('6.5.7 Bitwise shift operators', '84'), -('6.5.8 Relational operators', '85'), -('6.5.9 Equality operators', '86'), -('6.5.10 Bitwise AND operator', '87'), -('6.5.11 Bitwise exclusive OR operator', '88'), -('6.5.12 Bitwise inclusive OR operator', '88'), -('6.5.13 Logical AND operator', '89'), -('6.5.14 Logical OR operator', '89'), -('6.5.15 Conditional operator', '90'), -('6.5.16 Assignment operators', '91'), -('6.5.17 Comma operator', '94'), -('6.6 Constant expressions', '95'), -('6.7 Declarations', '97'), -('6.7.1 Storage-class specifiers', '98'), -('6.7.2 Type specifiers', '99'), -('6.7.3 Type qualifiers', '108'), -('6.7.4 Function specifiers', '112'), -('6.7.5 Declarators', '114'), -('6.7.6 Type names', '122'), -('6.7.7 Type definitions', '123'), -('6.7.8 Initialization', '125'), -('6.8 Statements and blocks', '131'), -('6.8.1 Labeled statements', '131'), -('6.8.2 Compound statement', '132'), -('6.8.3 Expression and null statements', '132'), -('6.8.4 Selection statements', '133'), -('6.8.5 Iteration statements', '135'), -('6.8.6 Jump statements', '136'), -('6.9 External definitions', '140'), -('6.9.1 Function definitions', '141'), -('6.9.2 External object definitions', '143'), -('6.10 Preprocessing directives', '145'), -('6.10.1 Conditional inclusion', '147'), -('6.10.2 Source file inclusion', '149'), -('6.10.3 Macro replacement', '151'), -('6.10.4 Line control', '158'), -('6.10.5 Error directive', '159'), -('6.10.6 Pragma directive', '159'), -('6.10.7 Null directive', '160'), -('6.10.8 Predefined macro names', '160'), -('6.10.9 Pragma operator', '161'), -('6.11 Future language directions', '163'), -('6.11.1 Floating types', '163'), -('6.11.2 Linkages of identifiers', '163'), -('6.11.3 External names', '163'), -('6.11.4 Character escape sequences', '163'), -('6.11.5 Storage-class specifiers', '163'), -('6.11.6 Function declarators', '163'), -('6.11.7 Function definitions', '163'), -('6.11.8 Pragma directives', '163'), -('6.11.9 Predefined macro names', '163'), -('7. Library', '164'), -('7.1 Introduction', '164'), -('7.1.1 Definitions of terms', '164'), -('7.1.2 Standard headers', '165'), -('7.1.3 Reserved identifiers', '166'), -('7.1.4 Use of library functions', '166'), -('7.2 Diagnostics <assert.h>', '169'), -('7.2.1 Program diagnostics', '169'), -('7.3 Complex arithmetic <complex.h>', '170'), -('7.3.1 Introduction', '170'), -('7.3.2 Conventions', '170'), -('7.3.3 Branch cuts', '171'), -('7.3.4 The CX_LIMITED_RANGE pragma', '171'), -('7.3.5 Trigonometric functions', '172'), -('7.3.6 Hyperbolic functions', '174'), -('7.3.7 Exponential and logarithmic functions', '176'), -('7.3.8 Power and absolute-value functions', '177'), -('7.3.9 Manipulation functions', '178'), -('7.4 Character handling <ctype.h>', '181'), -('7.4.1 Character classification functions', '181'), -('7.4.2 Character case mapping functions', '184'), -('7.5 Errors <errno.h>', '186'), -('7.6 Floating-point environment <fenv.h>', '187'), -('7.6.1 The FENV_ACCESS pragma', '189'), -('7.6.2 Floating-point exceptions', '190'), -('7.6.3 Rounding', '193'), -('7.6.4 Environment', '194'), -('7.7 Characteristics of floating types <float.h>', '197'), -('7.8 Format conversion of integer types <inttypes.h>', '198'), -('7.8.1 Macros for format specifiers', '198'), -('7.8.2 Functions for greatest-width integer types', '199'), -('7.9 Alternative spellings <iso646.h>', '202'), -('7.10 Sizes of integer types <limits.h>', '203'), -('7.11 Localization <locale.h>', '204'), -('7.11.1 Locale control', '205'), -('7.11.2 Numeric formatting convention inquiry', '206'), -('7.12 Mathematics <math.h>', '212'), -('7.12.1 Treatment of error conditions', '214'), -('7.12.2 The FP_CONTRACT pragma', '215'), -('7.12.3 Classification macros', '216'), -('7.12.4 Trigonometric functions', '218'), -('7.12.5 Hyperbolic functions', '221'), -('7.12.6 Exponential and logarithmic functions', '223'), -('7.12.7 Power and absolute-value functions', '228'), -('7.12.8 Error and gamma functions', '230'), -('7.12.9 Nearest integer functions', '231'), -('7.12.10 Remainder functions', '235'), -('7.12.11 Manipulation functions', '236'), -('7.12.12 Maximum, minimum, and positive difference functions', '238'), -('7.12.13 Floating multiply-add', '239'), -('7.12.14 Comparison macros', '240'), -('7.13 Nonlocal jumps <setjmp.h>', '243'), -('7.13.1 Save calling environment', '243'), -('7.13.2 Restore calling environment', '244'), -('7.14 Signal handling <signal.h>', '246'), -('7.14.1 Specify signal handling', '247'), -('7.14.2 Send signal', '248'), -('7.15 Variable arguments <stdarg.h>', '249'), -('7.15.1 Variable argument list access macros', '249'), -('7.16 Boolean type and values <stdbool.h>', '253'), -('7.17 Common definitions <stddef.h>', '254'), -('7.18 Integer types <stdint.h>', '255'), -('7.18.1 Integer types', '255'), -('7.18.2 Limits of specified-width integer types', '257'), -('7.18.3 Limits of other integer types', '259'), -('7.18.4 Macros for integer constants', '260'), -('7.19 Input/output <stdio.h>', '262'), -('7.19.1 Introduction', '262'), -('7.19.2 Streams', '264'), -('7.19.3 Files', '266'), -('7.19.4 Operations on files', '268'), -('7.19.5 File access functions', '270'), -('7.19.6 Formatted input/output functions', '274'), -('7.19.7 Character input/output functions', '296'), -('7.19.8 Direct input/output functions', '301'), -('7.19.9 File positioning functions', '302'), -('7.19.10 Error-handling functions', '304'), -('7.20 General utilities <stdlib.h>', '306'), -('7.20.1 Numeric conversion functions', '307'), -('7.20.2 Pseudo-random sequence generation functions', '312'), -('7.20.3 Memory management functions', '313'), -('7.20.4 Communication with the environment', '315'), -('7.20.5 Searching and sorting utilities', '318'), -('7.20.6 Integer arithmetic functions', '320'), -('7.20.7 Multibyte/wide character conversion functions', '321'), -('7.20.8 Multibyte/wide string conversion functions', '323'), -('7.21 String handling <string.h>', '325'), -('7.21.1 String function conventions', '325'), -('7.21.2 Copying functions', '325'), -('7.21.3 Concatenation functions', '327'), -('7.21.4 Comparison functions', '328'), -('7.21.5 Search functions', '330'), -('7.21.6 Miscellaneous functions', '333'), -('7.22 Type-generic math <tgmath.h>', '335'), -('7.23 Date and time <time.h>', '338'), -('7.23.1 Components of time', '338'), -('7.23.2 Time manipulation functions', '339'), -('7.23.3 Time conversion functions', '341'), -('7.24 Extended multibyte and wide character utilities <wchar.h>', '348'), -('7.24.1 Introduction', '348'), -('7.24.2 Formatted wide character input/output functions', '349'), -('7.24.3 Wide character input/output functions', '367'), -('7.24.4 General wide string utilities', '371'), -('7.24.5 Wide character time conversion functions', '385'), -('7.24.6 Extended multibyte/wide character conversion utilities', '386'), -('7.25 Wide character classification and mapping utilities <wctype.h>', - '393'), -('7.25.1 Introduction', '393'), -('7.25.2 Wide character classification utilities', '394'), -('7.25.3 Wide character case mapping utilities', '399'), -('7.26 Future library directions', '401'), -('7.26.1 Complex arithmetic <complex.h>', '401'), -('7.26.2 Character handling <ctype.h>', '401'), -('7.26.3 Errors <errno.h>', '401'), -('7.26.4 Format conversion of integer types <inttypes.h>', '401'), -('7.26.5 Localization <locale.h>', '401'), -('7.26.6 Signal handling <signal.h>', '401'), -('7.26.7 Boolean type and values <stdbool.h>', '401'), -('7.26.8 Integer types <stdint.h>', '401'), -('7.26.9 Input/output <stdio.h>', '402'), -('7.26.10 General utilities <stdlib.h>', '402'), -('7.26.11 String handling <string.h>', '402'), -('<wchar.h>', '402'), -('<wctype.h>', '402'), -('Annex A (informative) Language syntax summary', '403'), -('A.1 Lexical grammar', '403'), -('A.2 Phrase structure grammar', '409'), -('A.3 Preprocessing directives', '416'), -('Annex B (informative) Library summary', '418'), -('B.1 Diagnostics <assert.h>', '418'), -('B.2 Complex <complex.h>', '418'), -('B.3 Character handling <ctype.h>', '420'), -('B.4 Errors <errno.h>', '420'), -('B.5 Floating-point environment <fenv.h>', '420'), -('B.6 Characteristics of floating types <float.h>', '421'), -('B.7 Format conversion of integer types <inttypes.h>', '421'), -('B.8 Alternative spellings <iso646.h>', '422'), -('B.9 Sizes of integer types <limits.h>', '422'), -('B.10 Localization <locale.h>', '422'), -('B.11 Mathematics <math.h>', '422'), -('B.12 Nonlocal jumps <setjmp.h>', '427'), -('B.13 Signal handling <signal.h>', '427'), -('B.14 Variable arguments <stdarg.h>', '427'), -('B.15 Boolean type and values <stdbool.h>', '427'), -('B.16 Common definitions <stddef.h>', '428'), -('B.17 Integer types <stdint.h>', '428'), -('B.18 Input/output <stdio.h>', '428'), -('B.19 General utilities <stdlib.h>', '430'), -('B.20 String handling <string.h>', '432'), -('B.21 Type-generic math <tgmath.h>', '433'), -('B.22 Date and time <time.h>', '433'), -('B.23 Extended multibyte/wide character utilities <wchar.h>', '434'), -('B.24 Wide character classification and mapping utilities <wctype.h>', - '436'), -('Annex C (informative) Sequence points', '438'), -('Annex D (normative) Universal character names for identifiers', '439'), -('Annex E (informative) Implementation limits', '441'), -('Annex F (normative) IEC 60559 floating-point arithmetic', '443'), -('F.1 Introduction', '443'), -('F.2 Types', '443'), -('F.3 Operators and functions', '444'), -('F.4 Floating to integer conversion', '446'), -('F.5 Binary-decimal conversion', '446'), -('F.6 Contracted expressions', '447'), -('F.7 Floating-point environment', '447'), -('F.8 Optimization', '450'), -('F.9 Mathematics <math.h>', '453'), -('Annex G (informative) IEC 60559-compatible complex arithmetic', '466'), -('G.1 Introduction', '466'), -('G.2 Types', '466'), -('G.3 Conventions', '466'), -('G.4 Conversions', '467'), -('G.5 Binary operators', '467'), -('G.6 Complex arithmetic <complex.h>', '471'), -('G.7 Type-generic math <tgmath.h>', '479'), -('Annex H (informative) Language independent arithmetic', '480'), -('H.1 Introduction', '480'), -('H.2 Types', '480'), -('H.3 Notification', '484'), -('Annex I (informative) Common warnings', '486'), -('Annex J (informative) Portability issues', '488'), -('J.1 Unspecified behavior', '488'), -('J.2 Undefined behavior', '491'), -('J.3 Implementation-defined behavior', '504'), -('J.4 Locale-specific behavior', '511'), -('J.5 Common extensions', '512'), -('Bibliography', '515'), -('Index', '517')] - -cXXURL = 'http://open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2723.pdf' -cXXTOC = [('Contents', 'ii'), -('List of Tables', 'ix'), -('1 General', '1'), -('1.1 Scope', '1'), -('1.2 Normative references', '1'), -('1.3 Definitions', '2'), -('1.4 Implementation compliance', '4'), -('1.5 Structure of this International Standard', '5'), -('1.6 Syntax notation', '5'), -('1.7 The C++ memory model', '6'), -('1.8 The C++ object model', '6'), -('1.9 Program execution', '7'), -('1.10 Multi-threaded executions and data races', '10'), -('1.11 Acknowledgments', '13'), -('2 Lexical conventions', '15'), -('2.1 Phases of translation', '15'), -('2.2 Character sets', '16'), -('2.3 Trigraph sequences', '17'), -('2.4 Preprocessing tokens', '17'), -('2.5 Alternative tokens', '18'), -('2.6 Tokens', '19'), -('2.7 Comments', '19'), -('2.8 Header names', '19'), -('2.9 Preprocessing numbers', '20'), -('2.10 Identifiers', '20'), -('2.11 Keywords', '20'), -('2.12 Operators and punctuators', '21'), -('2.13 Literals', '21'), -('3 Basic concepts', '29'), -('3.1 Declarations and definitions', '29'), -('3.2 One definition rule', '31'), -('3.3 Declarative regions and scopes', '33'), -('3.4 Name lookup', '38'), -('3.5 Program and linkage', '51'), -('3.6 Start and termination', '54'), -('3.7 Storage duration', '58'), -('3.8 Object Lifetime', '62'), -('3.9 Types', '65'), -('3.10 Lvalues and rvalues', '70'), -('3.11 Alignment', '72'), -('4 Standard conversions', '73'), -('4.1 Lvalue-to-rvalue conversion', '74'), -('4.2 Array-to-pointer conversion', '74'), -('4.3 Function-to-pointer conversion', '74'), -('4.4 Qualification conversions', '74'), -('4.5 Integral promotions', '75'), -('4.6 Floating point promotion', '76'), -('4.7 Integral conversions', '76'), -('4.8 Floating point conversions', '76'), -('4.9 Floating-integral conversions', '77'), -('4.10 Pointer conversions', '77'), -('4.11 Pointer to member conversions', '77'), -('4.12 Boolean conversions', '78'), -('4.13 Integer conversion rank', '78'), -('5 Expressions', '79'), -('5.1 Primary expressions', '80'), -('5.2 Postfix expressions', '85'), -('5.3 Unary expressions', '96'), -('5.4 Explicit type conversion (cast notation)', '104'), -('5.5 Pointer-to-member operators', '105'), -('5.6 Multiplicative operators', '106'), -('5.7 Additive operators', '106'), -('5.8 Shift operators', '107'), -('5.9 Relational operators', '108'), -('5.10 Equality operators', '109'), -('5.11 Bitwise AND operator', '110'), -('5.12 Bitwise exclusive OR operator', '110'), -('5.13 Bitwise inclusive OR operator', '110'), -('5.14 Logical AND operator', '110'), -('5.15 Logical OR operator', '110'), -('5.16 Conditional operator', '111'), -('5.17 Assignment and compound assignment operators', '112'), -('5.18 Comma operator', '113'), -('5.19 Constant expressions', '113'), -('6 Statements', '116'), -('6.1 Labeled statement', '116'), -('6.2 Expression statement', '116'), -('6.3 Compound statement or block', '116'), -('6.4 Selection statements', '117'), -('6.5 Iteration statements', '118'), -('6.6 Jump statements', '121'), -('6.7 Declaration statement', '122'), -('6.8 Ambiguity resolution', '123'), -('7 Declarations', '125'), -('7.1 Specifiers', '126'), -('7.2 Enumeration declarations', '140'), -('7.3 Namespaces', '143'), -('7.4 The asm declaration', '156'), -('7.5 Linkage specifications', '156'), -('8 Declarators', '160'), -('8.1 Type names', '161'), -('8.2 Ambiguity resolution', '161'), -('8.3 Meaning of declarators', '163'), -('8.4 Function definitions', '175'), -('8.5 Initializers', '177'), -('9 Classes', '191'), -('9.1 Class names', '193'), -('9.2 Class members', '194'), -('9.3 Member functions', '197'), -('9.4 Static members', '200'), -('9.5 Unions', '202'), -('9.6 Bit-fields', '203'), -('9.7 Nested class declarations', '204'), -('9.8 Local class declarations', '205'), -('9.9 Nested type names', '206'), -('10 Derived classes', '207'), -('10.1 Multiple base classes', '208'), -('10.2 Member name lookup', '210'), -('10.3 Virtual functions', '213'), -('10.4 Abstract classes', '217'), -('11 Member access control', '219'), -('11.1 Access specifiers', '221'), -('11.2 Accessibility of base classes and base class members', '222'), -('11.3 Access declarations', '224'), -('11.4 Friends', '225'), -('11.5 Protected member access', '228'), -('11.6 Access to virtual functions', '229'), -('11.7 Multiple access', '230'), -('11.8 Nested classes', '230'), -('12 Special member functions', '231'), -('12.1 Constructors', '231'), -('12.2 Temporary objects', '233'), -('12.3 Conversions', '235'), -('12.4 Destructors', '238'), -('12.5 Free store', '240'), -('12.6 Initialization', '242'), -('12.7 Construction and destruction', '247'), -('12.8 Copying class objects', '250'), -('12.9 Inheriting Constructors', '255'), -('13 Overloading', '259'), -('13.1 Overloadable declarations', '259'), -('13.2 Declaration matching', '261'), -('13.3 Overload resolution', '262'), -('13.4 Address of overloaded function', '281'), -('13.5 Overloaded operators', '282'), -('13.6 Built-in operators', '286'), -('14 Templates', '290'), -('14.1 Template parameters', '291'), -('14.2 Names of template specializations', '294'), -('14.3 Template arguments', '296'), -('14.4 Type equivalence', '302'), -('14.5 Template declarations', '303'), -('14.6 Name resolution', '318'), -('14.7 Template instantiation and specialization', '331'), -('14.8 Function template specializations', '343'), -('15 Exception handling', '363'), -('15.1 Throwing an exception', '364'), -('15.2 Constructors and destructors', '366'), -('15.3 Handling an exception', '366'), -('15.4 Exception specifications', '368'), -('15.5 Special functions', '371'), -('15.6 Exceptions and access', '372'), -('16 Preprocessing directives', '373'), -('16.1 Conditional inclusion', '375'), -('16.2 Source file inclusion', '376'), -('16.3 Macro replacement', '377'), -('16.4 Line control', '382'), -('16.5 Error directive', '383'), -('16.6 Pragma directive', '383'), -('16.7 Null directive', '383'), -('16.8 Predefined macro names', '383'), -('16.9 Pragma operator', '384'), -('17 Library introduction', '386'), -('17.1 General', '386'), -('17.2 Overview', '386'), -('17.3 Definitions', '386'), -('17.4 Additional definitions', '390'), -('17.5 Method of description (Informative)', '390'), -('17.6 Library-wide requirements', '396'), -('18 Language support library', '407'), -('18.1 Types', '407'), -('18.2 Implementation properties', '408'), -('18.3 Integer types', '417'), -('18.4 Start and termination', '418'), -('18.5 Dynamic memory management', '420'), -('18.6 Type identification', '424'), -('18.7 Exception handling', '427'), -('18.8 Initializer lists', '432'), -('18.9 Other runtime support', '434'), -('19 Diagnostics library', '435'), -('19.1 Exception classes', '435'), -('19.2 Assertions', '439'), -('19.3 Error numbers', '440'), -('19.4 System error support', '440'), -('20 General utilities library', '452'), -('20.1 Requirements', '452'), -('20.2 Utility components', '457'), -('20.3 Compile-time rational arithmetic', '463'), -('20.4 Tuples', '465'), -('20.5 Metaprogramming and type traits', '473'), -('20.6 Function objects', '486'), -('20.7 Memory', '509'), -('20.8 Time utilities', '548'), -('20.9 Date and time functions', '562'), -('21 Strings library', '563'), -('21.1 Character traits', '563'), -('21.2 String classes', '569'), -('21.3 Class template basic_string', '572'), -('21.4 Numeric Conversions', '599'), -('21.5 Null-terminated sequence utilities', '600'), -('22 Localization library', '604'), -('22.1 Locales', '604'), -('22.2 Standard locale categories', '617'), -('22.3 Standard code conversion facets', '657'), -('22.4 C Library Locales', '659'), -('23 Containers library', '660'), -('23.1 Container requirements', '660'), -('23.2 Sequence containers', '681'), -('23.3 Associative containers', '719'), -('23.4 Unordered associative containers', '744'), -('24 Iterators library', '759'), -('24.1 Iterator requirements', '759'), -('24.2 Header <iterator> synopsis', '764'), -('24.3 Iterator primitives', '767'), -('24.4 Predefined iterators', '770'), -('24.5 Stream iterators', '784'), -('25 Algorithms library', '792'), -('25.1 Non-modifying sequence operations', '802'), -('25.2 Mutating sequence operations', '806'), -('25.3 Sorting and related operations', '815'), -('25.4 C library algorithms', '829'), -('26 Numerics library', '831'), -('26.1 Numeric type requirements', '831'), -('26.2 The floating-point environment', '832'), -('26.3 Complex numbers', '833'), -('26.4 Random number generation', '842'), -('26.5 Numeric arrays', '884'), -('26.6 Generalized numeric operations', '904'), -('26.7 C Library', '907'), -('27 Input/output library', '912'), -('27.1 Iostreams requirements', '912'), -('27.2 Forward declarations', '912'), -('27.3 Standard iostream objects', '915'), -('27.4 Iostreams base classes', '916'), -('27.5 Stream buffers', '934'), -('27.6 Formatting and manipulators', '944'), -('27.7 String-based streams', '972'), -('27.8 File-based streams', '984'), -('28 Regular expressions library', '1000'), -('28.1 Definitions', '1000'), -('28.2 Requirements', '1000'), -('28.3 Regular expressions summary', '1002'), -('28.4 Header <regex> synopsis', '1003'), -('28.5 Namespace std::regex_constants', '1009'), -('28.6 Class regex_error', '1012'), -('28.7 Class template regex_traits', '1012'), -('28.8 Class template basic_regex', '1015'), -('28.9 Class template sub_match', '1020'), -('28.10Class template match_results', '1025'), -('28.11Regular expression algorithms', '1029'), -('28.12Regular expression Iterators', '1033'), -('28.13Modified ECMAScript regular expression grammar', '1039'), -('29 Atomic operations library', '1042'), -('29.1 Order and Consistency', '1044'), -('29.2 Lock-free Property', '1046'), -('29.3 Atomic Types', '1046'), -('29.4 Operations on Atomic Types', '1051'), -('29.5 Flag Type and Operations', '1054'), -('30 Thread support library', '1057'), -('30.1 Requirements', '1057'), -('30.2 Threads', '1058'), -('30.3 Mutual exclusion', '1063'), -('30.4 Condition variables', '1077'), -('A Grammar summary', '1085'), -('A.1 Keywords', '1085'), -('A.2 Lexical conventions', '1085'), -('A.3 Basic concepts', '1089'), -('A.4 Expressions', '1090'), -('A.5 Statements', '1093'), -('A.6 Declarations', '1094'), -('A.7 Declarators', '1097'), -('A.8 Classes', '1098'), -('A.9 Derived classes', '1099'), -('A.10 Special member functions', '1099'), -('A.11 Overloading', '1100'), -('A.12 Templates', '1100'), -('A.13 Exception handling', '1101'), -('A.14 Preprocessing directives', '1101'), -('B Implementation quantities', '1103'), -('C Compatibility', '1105'), -('C.1 C++ and ISO C', '1105'), -('C.2 Standard C library', '1114'), -('D Compatibility features', '1119'), -('D.1 Increment operator with bool operand', '1119'), -('D.2 static keyword', '1119'), -('D.3 Access declarations', '1119'), -('D.4 Implicit conversion from const strings', '1119'), -('D.5 C standard library headers', '1119'), -('D.6 Old iostreams members', '1120'), -('D.7 char* streams', '1121'), -('D.8 Binders', '1130'), -('D.9 auto_ptr', '1132'), -('E Universal-character-names', '1135'), -('F Cross references', '1137'), -('Index', '1153')] - -kDocuments = { - 'C99' : (c99URL, c99TOC, 12), - 'C++' : (cXXURL, cXXTOC, 12), -} - -def findClosestTOCEntry(data, target): - # FIXME: Fix for named spec references - if isinstance(target[0],str): - return ('.'.join(target),'<named>',1) - - offset = data[2] - best = None - for (name,page) in data[1]: - if ' ' in name: - section,name = name.split(' ',1) - if section == 'Annex': - section,name = name.split(' ',1) - section = 'Annex '+section - else: - section = None - try: - page = int(page) + offset - except: - page = 1 - try: - spec = SpecIndex.fromstring(section) - except: - spec = None - - # Meh, could be better... - if spec is not None: - dist = spec - target - if best is None or dist < best[0]: - best = (dist, (section, name, page)) - return best[1] - -# What a hack. Slow to boot. -doxyLineRefRE = re.compile(r"<a name=\"l([0-9]+)\"></a>") -def findClosestLineReference(clangRoot, doxyName, target): - try: - f = open(os.path.join(clangRoot, 'docs', 'doxygen', 'html', doxyName)) - except: - return None - - best = None - for m in doxyLineRefRE.finditer(f.read()): - line = int(m.group(1), 10) - dist = abs(line - target) - if best is None or dist < best[0]: - best = (dist,'l'+m.group(1)) - f.close() - if best is not None: - return best[1] - return None - -### - -nameAndSpecRefRE = re.compile(r"(C99|C90|C\+\+|H\&S) ((([0-9]+)(\.[0-9]+)*|\[[^]]+\])(p[0-9]+)?)") -loneSpecRefRE = re.compile(r" (([0-9]+)(\.[0-9]+){2,100}(p[0-9]+)?)") -def scanFile(path, filename): - try: - f = open(path) - except IOError: - print >>sys.stderr,'WARNING: Unable to open:',path - return - - for i,ln in enumerate(f): - ignore = set() - for m in nameAndSpecRefRE.finditer(ln): - section = m.group(2) - name = m.group(1) - if section.endswith('.'): - section = section[:-1] - yield RefItem(name, section, filename, path, i+1) - ignore.add(section) - for m in loneSpecRefRE.finditer(ln): - section = m.group(1) - if section.endswith('.'): - section = section[:-1] - if section not in ignore: - yield RefItem(None, section, filename, path, i+1) - -### - -class SpecIndex: - @staticmethod - def fromstring(str): - # Check for named sections - if str[0] == '[': - assert ']' in str - secs = str[1:str.index(']')].split('.') - tail = str[str.index(']')+1:] - if tail: - assert tail[0] == 'p' - paragraph = int(tail[1:]) - else: - paragraph = None - indices = secs - else: - secs = str.split('.') - paragraph = None - if 'p' in secs[-1]: - secs[-1],p = secs[-1].split('p',1) - paragraph = int(p) - indices = map(int, secs) - return SpecIndex(indices, paragraph) - - def __init__(self, indices, paragraph=None): - assert len(indices)>0 - self.indices = tuple(indices) - self.paragraph = paragraph - - def __str__(self): - s = '.'.join(map(str,self.indices)) - if self.paragraph is not None: - s += '.p%d'%(self.paragraph,) - return s - - def __repr__(self): - return 'SpecIndex(%s, %s)'%(self.indices, self.paragraph) - - def __cmp__(self, b): - return cmp((self.indices,self.paragraph), - (b.indices,b.paragraph)) - - def __hash__(self): - return hash((self.indices,self.paragraph)) - - def __sub__(self, indices): - def sub(a,b): - a = a or 0 - b = b or 0 - return abs(a-b) - return map(sub,self.indices,indices) - -class RefItem: - def __init__(self, name, section, filename, path, line): - self.name = name - self.section = SpecIndex.fromstring(section) - self.filename = filename - self.path = path - self.line = line - - def __str__(self): - if self.name is not None: - return '%s %s'%(self.name, self.section) - else: - return '--- %s'%(self.section,) - - def __repr__(self): - return 'RefItem(%s, %r, "%s", "%s", %d)'%(self.name, - self.section, - self.filename, - self.path, - self.line) - - def __cmp__(self, b): - return cmp((self.name,self.section,self.filename,self.path,self.line), - (b.name,b.section,self.filename,self.path,self.line)) - - def __hash__(self): - return hash((self.name,self.section,self.filename,self.path,self.line)) - -### - -def sorted(l): - l = list(l) - l.sort() - return l - -def getRevision(path): - import subprocess - p = subprocess.Popen(['svn', 'info', path], - stdin=open('/dev/null','r'), - stdout=subprocess.PIPE) - for ln in p.stdout.read(1024).split('\n'): - if ln.startswith('Revision:'): - return ln.split(':',1)[1].strip() - return None - -def buildRefTree(references): - root = (None, {}, []) - - def getNode(keys): - if not keys: - return root - key,parent = keys[-1],getNode(keys[:-1]) - node = parent[1].get(key) - if node is None: - parent[1][key] = node = (key, {}, []) - return node - - for ref in references: - n = getNode((ref.name,) + ref.section.indices) - n[2].append(ref) - - def flatten((key, children, data)): - children = sorted(map(flatten,children.values())) - return (key, children, sorted(data)) - - return flatten(root) - -def preorder(node,parents=(),first=True): - (key,children,data) = node - if first: - yield parents+(node,) - for c in children: - for item in preorder(c, parents+(node,)): - yield item - -def main(): - global options - from optparse import OptionParser - parser = OptionParser("usage: %prog [options] CLANG_ROOT <output-dir>") - parser.add_option("", "--debug", dest="debug", - help="Print extra debugging output", - action="store_true", - default=False) - (opts, args) = parser.parse_args() - - if len(args) != 2: - parser.error("incorrect number of arguments") - - references = [] - root,outputDir = args - if os.path.isdir(root): - for (dirpath, dirnames, filenames) in os.walk(root): - for filename in filenames: - name,ext = os.path.splitext(filename) - if ext in ('.c', '.cpp', '.h', '.def'): - fullpath = os.path.join(dirpath, filename) - references.extend(list(scanFile(fullpath, filename))) - else: - references.extend(list(scanFile(root, root))) - - refTree = buildRefTree(references) - - specs = {} - for ref in references: - spec = specs[ref.name] = specs.get(ref.name,{}) - items = spec[ref.section] = spec.get(ref.section,[]) - items.append(ref) - - print 'Found %d references.'%(len(references),) - - if opts.debug: - pprint(refTree) - - referencesPath = os.path.join(outputDir,'references.html') - print 'Writing: %s'%(referencesPath,) - f = open(referencesPath,'w') - print >>f, '<html><head><title>clang: Specification References</title></head>' - print >>f, '<body>' - print >>f, '\t<h2>Specification References</h2>' - for i,node in enumerate(refTree[1]): - specName = node[0] or 'Unknown' - print >>f, '<a href="#spec%d">%s</a><br>'%(i,specName) - for i,node in enumerate(refTree[1]): - specName = node[0] or 'Unknown' - print >>f, '<hr>' - print >>f, '<a name="spec%d">'%(i,) - print >>f, '<h3>Document: %s</h3>'%(specName or 'Unknown',) - print >>f, '<table border="1" cellspacing="2" width="80%">' - print >>f, '<tr><th width="20%">Name</th><th>References</th></tr>' - docData = kDocuments.get(specName) - for path in preorder(node,first=False): - if not path[-1][2]: - continue - components = '.'.join([str(p[0]) for p in path[1:]]) - print >>f, '\t<tr>' - tocEntry = None - if docData is not None: - tocEntry = findClosestTOCEntry(docData, [p[0] for p in path[1:]]) - if tocEntry is not None: - section,name,page = tocEntry - # If section is exact print the TOC name - if page is not None: - linkStr = '<a href="%s#page=%d">%s</a> (pg.%d)'%(docData[0],page,components,page) - else: - linkStr = components - if section == components: - print >>f, '\t\t<td valign=top>%s<br>%s</td>'%(linkStr,name) - else: - print >>f, '\t\t<td valign=top>%s</td>'%(linkStr,) - else: - print >>f, '\t\t<td valign=top>%s</td>'%(components,) - print >>f, '\t\t<td valign=top>' - for item in path[-1][2]: - # XXX total hack - relativePath = item.path[len(root):] - if relativePath.startswith('/'): - relativePath = relativePath[1:] - # XXX this is broken, how does doxygen mangle w/ multiple - # refs? Can we just read its map? - filename = os.path.basename(relativePath) - doxyName = '%s-source.html'%(filename.replace('.','_8'),) - # Grrr, why can't doxygen write line number references. - lineReference = findClosestLineReference(root,doxyName,item.line) - if lineReference is not None: - linkStr = 'http://clang.llvm.org/doxygen/%s#%s'%(doxyName,lineReference) - else: - linkStr = 'http://clang.llvm.org/doxygen/%s'%(doxyName,) - if item.section.paragraph is not None: - paraText = ' (p%d)'%(item.section.paragraph,) - else: - paraText = '' - print >>f,'<a href="%s">%s:%d</a>%s<br>'%(linkStr,relativePath,item.line,paraText) - print >>f, '\t\t</td>' - print >>f, '\t</tr>' - print >>f, '</table>' - print >>f, '<hr>' - print >>f, 'Generated: %s<br>'%(time.strftime('%Y-%m-%d %H:%M'),) - print >>f, 'SVN Revision: %s'%(getRevision(root),) - print >>f, '</body>' - f.close() - -if __name__=='__main__': - main() diff --git a/contrib/llvm/tools/clang/utils/FuzzTest b/contrib/llvm/tools/clang/utils/FuzzTest deleted file mode 100755 index 2aa5989..0000000 --- a/contrib/llvm/tools/clang/utils/FuzzTest +++ /dev/null @@ -1,340 +0,0 @@ -#!/usr/bin/env python - -""" -This is a generic fuzz testing tool, see --help for more information. -""" - -import os -import sys -import random -import subprocess -import itertools - -class TestGenerator: - def __init__(self, inputs, delete, insert, replace, - insert_strings, pick_input): - self.inputs = [(s, open(s).read()) for s in inputs] - - self.delete = bool(delete) - self.insert = bool(insert) - self.replace = bool(replace) - self.pick_input = bool(pick_input) - self.insert_strings = list(insert_strings) - - self.num_positions = sum([len(d) for _,d in self.inputs]) - self.num_insert_strings = len(insert_strings) - self.num_tests = ((delete + (insert + replace)*self.num_insert_strings) - * self.num_positions) - self.num_tests += 1 - - if self.pick_input: - self.num_tests *= self.num_positions - - def position_to_source_index(self, position): - for i,(s,d) in enumerate(self.inputs): - n = len(d) - if position < n: - return (i,position) - position -= n - raise ValueError,'Invalid position.' - - def get_test(self, index): - assert 0 <= index < self.num_tests - - picked_position = None - if self.pick_input: - index,picked_position = divmod(index, self.num_positions) - picked_position = self.position_to_source_index(picked_position) - - if index == 0: - return ('nothing', None, None, picked_position) - - index -= 1 - index,position = divmod(index, self.num_positions) - position = self.position_to_source_index(position) - if self.delete: - if index == 0: - return ('delete', position, None, picked_position) - index -= 1 - - index,insert_index = divmod(index, self.num_insert_strings) - insert_str = self.insert_strings[insert_index] - if self.insert: - if index == 0: - return ('insert', position, insert_str, picked_position) - index -= 1 - - assert self.replace - assert index == 0 - return ('replace', position, insert_str, picked_position) - -class TestApplication: - def __init__(self, tg, test): - self.tg = tg - self.test = test - - def apply(self): - if self.test[0] == 'nothing': - pass - else: - i,j = self.test[1] - name,data = self.tg.inputs[i] - if self.test[0] == 'delete': - data = data[:j] + data[j+1:] - elif self.test[0] == 'insert': - data = data[:j] + self.test[2] + data[j:] - elif self.test[0] == 'replace': - data = data[:j] + self.test[2] + data[j+1:] - else: - raise ValueError,'Invalid test %r' % self.test - open(name,'wb').write(data) - - def revert(self): - if self.test[0] != 'nothing': - i,j = self.test[1] - name,data = self.tg.inputs[i] - open(name,'wb').write(data) - -def quote(str): - return '"' + str + '"' - -def run_one_test(test_application, index, input_files, args): - test = test_application.test - - # Interpolate arguments. - options = { 'index' : index, - 'inputs' : ' '.join(quote(f) for f in input_files) } - - # Add picked input interpolation arguments, if used. - if test[3] is not None: - pos = test[3][1] - options['picked_input'] = input_files[test[3][0]] - options['picked_input_pos'] = pos - # Compute the line and column. - file_data = test_application.tg.inputs[test[3][0]][1] - line = column = 1 - for i in range(pos): - c = file_data[i] - if c == '\n': - line += 1 - column = 1 - else: - column += 1 - options['picked_input_line'] = line - options['picked_input_col'] = column - - test_args = [a % options for a in args] - if opts.verbose: - print '%s: note: executing %r' % (sys.argv[0], test_args) - - stdout = None - stderr = None - if opts.log_dir: - stdout_log_path = os.path.join(opts.log_dir, '%s.out' % index) - stderr_log_path = os.path.join(opts.log_dir, '%s.err' % index) - stdout = open(stdout_log_path, 'wb') - stderr = open(stderr_log_path, 'wb') - else: - sys.stdout.flush() - p = subprocess.Popen(test_args, stdout=stdout, stderr=stderr) - p.communicate() - exit_code = p.wait() - - test_result = (exit_code == opts.expected_exit_code or - exit_code in opts.extra_exit_codes) - - if stdout is not None: - stdout.close() - stderr.close() - - # Remove the logs for passes, unless logging all results. - if not opts.log_all and test_result: - os.remove(stdout_log_path) - os.remove(stderr_log_path) - - if not test_result: - print 'FAIL: %d' % index - elif not opts.succinct: - print 'PASS: %d' % index - -def main(): - global opts - from optparse import OptionParser, OptionGroup - parser = OptionParser("""%prog [options] ... test command args ... - -%prog is a tool for fuzzing inputs and testing them. - -The most basic usage is something like: - - $ %prog --file foo.txt ./test.sh - -which will run a default list of fuzzing strategies on the input. For each -fuzzed input, it will overwrite the input files (in place), run the test script, -then restore the files back to their original contents. - -NOTE: You should make sure you have a backup copy of your inputs, in case -something goes wrong!!! - -You can cause the fuzzing to not restore the original files with -'--no-revert'. Generally this is used with '--test <index>' to run one failing -test and then leave the fuzzed inputs in place to examine the failure. - -For each fuzzed input, %prog will run the test command given on the command -line. Each argument in the command is subject to string interpolation before -being executed. The syntax is "%(VARIABLE)FORMAT" where FORMAT is a standard -printf format, and VARIBLE is one of: - - 'index' - the test index being run - 'inputs' - the full list of test inputs - 'picked_input' - (with --pick-input) the selected input file - 'picked_input_pos' - (with --pick-input) the selected input position - 'picked_input_line' - (with --pick-input) the selected input line - 'picked_input_col' - (with --pick-input) the selected input column - -By default, the script will run forever continually picking new tests to -run. You can limit the number of tests that are run with '--max-tests <number>', -and you can run a particular test with '--test <index>'. -""") - parser.add_option("-v", "--verbose", help="Show more output", - action='store_true', dest="verbose", default=False) - parser.add_option("-s", "--succinct", help="Reduce amount of output", - action="store_true", dest="succinct", default=False) - - group = OptionGroup(parser, "Test Execution") - group.add_option("", "--expected-exit-code", help="Set expected exit code", - type=int, dest="expected_exit_code", - default=0) - group.add_option("", "--extra-exit-code", - help="Set additional expected exit code", - type=int, action="append", dest="extra_exit_codes", - default=[]) - group.add_option("", "--log-dir", - help="Capture test logs to an output directory", - type=str, dest="log_dir", - default=None) - group.add_option("", "--log-all", - help="Log all outputs (not just failures)", - action="store_true", dest="log_all", default=False) - parser.add_option_group(group) - - group = OptionGroup(parser, "Input Files") - group.add_option("", "--file", metavar="PATH", - help="Add an input file to fuzz", - type=str, action="append", dest="input_files", default=[]) - group.add_option("", "--filelist", metavar="LIST", - help="Add a list of inputs files to fuzz (one per line)", - type=int, action="append", dest="filelists", default=[]) - parser.add_option_group(group) - - group = OptionGroup(parser, "Fuzz Options") - group.add_option("", "--replacement-chars", dest="replacement_chars", - help="Characters to insert/replace", - default="0{}[]<>\;@#$^%& ") - group.add_option("", "--replacement-string", dest="replacement_strings", - action="append", help="Add a replacement string to use", - default=[]) - group.add_option("", "--replacement-list", dest="replacement_lists", - help="Add a list of replacement strings (one per line)", - action="append", default=[]) - group.add_option("", "--no-delete", help="Don't delete characters", - action='store_false', dest="enable_delete", default=True) - group.add_option("", "--no-insert", help="Don't insert strings", - action='store_false', dest="enable_insert", default=True) - group.add_option("", "--no-replace", help="Don't replace strings", - action='store_false', dest="enable_replace", default=True) - group.add_option("", "--no-revert", help="Don't revert changes", - action='store_false', dest="revert", default=True) - parser.add_option_group(group) - - group = OptionGroup(parser, "Test Selection") - group.add_option("", "--test", help="Run a particular test", - type=int, dest="test", default=None, metavar="INDEX") - group.add_option("", "--max-tests", help="Maximum number of tests", - type=int, dest="max_tests", default=10, metavar="COUNT") - group.add_option("", "--pick-input", - help="Randomly select an input byte as well as fuzzing", - action='store_true', dest="pick_input", default=False) - parser.add_option_group(group) - - parser.disable_interspersed_args() - - (opts, args) = parser.parse_args() - - if not args: - parser.error("Invalid number of arguments") - - # Collect the list of inputs. - input_files = list(opts.input_files) - for filelist in opts.filelists: - f = open(filelist) - try: - for ln in f: - ln = ln.strip() - if ln: - input_files.append(ln) - finally: - f.close() - input_files.sort() - - if not input_files: - parser.error("No input files!") - - print '%s: note: fuzzing %d files.' % (sys.argv[0], len(input_files)) - - # Make sure the log directory exists if used. - if opts.log_dir: - if not os.path.exists(opts.log_dir): - try: - os.mkdir(opts.log_dir) - except OSError: - print "%s: error: log directory couldn't be created!" % ( - sys.argv[0],) - raise SystemExit,1 - - # Get the list if insert/replacement strings. - replacements = list(opts.replacement_chars) - replacements.extend(opts.replacement_strings) - for replacement_list in opts.replacement_lists: - f = open(replacement_list) - try: - for ln in f: - ln = ln[:-1] - if ln: - replacements.append(ln) - finally: - f.close() - - # Unique and order the replacement list. - replacements = list(set(replacements)) - replacements.sort() - - # Create the test generator. - tg = TestGenerator(input_files, opts.enable_delete, opts.enable_insert, - opts.enable_replace, replacements, opts.pick_input) - - print '%s: note: %d input bytes.' % (sys.argv[0], tg.num_positions) - print '%s: note: %d total tests.' % (sys.argv[0], tg.num_tests) - if opts.test is not None: - it = [opts.test] - elif opts.max_tests is not None: - it = itertools.imap(random.randrange, - itertools.repeat(tg.num_tests, opts.max_tests)) - else: - it = itertools.imap(random.randrange, itertools.repeat(tg.num_tests)) - for test in it: - t = tg.get_test(test) - - if opts.verbose: - print '%s: note: running test %d: %r' % (sys.argv[0], test, t) - ta = TestApplication(tg, t) - try: - ta.apply() - run_one_test(ta, test, input_files, args) - finally: - if opts.revert: - ta.revert() - - sys.stdout.flush() - -if __name__ == '__main__': - main() diff --git a/contrib/llvm/tools/clang/utils/OptionalTests/Extra/README.txt b/contrib/llvm/tools/clang/utils/OptionalTests/Extra/README.txt deleted file mode 100644 index 565241b..0000000 --- a/contrib/llvm/tools/clang/utils/OptionalTests/Extra/README.txt +++ /dev/null @@ -1,3 +0,0 @@ -This directory is for extra unit style tests following the structure of -clang/tests, but which are not portable or not suitable for inclusion in the -regular test suite. diff --git a/contrib/llvm/tools/clang/utils/OptionalTests/Extra/Runtime/darwin-clang_rt.c b/contrib/llvm/tools/clang/utils/OptionalTests/Extra/Runtime/darwin-clang_rt.c deleted file mode 100644 index d22c0bd..0000000 --- a/contrib/llvm/tools/clang/utils/OptionalTests/Extra/Runtime/darwin-clang_rt.c +++ /dev/null @@ -1,338 +0,0 @@ -/* This file tests that we can succesfully call each compiler-rt function. It is - designed to check that the runtime libraries are available for linking and - that they contain the expected contents. It is not designed to test the - correctness of the individual functions in compiler-rt. - - This test is assumed to be run on a 10.6 machine. The two environment - variables below should be set to 10.4 and 10.5 machines which can be directly - ssh/rsync'd to in order to actually test the executables can run on the - desired targets. -*/ - -// RUN: export TENFOUR_X86_MACHINE=localhost -// RUN: export TENFIVE_X86_MACHINE=localhost -// RUN: export ARM_MACHINE=localhost -// RUN: export ARM_SYSROOT=$(xcodebuild -sdk iphoneos -version Path) - -// RUN: echo iPhoneOS, ARM, v6, thumb -// RUN: %clang -isysroot $ARM_SYSROOT -arch armv6 -mthumb -c %s -o %t.o -// RUN: %clang -isysroot $ARM_SYSROOT -arch armv6 -mthumb -v -Wl,-t,-v -o %t %t.o 1>&2 -// RUN: rsync -arv %t $ARM_MACHINE:/tmp/a.out -// RUN: ssh $ARM_MACHINE /tmp/a.out -// RUN: echo - -// RUN: echo iPhoneOS, ARM, v6, no-thumb -// RUN: %clang -isysroot $ARM_SYSROOT -arch armv6 -mno-thumb -c %s -o %t.o -// RUN: %clang -isysroot $ARM_SYSROOT -arch armv6 -mno-thumb -v -Wl,-t,-v -o %t %t.o 1>&2 -// RUN: rsync -arv %t $ARM_MACHINE:/tmp/a.out -// RUN: ssh $ARM_MACHINE /tmp/a.out -// RUN: echo - -// RUN: echo iPhoneOS, ARM, v7, thumb -// RUN: %clang -isysroot $ARM_SYSROOT -arch armv7 -mthumb -c %s -o %t.o -// RUN: %clang -isysroot $ARM_SYSROOT -arch armv7 -mthumb -v -Wl,-t,-v -o %t %t.o 1>&2 -// RUN: rsync -arv %t $ARM_MACHINE:/tmp/a.out -// RUN: ssh $ARM_MACHINE /tmp/a.out -// RUN: echo - -// RUN: echo iPhoneOS, ARM, v7, no-thumb -// RUN: %clang -isysroot $ARM_SYSROOT -arch armv7 -mno-thumb -c %s -o %t.o -// RUN: %clang -isysroot $ARM_SYSROOT -arch armv7 -mno-thumb -v -Wl,-t,-v -o %t %t.o 1>&2 -// RUN: rsync -arv %t $ARM_MACHINE:/tmp/a.out -// RUN: ssh $ARM_MACHINE /tmp/a.out -// RUN: echo - -// RUN: echo 10.4, i386 -// RUN: %clang -arch i386 -mmacosx-version-min=10.4 -c %s -o %t.o -// RUN: %clang -arch i386 -mmacosx-version-min=10.4 -v -Wl,-t,-v -o %t %t.o 1>&2 -// RUN: %t -// RUN: echo - -// RUN: rsync -arv %t $TENFOUR_X86_MACHINE:/tmp/a.out -// RUN: ssh $TENFOUR_X86_MACHINE /tmp/a.out -// RUN: echo - -// RUX: rsync -arv %t $TENFIVE_X86_MACHINE:/tmp/a.out -// RUX: ssh $TENFIVE_X86_MACHINE /tmp/a.out -// RUN: echo - -// RUN: echo 10.5, i386 -// RUN: %clang -arch i386 -mmacosx-version-min=10.5 -c %s -o %t.o -// RUN: %clang -arch i386 -mmacosx-version-min=10.5 -v -Wl,-t,-v -o %t %t.o 1>&2 -// RUN: %t -// RUN: echo - -// RUN: rsync -arv %t $TENFIVE_X86_MACHINE:/tmp/a.out -// RUN: ssh $TENFIVE_X86_MACHINE /tmp/a.out -// RUN: echo - -// RUN: echo 10.6, i386 -// RUN: %clang -arch i386 -mmacosx-version-min=10.6 -c %s -o %t.o -// RUN: %clang -arch i386 -mmacosx-version-min=10.6 -v -Wl,-t,-v -o %t %t.o 1>&2 -// RUN: %t -// RUN: echo - -// RUN: echo 10.4, x86_64 -// RUN: %clang -arch x86_64 -mmacosx-version-min=10.4 -c %s -o %t.o -// RUN: %clang -arch x86_64 -mmacosx-version-min=10.4 -v -Wl,-t,-v -o %t %t.o 1>&2 -// RUN: %t -// RUN: echo - -// RUN: rsync -arv %t $TENFOUR_X86_MACHINE:/tmp/a.out -// RUN: ssh $TENFOUR_X86_MACHINE /tmp/a.out -// RUN: echo - -// RUN: rsync -arv %t $TENFIVE_X86_MACHINE:/tmp/a.out -// RUN: ssh $TENFIVE_X86_MACHINE /tmp/a.out -// RUN: echo - -// RUN: echo 10.5, x86_64 -// RUN: %clang -arch x86_64 -mmacosx-version-min=10.5 -c %s -o %t.o -// RUN: %clang -arch x86_64 -mmacosx-version-min=10.5 -v -Wl,-t,-v -o %t %t.o 1>&2 -// RUN: %t -// RUN: echo - -// RUN: rsync -arv %t $TENFIVE_X86_MACHINE:/tmp/a.out -// RUN: ssh $TENFIVE_X86_MACHINE /tmp/a.out -// RUN: echo - -// RUN: echo 10.6, x86_64 -// RUN: %clang -arch x86_64 -mmacosx-version-min=10.6 -c %s -o %t.o -// RUN: %clang -arch x86_64 -mmacosx-version-min=10.6 -v -Wl,-t,-v -o %t %t.o 1>&2 -// RUN: %t -// RUN: echo - -#include <assert.h> -#include <stdio.h> -#include <sys/utsname.h> - -typedef int si_int; -typedef unsigned su_int; - -typedef long long di_int; -typedef unsigned long long du_int; - -// Integral bit manipulation - -di_int __ashldi3(di_int a, si_int b); // a << b -di_int __ashrdi3(di_int a, si_int b); // a >> b arithmetic (sign fill) -di_int __lshrdi3(di_int a, si_int b); // a >> b logical (zero fill) - -si_int __clzsi2(si_int a); // count leading zeros -si_int __clzdi2(di_int a); // count leading zeros -si_int __ctzsi2(si_int a); // count trailing zeros -si_int __ctzdi2(di_int a); // count trailing zeros - -si_int __ffsdi2(di_int a); // find least significant 1 bit - -si_int __paritysi2(si_int a); // bit parity -si_int __paritydi2(di_int a); // bit parity - -si_int __popcountsi2(si_int a); // bit population -si_int __popcountdi2(di_int a); // bit population - -// Integral arithmetic - -di_int __negdi2 (di_int a); // -a -di_int __muldi3 (di_int a, di_int b); // a * b -di_int __divdi3 (di_int a, di_int b); // a / b signed -du_int __udivdi3 (du_int a, du_int b); // a / b unsigned -di_int __moddi3 (di_int a, di_int b); // a % b signed -du_int __umoddi3 (du_int a, du_int b); // a % b unsigned -du_int __udivmoddi4(du_int a, du_int b, du_int* rem); // a / b, *rem = a % b - -// Integral arithmetic with trapping overflow - -si_int __absvsi2(si_int a); // abs(a) -di_int __absvdi2(di_int a); // abs(a) - -si_int __negvsi2(si_int a); // -a -di_int __negvdi2(di_int a); // -a - -si_int __addvsi3(si_int a, si_int b); // a + b -di_int __addvdi3(di_int a, di_int b); // a + b - -si_int __subvsi3(si_int a, si_int b); // a - b -di_int __subvdi3(di_int a, di_int b); // a - b - -si_int __mulvsi3(si_int a, si_int b); // a * b -di_int __mulvdi3(di_int a, di_int b); // a * b - -// Integral comparison: a < b -> 0 -// a == b -> 1 -// a > b -> 2 - -si_int __cmpdi2 (di_int a, di_int b); -si_int __ucmpdi2(du_int a, du_int b); - -// Integral / floating point conversion - -di_int __fixsfdi( float a); -di_int __fixdfdi( double a); -di_int __fixxfdi(long double a); - -su_int __fixunssfsi( float a); -su_int __fixunsdfsi( double a); -su_int __fixunsxfsi(long double a); - -du_int __fixunssfdi( float a); -du_int __fixunsdfdi( double a); -du_int __fixunsxfdi(long double a); - -float __floatdisf(di_int a); -double __floatdidf(di_int a); -long double __floatdixf(di_int a); - -float __floatundisf(du_int a); -double __floatundidf(du_int a); -long double __floatundixf(du_int a); - -// Floating point raised to integer power - -float __powisf2( float a, si_int b); // a ^ b -double __powidf2( double a, si_int b); // a ^ b -long double __powixf2(long double a, si_int b); // a ^ b - -// Complex arithmetic - -// (a + ib) * (c + id) - - float _Complex __mulsc3( float a, float b, float c, float d); - double _Complex __muldc3(double a, double b, double c, double d); -long double _Complex __mulxc3(long double a, long double b, - long double c, long double d); - -// (a + ib) / (c + id) - - float _Complex __divsc3( float a, float b, float c, float d); - double _Complex __divdc3(double a, double b, double c, double d); -long double _Complex __divxc3(long double a, long double b, - long double c, long double d); - -#ifndef __arm -#define HAS_LONG_DOUBLE -#endif - -int main(int argc, char **argv) { - du_int du_tmp; - struct utsname name; -#ifdef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ - const char *target_name = "OS X"; - unsigned target_version = __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__; - unsigned target_maj = target_version / 100; - unsigned target_min = (target_version / 10) % 10; - unsigned target_micro = target_version % 10; -#else - const char *target_name = "iPhoneOS"; - unsigned target_version = __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__; - unsigned target_maj = target_version / 10000; - unsigned target_min = (target_version / 100) % 100; - unsigned target_micro = target_version % 100; -#endif - - if (uname(&name)) - return 1; - - fprintf(stderr, "%s: clang_rt test:\n", argv[0]); - fprintf(stderr, " target : %s %d.%d.%d\n\n", target_name, - target_maj, target_min, target_micro); - fprintf(stderr, " sysname : %s\n", name.sysname); - fprintf(stderr, " nodename: %s\n", name.nodename); - fprintf(stderr, " release : %s\n", name.release); - fprintf(stderr, " version : %s\n", name.version); - fprintf(stderr, " machine : %s\n", name.machine); - - assert(__ashldi3(1, 1) == 2); - assert(__ashrdi3(2, 1) == 1); - assert(__lshrdi3(2, 1) == 1); - assert(__clzsi2(1) == 31); - assert(__clzdi2(1) == 63); - assert(__ctzsi2(2) == 1); - assert(__ctzdi2(2) == 1); - assert(__ffsdi2(12) == 3); - assert(__paritysi2(13) == 1); - assert(__paritydi2(13) == 1); - assert(__popcountsi2(13) == 3); - assert(__popcountdi2(13) == 3); - assert(__negdi2(3) == -3); - assert(__muldi3(2,2) == 4); - assert(__divdi3(-4,2) == -2); - assert(__udivdi3(4,2) == 2); - assert(__moddi3(3,2) == 1); - assert(__umoddi3(3,2) == 1); - assert(__udivmoddi4(5,2,&du_tmp) == 2 && du_tmp == 1); - assert(__absvsi2(-2) == 2); - assert(__absvdi2(-2) == 2); - assert(__negvsi2(2) == -2); - assert(__negvdi2(2) == -2); - assert(__addvsi3(2, 3) == 5); - assert(__addvdi3(2, 3) == 5); - assert(__subvsi3(2, 3) == -1); - assert(__subvdi3(2, 3) == -1); - assert(__mulvsi3(2, 3) == 6); - assert(__mulvdi3(2, 3) == 6); - assert(__cmpdi2(3, 2) == 2); - assert(__ucmpdi2(3, 2) == 2); - assert(__fixsfdi(2.0) == 2); - assert(__fixdfdi(2.0) == 2); - assert(__fixunssfsi(2.0) == 2); - assert(__fixunsdfsi(2.0) == 2); - assert(__fixunssfdi(2.0) == 2); - assert(__fixunsdfdi(2.0) == 2); - assert(__floatdisf(2) == 2.0); - assert(__floatdidf(2) == 2.0); - assert(__floatundisf(2) == 2.0); - assert(__floatundidf(2) == 2.0); - assert(__powisf2(2.0, 2) == 4.0); - assert(__powidf2(2.0, 2) == 4.0); - - // FIXME: Clang/LLVM seems to be miscompiling _Complex currently, probably an - // ABI issue. -#ifndef __arm - { - _Complex float a = __mulsc3(1.0, 2.0, 4.0, 8.0); - _Complex float b = (-12.0 + 16.0j); - fprintf(stderr, "a: (%f + %f), b: (%f + %f)\n", - __real a, __imag a, __real b, __imag b); - } - assert(__mulsc3(1.0, 2.0, 4.0, 8.0) == (-12.0 + 16.0j)); - assert(__muldc3(1.0, 2.0, 4.0, 8.0) == (-12.0 + 16.0j)); - assert(__divsc3(1.0, 2.0, 4.0, 8.0) == (0.25 + 0j)); - assert(__divdc3(1.0, 2.0, 4.0, 8.0) == (0.25 + 0j)); -#endif - -#ifdef HAS_LONG_DOUBLE - assert(__divxc3(1.0, 2.0, 4.0, 8.0) == (0.25 + 0j)); - assert(__fixunsxfdi(2.0) == 2); - assert(__fixunsxfsi(2.0) == 2); - assert(__fixxfdi(2.0) == 2); - assert(__floatdixf(2) == 2.0); - assert(__floatundixf(2) == 2); - assert(__mulxc3(1.0, 2.0, 4.0, 8.0) == (-12.0 + 16.0j)); - assert(__powixf2(2.0, 2) == 4.0); -#endif - - // Test some calls which are used on armv6/thumb. The calls/prototypes are - // fake, it would be nice to test correctness, but mostly we just want to - // make sure we resolve symbols correctly. -#if defined(__arm) && defined(__ARM_ARCH_6K__) && defined(__thumb__) - if (argc == 100) { - extern void __restore_vfp_d8_d15_regs(void), __save_vfp_d8_d15_regs(void); - extern void __switch8(void), __switchu8(void), - __switch16(void), __switch32(void); - extern void __addsf3vfp(void); - - __addsf3vfp(); - __restore_vfp_d8_d15_regs(); - __save_vfp_d8_d15_regs(); - __switch8(); - __switchu8(); - __switch16(); - __switch32(); - } -#endif - - fprintf(stderr, " OK!\n"); - - return 0; -} diff --git a/contrib/llvm/tools/clang/utils/OptionalTests/README.txt b/contrib/llvm/tools/clang/utils/OptionalTests/README.txt deleted file mode 100644 index 4ffdb3b..0000000 --- a/contrib/llvm/tools/clang/utils/OptionalTests/README.txt +++ /dev/null @@ -1,4 +0,0 @@ -This is a dumping ground for additional tests which do not fit cleanly into the -clang regression tests. For example, tests which are not portable, require -additional software or configuration, take an excessive time to run, or are -flaky can be kept here. diff --git a/contrib/llvm/tools/clang/utils/OptionalTests/lit.cfg b/contrib/llvm/tools/clang/utils/OptionalTests/lit.cfg deleted file mode 100644 index 592c424..0000000 --- a/contrib/llvm/tools/clang/utils/OptionalTests/lit.cfg +++ /dev/null @@ -1,26 +0,0 @@ -# -*- Python -*- - -# Configuration file for the 'lit' test runner. - -# Load the main clang test config so we can leech its clang finding logic. -lit.load_config(config, os.path.join(os.path.dirname(__file__), - '..', '..', 'test', 'lit.cfg')) -assert config.clang, "Failed to set clang!?" - -# name: The name of this test suite. -config.name = 'Clang-Opt-Tests' - -# suffixes: A list of file extensions to treat as test files. -config.suffixes = [] - -# Reset these from the Clang config. - -# test_source_root: The root path where tests are located. -config.test_source_root = os.path.dirname(__file__) - -# test_exec_root: The root path where tests should be run. -clang_obj_root = getattr(config, 'clang_obj_root', None) -if clang_obj_root is not None: - config.test_exec_root = os.path.join(clang_obj_root, 'utils', - 'OptionalTests') - diff --git a/contrib/llvm/tools/clang/utils/SummarizeErrors b/contrib/llvm/tools/clang/utils/SummarizeErrors deleted file mode 100755 index b6e9122..0000000 --- a/contrib/llvm/tools/clang/utils/SummarizeErrors +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/env python - -import os, sys, re - -class multidict: - def __init__(self, elts=()): - self.data = {} - for key,value in elts: - self[key] = value - - def __getitem__(self, item): - return self.data[item] - def __setitem__(self, key, value): - if key in self.data: - self.data[key].append(value) - else: - self.data[key] = [value] - def items(self): - return self.data.items() - def values(self): - return self.data.values() - def keys(self): - return self.data.keys() - def __len__(self): - return len(self.data) - -kDiagnosticRE = re.compile(': (error|warning): (.*)') -kAssertionRE = re.compile('Assertion failed: (.*, function .*, file .*, line [0-9]+\\.)') - -def readInfo(path, opts): - lastProgress = [-100,0] - def progress(pos): - pct = (100. * pos) / (size * 2) - if (pct - lastProgress[0]) >= 10: - lastProgress[0] = pct - print '%d/%d = %.2f%%' % (pos, size*2, pct) - - f = open(path) - data = f.read() - f.close() - - if opts.truncate != -1: - data = data[:opts.truncate] - - size = len(data) - warnings = multidict() - errors = multidict() - for m in kDiagnosticRE.finditer(data): - progress(m.end()) - if m.group(1) == 'error': - d = errors - else: - d = warnings - d[m.group(2)] = m - warnings = warnings.items() - errors = errors.items() - assertions = multidict() - for m in kAssertionRE.finditer(data): - print '%d/%d = %.2f%%' % (size + m.end(), size, (float(m.end()) / (size*2)) * 100.) - assertions[m.group(1)] = m - assertions = assertions.items() - - # Manual scan for stack traces - aborts = multidict() - if 0: - prevLine = None - lnIter = iter(data.split('\n')) - for ln in lnIter: - m = kStackDumpLineRE.match(ln) - if m: - stack = [m.group(2)] - for ln in lnIter: - m = kStackDumpLineRE.match(ln) - if not m: - break - stack.append(m.group(2)) - if prevLine is None or not kAssertionRE.match(prevLine): - aborts[tuple(stack)] = stack - prevLine = ln - - sections = [ - (warnings, 'Warnings'), - (errors, 'Errors'), - (assertions, 'Assertions'), - (aborts.items(), 'Aborts'), - ] - - if opts.ascending: - sections.reverse() - - for l,title in sections: - l.sort(key = lambda (a,b): -len(b)) - if l: - print '-- %d %s (%d kinds) --' % (sum([len(b) for a,b in l]), title, len(l)) - for name,elts in l: - print '%5d:' % len(elts), name - -def main(): - global options - from optparse import OptionParser - parser = OptionParser("usage: %prog [options] {inputs}") - parser.add_option("", "--ascending", dest="ascending", - help="Print output in ascending order of severity.", - action="store_true", default=False) - parser.add_option("", "--truncate", dest="truncate", - help="Truncate input file (for testing).", - type=int, action="store", default=-1) - (opts, args) = parser.parse_args() - - if not args: - parser.error('No inputs specified') - - for arg in args: - readInfo(arg, opts) - -if __name__=='__main__': - main() diff --git a/contrib/llvm/tools/clang/utils/TestUtils/deep-stack.py b/contrib/llvm/tools/clang/utils/TestUtils/deep-stack.py deleted file mode 100755 index 1750a5f..0000000 --- a/contrib/llvm/tools/clang/utils/TestUtils/deep-stack.py +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env python - -def pcall(f, N): - if N == 0: - print >>f, ' f(0)' - return - - print >>f, ' f(' - pcall(f, N - 1) - print >>f, ' )' - -def main(): - f = open('t.c','w') - print >>f, 'int f(int n) { return n; }' - print >>f, 'int t() {' - print >>f, ' return' - pcall(f, 10000) - print >>f, ' ;' - print >>f, '}' - -if __name__ == "__main__": - import sys - sys.setrecursionlimit(100000) - main() diff --git a/contrib/llvm/tools/clang/utils/TestUtils/pch-test.pl b/contrib/llvm/tools/clang/utils/TestUtils/pch-test.pl deleted file mode 100755 index e4311e9..0000000 --- a/contrib/llvm/tools/clang/utils/TestUtils/pch-test.pl +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/perl -w - -# This tiny little script, which should be run from the clang -# directory (with clang in your patch), tries to take each -# compilable Clang test and build a PCH file from that test, then read -# and dump the contents of the PCH file just created. -use POSIX; - -$exitcode = 0; -sub testfiles($$) { - my $suffix = shift; - my $language = shift; - my $passed = 0; - my $failed = 0; - my $skipped = 0; - - @files = `ls test/*/*.$suffix`; - foreach $file (@files) { - chomp($file); - my $code = system("clang -fsyntax-only -x $language $file > /dev/null 2>&1"); - if ($code == 0) { - print("."); - $code = system("clang -cc1 -emit-pch -x $language -o $file.pch $file > /dev/null 2>&1"); - if ($code == 0) { - $code = system("clang -cc1 -include-pch $file.pch -x $language -ast-dump /dev/null > /dev/null 2>&1"); - if ($code == 0) { - $passed++; - } elsif (($code & 0xFF) == SIGINT) { - exit($exitcode); - } else { - print("\n---Failed to dump AST file for \"$file\"---\n"); - $exitcode = 1; - $failed++; - } - unlink "$file.pch"; - } elsif (($code & 0xFF) == SIGINT) { - exit($exitcode); - } else { - print("\n---Failed to build PCH file for \"$file\"---\n"); - $exitcode = 1; - $failed++; - } - } elsif (($code & 0xFF) == SIGINT) { - exit($exitcode); - } else { - print("x"); - $skipped++; - } - } - - print("\n\n$passed tests passed\n"); - print("$failed tests failed\n"); - print("$skipped tests skipped ('x')\n") -} - -printf("-----Testing precompiled headers for C-----\n"); -testfiles("c", "c"); -printf("\n-----Testing precompiled headers for Objective-C-----\n"); -testfiles("m", "objective-c"); -print("\n"); -exit($exitcode); diff --git a/contrib/llvm/tools/clang/utils/VtableTest/Makefile b/contrib/llvm/tools/clang/utils/VtableTest/Makefile deleted file mode 100644 index dd615ae..0000000 --- a/contrib/llvm/tools/clang/utils/VtableTest/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -GXX := llvm-g++-4.2 -CLANGXX := clang++ - -all: one - -test.cc: gen.cc - g++ gen.cc -o gen - ./gen >test.cc - -test-gcc.sum: test.cc - time $(GXX) test.cc -o test-gcc.s -S - $(GXX) test-gcc.s -o test-gcc - ./test-gcc >test-gcc.sum - -test-clang.sum: test.cc - time $(CLANGXX) test.cc -o test-clang.s -S - $(CLANGXX) test-clang.s -o test-clang - ./test-clang >test-clang.sum - -one: test-gcc.sum test-clang.sum - cmp test-gcc.sum test-clang.sum - -clean: - rm -f gen test-gcc test-clang test.cc test-gcc.sum test-clang.sum test-gcc.s test-clang.s diff --git a/contrib/llvm/tools/clang/utils/VtableTest/check-zti b/contrib/llvm/tools/clang/utils/VtableTest/check-zti deleted file mode 100755 index bf5b045..0000000 --- a/contrib/llvm/tools/clang/utils/VtableTest/check-zti +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh - -N_STRUCTS=300 - -# Utility routine to "hand" check type infos. - -let i=1; -while [ $i != $N_STRUCTS ]; do - sed -n "/^__ZTI.*s$i:/,/\.[sg][el]/p" test-clang.s | - grep -v '\.[sg][el]' | sed 's/(\([0-9][0-9]*\))/\1/' >test-clang-zti - sed -n "/^__ZTI.*s$i:/,/\.[sg][el]/p" test-gcc.s | - grep -v '\.[sg][el]' | sed 's/(\([0-9][0-9]*\))/\1/' >test-gcc-zti - diff -U3 test-gcc-zti test-clang-zti - if [ $? != 0 ]; then - echo "FAIL: s$i type info" - else - echo "PASS: s$i type info" - fi - let i=i+1 -done diff --git a/contrib/llvm/tools/clang/utils/VtableTest/check-ztt b/contrib/llvm/tools/clang/utils/VtableTest/check-ztt deleted file mode 100755 index 4a83c55..0000000 --- a/contrib/llvm/tools/clang/utils/VtableTest/check-ztt +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh - -N_STRUCTS=300 - -# Utility routine to "hand" check VTTs. - -let i=1; -while [ $i != $N_STRUCTS ]; do - sed -n "/^__ZTT.*s$i:/,/\.[sgm][elo]/p" test-clang.s | - grep -v '\.[sgm][elo]' | sed -e 's/[()]//g' -e '/^$/d' >test-clang-ztt - sed -n "/^__ZTT.*s$i:/,/\.[sgm][elo]/p" test-gcc.s | - grep -v '\.[sgm][elo]' | sed -e 's/[()]//g' -e 's/ + /+/' >test-gcc-ztt - diff -U3 test-gcc-ztt test-clang-ztt - if [ $? != 0 ]; then - echo "FAIL: s$i VTT" - else - echo "PASS: s$i VTT" - fi - let i=i+1 -done diff --git a/contrib/llvm/tools/clang/utils/VtableTest/check-zvt b/contrib/llvm/tools/clang/utils/VtableTest/check-zvt deleted file mode 100755 index d8b93bd..0000000 --- a/contrib/llvm/tools/clang/utils/VtableTest/check-zvt +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh - -N_STRUCTS=300 - -# Utility routine to "hand" check vtables. - -let i=1; -while [ $i != $N_STRUCTS ]; do - sed -n "/^__ZTV.*s$i:/,/\.[sg][el]/p" test-clang.s | grep -v '\.[sg][el]' >test-clang-ztv - sed -n "/^__ZTV.*s$i:/,/\.[sg][el]/p" test-gcc.s | grep -v '\.[sg][el]' >test-gcc-ztv - diff -U3 test-gcc-ztv test-clang-ztv - if [ $? != 0 ]; then - echo "FAIL: s$i vtable" - else - echo "PASS: s$i vtable" - fi - let i=i+1 -done diff --git a/contrib/llvm/tools/clang/utils/VtableTest/gen.cc b/contrib/llvm/tools/clang/utils/VtableTest/gen.cc deleted file mode 100644 index 8396f8d..0000000 --- a/contrib/llvm/tools/clang/utils/VtableTest/gen.cc +++ /dev/null @@ -1,350 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> - -#define N_FIELDS 7 -#define N_FUNCS 128 -#define FUNCSPACING 20 -#define N_STRUCTS 180 /* 1280 */ -#define N_BASES 6 -#define COVARIANT 0 - -const char *simple_types[] = { "bool", "char", "short", "int", "float", - "double", "long double", "wchar_t", "void *", - "char *" -}; - -void gl(const char *c) { - printf("%s\n", c); -} - -void g(const char *c) { - printf("%s", c); -} - -void g(int i) { - printf("%d", i); -} - -int uuid = 0; -char base_present[N_STRUCTS][N_STRUCTS]; - -// The return type for each function when doing covariant testcase generation. -short ret_types[N_STRUCTS][N_FUNCS*FUNCSPACING]; - -bool is_ambiguous(int s, int base) { - for (int i = 0; i < N_STRUCTS; ++i) { - if ((base_present[base][i] & base_present[s][i]) == 1) - return true; - } - return false; -} - -void add_bases(int s, int base) { - for (int i = 0; i < N_STRUCTS; ++i) - base_present[s][i] |= base_present[base][i]; - if (!COVARIANT) - return; - for (int i = 0; i < N_FUNCS*FUNCSPACING; ++i) { - if (!ret_types[base][i]) - continue; - if (!ret_types[s][i]) { - ret_types[s][i] = ret_types[base][i]; - continue; - } - if (base_present[ret_types[base][i]][ret_types[s][i]]) - // If the return type of the function from this base dominates - ret_types[s][i] = ret_types[base][i]; - if (base_present[ret_types[s][i]][ret_types[base][i]]) - // If a previous base dominates - continue; - // If neither dominates, we'll use this class. - ret_types[s][i] = s; - } -} - -// This contains the class that has the final override for -// each class, for each function. -short final_override[N_STRUCTS][N_FUNCS*FUNCSPACING]; - -void gs(int s) { - bool polymorphic = false; - - static int bases[N_BASES]; - int i_bases = random() % (N_BASES*2); - if (i_bases >= N_BASES) - // PARAM: 1/2 of all clases should have no bases - i_bases = 0; - int n_bases = 0; - bool first_base = true; - - // PARAM: 3/4 of all should be class, the rest are structs - if (random() % 4 == 0) - g("struct s"); - else - g("class s"); - g(s); - int old_base = -1; - if (s == 0 || s == 1) - i_bases = 0; - while (i_bases) { - --i_bases; - int base = random() % (s-1) + 1; - if (!base_present[s][base]) { - if (is_ambiguous(s, base)) - continue; - if (first_base) { - first_base = false; - g(": "); - } else - g(", "); - int base_type = 1; - if (random()%8 == 0) { - // PARAM: 1/8th the bases are virtual - g("virtual "); - // We have a vtable and rtti, but technically we're not polymorphic - // polymorphic = true; - base_type = 3; - } - // PARAM: 1/4 are public, 1/8 are privare, 1/8 are protected, the reset, default - int base_protection = 0; - if (!COVARIANT) - base_protection = random()%8; - switch (base_protection) { - case 0: - case 1: - g("public "); break; - case 2: - case 3: - case 4: - case 5: - break; - case 6: - g("private "); break; - case 7: - g("protected "); break; - } - g("s"); - add_bases(s, base); - bases[n_bases] = base; - base_present[s][base] = base_type; - ++n_bases; - g(base); - old_base = base; - } - } - gl(" {"); - - /* Fields */ - int n_fields = N_FIELDS == 0 ? 0 : random() % (N_FIELDS*4); - // PARAM: 3/4 of all structs should have no members - if (n_fields >= N_FIELDS) - n_fields = 0; - for (int i = 0; i < n_fields; ++i) { - int t = random() % (sizeof(simple_types) / sizeof(simple_types[0])); - g(" "); g(simple_types[t]); g(" field"); g(i); gl(";"); - } - - /* Virtual functions */ - static int funcs[N_FUNCS*FUNCSPACING]; - // PARAM: 1/2 of all structs should have no virtual functions - int n_funcs = random() % (N_FUNCS*2); - if (n_funcs > N_FUNCS) - n_funcs = 0; - int old_func = -1; - for (int i = 0; i < n_funcs; ++i) { - int fn = old_func + random() % FUNCSPACING + 1; - funcs[i] = fn; - int ret_type = 0; - if (COVARIANT) { - ret_type = random() % s + 1; - if (!base_present[s][ret_type] - || !base_present[ret_type][ret_types[s][fn]]) - if (ret_types[s][fn]) { - printf(" // Found one for s%d for s%d* fun%d.\n", s, - ret_types[s][fn], fn); - ret_type = ret_types[s][fn]; - } else - ret_type = s; - else - printf(" // Wow found one for s%d for fun%d.\n", s, fn); - ret_types[s][fn] = ret_type; - } - if (ret_type) { - g(" virtual s"); g(ret_type); g("* fun"); - } else - g(" virtual void fun"); - g(fn); g("(char *t) { mix(\"vfn this offset\", (char *)this - t); mix(\"vfn uuid\", "); g(++uuid); - if (ret_type) - gl("); return 0; }"); - else - gl("); }"); - final_override[s][fn] = s; - old_func = fn; - } - - // Add required overriders for correctness - for (int i = 0; i < n_bases; ++i) { - // For each base - int base = bases[i]; - for (int fn = 0; fn < N_FUNCS*FUNCSPACING; ++fn) { - // For each possible function - int new_base = final_override[base][fn]; - if (new_base == 0) - // If the base didn't have a final overrider, skip - continue; - - int prev_base = final_override[s][fn]; - if (prev_base == s) - // Skip functions defined in this class - continue; - - // If we don't want to change the info, skip - if (prev_base == new_base) - continue; - - if (prev_base == 0) { - // record the final override - final_override[s][fn] = new_base; - continue; - } - - if (base_present[prev_base][new_base]) { - // The previous base dominates the new base, no update necessary - printf(" // No override for fun%d in s%d as s%d dominates s%d.\n", - fn, s, prev_base, new_base); - continue; - } - - if (base_present[new_base][prev_base]) { - // The new base dominates the old base, no override necessary - printf(" // No override for fun%d in s%d as s%d dominates s%d.\n", - fn, s, new_base, prev_base); - // record the final override - final_override[s][fn] = new_base; - continue; - } - - printf(" // Found we needed override for fun%d in s%d.\n", fn, s); - - // record the final override - funcs[n_funcs++] = fn; - if (n_funcs == (N_FUNCS*FUNCSPACING-1)) - abort(); - int ret_type = 0; - if (COVARIANT) { - if (!ret_types[s][fn]) { - ret_types[s][fn] = ret_type = s; - } else { - ret_type = ret_types[s][fn]; - if (ret_type != s) - printf(" // Calculated return type in s%d as s%d* fun%d.\n", - s, ret_type, fn); - } - } - if (ret_type) { - g(" virtual s"); g(ret_type); g("* fun"); - } else - g(" virtual void fun"); - g(fn); g("(char *t) { mix(\"vfn this offset\", (char *)this - t); mix(\"vfn uuid\", "); g(++uuid); - if (ret_type) - gl("); return 0; }"); - else - gl("); }"); - final_override[s][fn] = s; - } - } - - gl("public:"); - gl(" void calc(char *t) {"); - - // mix in the type number - g(" mix(\"type num\", "); g(s); gl(");"); - // mix in the size - g(" mix(\"type size\", sizeof (s"); g(s); gl("));"); - // mix in the this offset - gl(" mix(\"subobject offset\", (char *)this - t);"); - if (n_funcs) - polymorphic = true; - if (polymorphic) { - // mix in offset to the complete object under construction - gl(" mix(\"real top v current top\", t - (char *)dynamic_cast<void*>(this));"); - } - - /* check base layout and overrides */ - for (int i = 0; i < n_bases; ++i) { - g(" calc_s"); g(bases[i]); gl("(t);"); - } - - if (polymorphic) { - /* check dynamic_cast to each direct base */ - for (int i = 0; i < n_bases; ++i) { - g(" if ((char *)dynamic_cast<s"); g(bases[i]); gl("*>(this))"); - g(" mix(\"base dyn cast\", t - (char *)dynamic_cast<s"); g(bases[i]); gl("*>(this));"); - g(" else mix(\"no dyncast\", "); g(++uuid); gl(");"); - } - } - - /* check field layout */ - for (int i = 0; i < n_fields; ++i) { - g(" mix(\"field offset\", (char *)&field"); g(i); gl(" - (char *)this);"); - } - if (n_fields == 0) { - g(" mix(\"no fields\", "); g(++uuid); gl(");"); - } - - /* check functions */ - for (int i = 0; i < n_funcs; ++i) { - g(" fun"); g(funcs[i]); gl("(t);"); - } - if (n_funcs == 0) { - g(" mix(\"no funcs\", "); g(++uuid); gl(");"); - } - - gl(" }"); - - // default ctor - g(" s"); g(s); g("() "); - first_base = true; - for (int i = 0; i < n_bases; ++i) { - if (first_base) { - g(": "); - first_base = false; - } else - g(", "); - g("s"); g(bases[i]); g("((char *)this)"); - } - gl(" { calc((char *)this); }"); - g(" ~s"); g(s); gl("() { calc((char *)this); }"); - - // ctor with this to the complete object - g(" s"); g(s); gl("(char *t) { calc(t); }"); - g(" void calc_s"); g(s); gl("(char *t) { calc(t); }"); - g("} a"); g(s); gl(";"); -} - -main(int argc, char **argv) { - unsigned seed = 0; - char state[16]; - if (argc > 1) - seed = atol(argv[1]); - - initstate(seed, state, sizeof(state)); - gl("extern \"C\" int printf(const char *...);"); - gl(""); - gl("long long sum;"); - gl("void mix(const char *desc, long long i) {"); - // If this ever becomes too slow, we can remove this after we improve the - // mixing function - gl(" printf(\"%s: %lld\\n\", desc, i);"); - gl(" sum += ((sum ^ i) << 3) + (sum<<1) - i;"); - gl("}"); - gl(""); - // PARAM: Randomly size testcases or large testcases? - int n_structs = /* random() % */ N_STRUCTS; - for (int i = 1; i < n_structs; ++i) - gs(i); - gl("int main() {"); - gl(" printf(\"%llx\\n\", sum);"); - gl("}"); - return 0; -} diff --git a/contrib/llvm/tools/clang/utils/analyzer/CmpRuns b/contrib/llvm/tools/clang/utils/analyzer/CmpRuns deleted file mode 100755 index 739d584..0000000 --- a/contrib/llvm/tools/clang/utils/analyzer/CmpRuns +++ /dev/null @@ -1,230 +0,0 @@ -#!/usr/bin/env python - -""" -CmpRuns - A simple tool for comparing two static analyzer runs to determine -which reports have been added, removed, or changed. - -This is designed to support automated testing using the static analyzer, from -two perspectives: - 1. To monitor changes in the static analyzer's reports on real code bases, for - regression testing. - - 2. For use by end users who want to integrate regular static analyzer testing - into a buildbot like environment. -""" - -import os -import plistlib - -# - -class multidict: - def __init__(self, elts=()): - self.data = {} - for key,value in elts: - self[key] = value - - def __getitem__(self, item): - return self.data[item] - def __setitem__(self, key, value): - if key in self.data: - self.data[key].append(value) - else: - self.data[key] = [value] - def items(self): - return self.data.items() - def values(self): - return self.data.values() - def keys(self): - return self.data.keys() - def __len__(self): - return len(self.data) - def get(self, key, default=None): - return self.data.get(key, default) - -# - -class AnalysisReport: - def __init__(self, run, files): - self.run = run - self.files = files - -class AnalysisDiagnostic: - def __init__(self, data, report, htmlReport): - self.data = data - self.report = report - self.htmlReport = htmlReport - - def getReadableName(self): - loc = self.data['location'] - filename = self.report.run.getSourceName(self.report.files[loc['file']]) - line = loc['line'] - column = loc['col'] - - # FIXME: Get a report number based on this key, to 'distinguish' - # reports, or something. - - return '%s:%d:%d' % (filename, line, column) - - def getReportData(self): - if self.htmlReport is None: - return "This diagnostic does not have any report data." - - return open(os.path.join(self.report.run.path, - self.htmlReport), "rb").read() - -class AnalysisRun: - def __init__(self, path, opts): - self.path = path - self.reports = [] - self.diagnostics = [] - self.opts = opts - - def getSourceName(self, path): - if path.startswith(self.opts.root): - return path[len(self.opts.root):] - return path - -def loadResults(path, opts): - run = AnalysisRun(path, opts) - - for f in os.listdir(path): - if (not f.startswith('report') or - not f.endswith('plist')): - continue - - p = os.path.join(path, f) - data = plistlib.readPlist(p) - - # Ignore empty reports. - if not data['files']: - continue - - # Extract the HTML reports, if they exists. - if 'HTMLDiagnostics_files' in data['diagnostics'][0]: - htmlFiles = [] - for d in data['diagnostics']: - # FIXME: Why is this named files, when does it have multiple - # files? - assert len(d['HTMLDiagnostics_files']) == 1 - htmlFiles.append(d.pop('HTMLDiagnostics_files')[0]) - else: - htmlFiles = [None] * len(data['diagnostics']) - - report = AnalysisReport(run, data.pop('files')) - diagnostics = [AnalysisDiagnostic(d, report, h) - for d,h in zip(data.pop('diagnostics'), - htmlFiles)] - - assert not data - - run.reports.append(report) - run.diagnostics.extend(diagnostics) - - return run - -def compareResults(A, B): - """ - compareResults - Generate a relation from diagnostics in run A to - diagnostics in run B. - - The result is the relation as a list of triples (a, b, confidence) where - each element {a,b} is None or an element from the respective run, and - confidence is a measure of the match quality (where 0 indicates equality, - and None is used if either element is None). - """ - - res = [] - - # Quickly eliminate equal elements. - neqA = [] - neqB = [] - eltsA = list(A.diagnostics) - eltsB = list(B.diagnostics) - eltsA.sort(key = lambda d: d.data) - eltsB.sort(key = lambda d: d.data) - while eltsA and eltsB: - a = eltsA.pop() - b = eltsB.pop() - if a.data == b.data: - res.append((a, b, 0)) - elif a.data > b.data: - neqA.append(a) - eltsB.append(b) - else: - neqB.append(b) - eltsA.append(a) - neqA.extend(eltsA) - neqB.extend(eltsB) - - # FIXME: Add fuzzy matching. One simple and possible effective idea would be - # to bin the diagnostics, print them in a normalized form (based solely on - # the structure of the diagnostic), compute the diff, then use that as the - # basis for matching. This has the nice property that we don't depend in any - # way on the diagnostic format. - - for a in neqA: - res.append((a, None, None)) - for b in neqB: - res.append((None, b, None)) - - return res - -def main(): - from optparse import OptionParser - parser = OptionParser("usage: %prog [options] [dir A] [dir B]") - parser.add_option("", "--root", dest="root", - help="Prefix to ignore on source files", - action="store", type=str, default="") - parser.add_option("", "--verbose-log", dest="verboseLog", - help="Write additional information to LOG [default=None]", - action="store", type=str, default=None, - metavar="LOG") - (opts, args) = parser.parse_args() - - if len(args) != 2: - parser.error("invalid number of arguments") - - dirA,dirB = args - - # Load the run results. - resultsA = loadResults(dirA, opts) - resultsB = loadResults(dirB, opts) - - # Open the verbose log, if given. - if opts.verboseLog: - auxLog = open(opts.verboseLog, "wb") - else: - auxLog = None - - diff = compareResults(resultsA, resultsB) - for res in diff: - a,b,confidence = res - if a is None: - print "ADDED: %r" % b.getReadableName() - if auxLog: - print >>auxLog, ("('ADDED', %r, %r)" % (b.getReadableName(), - b.getReportData())) - elif b is None: - print "REMOVED: %r" % a.getReadableName() - if auxLog: - print >>auxLog, ("('REMOVED', %r, %r)" % (a.getReadableName(), - a.getReportData())) - elif confidence: - print "CHANGED: %r to %r" % (a.getReadableName(), - b.getReadableName()) - if auxLog: - print >>auxLog, ("('CHANGED', %r, %r, %r, %r)" - % (a.getReadableName(), - b.getReadableName(), - a.getReportData(), - b.getReportData())) - else: - pass - - print "TOTAL REPORTS: %r" % len(resultsB.diagnostics) - if auxLog: - print >>auxLog, "('TOTAL', %r)" % len(resultsB.diagnostics) - -if __name__ == '__main__': - main() diff --git a/contrib/llvm/tools/clang/utils/analyzer/ubiviz b/contrib/llvm/tools/clang/utils/analyzer/ubiviz deleted file mode 100755 index 1582797..0000000 --- a/contrib/llvm/tools/clang/utils/analyzer/ubiviz +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/env python -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -# -# This script reads visualization data emitted by the static analyzer for -# display in Ubigraph. -# -##===----------------------------------------------------------------------===## - -import xmlrpclib -import sys - -def Error(message): - print >> sys.stderr, 'ubiviz: ' + message - sys.exit(1) - -def StreamData(filename): - file = open(filename) - for ln in file: - yield eval(ln) - file.close() - -def Display(G, data): - action = data[0] - if action == 'vertex': - vertex = data[1] - G.new_vertex_w_id(vertex) - for attribute in data[2:]: - G.set_vertex_attribute(vertex, attribute[0], attribute[1]) - elif action == 'edge': - src = data[1] - dst = data[2] - edge = G.new_edge(src,dst) - for attribute in data[3:]: - G.set_edge_attribute(edge, attribute[0], attribute[1]) - elif action == "vertex_style": - style_id = data[1] - parent_id = data[2] - G.new_vertex_style_w_id(style_id, parent_id) - for attribute in data[3:]: - G.set_vertex_style_attribute(style_id, attribute[0], attribute[1]) - elif action == "vertex_style_attribute": - style_id = data[1] - for attribute in data[2:]: - G.set_vertex_style_attribute(style_id, attribute[0], attribute[1]) - elif action == "change_vertex_style": - vertex_id = data[1] - style_id = data[2] - G.change_vertex_style(vertex_id,style_id) - -def main(args): - if len(args) == 0: - Error('no input files') - - server = xmlrpclib.Server('http://127.0.0.1:20738/RPC2') - G = server.ubigraph - - for arg in args: - G.clear() - for x in StreamData(arg): - Display(G,x) - - sys.exit(0) - - -if __name__ == '__main__': - main(sys.argv[1:]) - -
\ No newline at end of file diff --git a/contrib/llvm/tools/clang/utils/builtin-defines.c b/contrib/llvm/tools/clang/utils/builtin-defines.c deleted file mode 100644 index 9bbe5be2..0000000 --- a/contrib/llvm/tools/clang/utils/builtin-defines.c +++ /dev/null @@ -1,85 +0,0 @@ -/* -This is a clang style test case for checking that preprocessor -defines match gcc. -*/ - -/* -RUN: for arch in -m32 -m64; do \ -RUN: for lang in -std=gnu89 -ansi -std=c99 -std=gnu99; do \ -RUN: for input in c objective-c; do \ -RUN: for opts in "-O0" "-O1 -dynamic" "-O2 -static" "-Os"; do \ -RUN: echo "-- $arch, $lang, $input, $opts --"; \ -RUN: for cc in 0 1; do \ -RUN: if [ "$cc" == 0 ]; then \ -RUN: cc_prog=clang; \ -RUN: output=%t0; \ -RUN: else \ -RUN: cc_prog=gcc; \ -RUN: output=%t1; \ -RUN: fi; \ -RUN: $cc_prog $arch $lang $opts -march=core2 -dM -E -x $input %s | sort > $output; \ -RUN: done; \ -RUN: if (! diff %t0 %t1); then exit 1; fi; \ -RUN: done; \ -RUN: done; \ -RUN: done; \ -RUN: done; -*/ - -/* We don't care about this difference */ -#ifdef __PIC__ -#if __PIC__ == 1 -#undef __PIC__ -#undef __pic__ -#define __PIC__ 2 -#define __pic__ 2 -#endif -#endif - -/* Undefine things we don't expect to match. */ -#undef __core2 -#undef __core2__ -#undef __SSSE3__ - -/* Undefine things we don't expect to match. */ -#undef __DEC_EVAL_METHOD__ -#undef __INT16_TYPE__ -#undef __INT32_TYPE__ -#undef __INT64_TYPE__ -#undef __INT8_TYPE__ -#undef __SSP__ -#undef __APPLE_CC__ -#undef __VERSION__ -#undef __clang__ -#undef __llvm__ -#undef __nocona -#undef __nocona__ -#undef __k8 -#undef __k8__ -#undef __tune_nocona__ -#undef __tune_core2__ -#undef __POINTER_WIDTH__ -#undef __INTPTR_TYPE__ -#undef __NO_MATH_INLINES - -#undef __DEC128_DEN__ -#undef __DEC128_EPSILON__ -#undef __DEC128_MANT_DIG__ -#undef __DEC128_MAX_EXP__ -#undef __DEC128_MAX__ -#undef __DEC128_MIN_EXP__ -#undef __DEC128_MIN__ -#undef __DEC32_DEN__ -#undef __DEC32_EPSILON__ -#undef __DEC32_MANT_DIG__ -#undef __DEC32_MAX_EXP__ -#undef __DEC32_MAX__ -#undef __DEC32_MIN_EXP__ -#undef __DEC32_MIN__ -#undef __DEC64_DEN__ -#undef __DEC64_EPSILON__ -#undef __DEC64_MANT_DIG__ -#undef __DEC64_MAX_EXP__ -#undef __DEC64_MAX__ -#undef __DEC64_MIN_EXP__ -#undef __DEC64_MIN__ diff --git a/contrib/llvm/tools/clang/utils/clang-completion-mode.el b/contrib/llvm/tools/clang/utils/clang-completion-mode.el deleted file mode 100644 index 873127f..0000000 --- a/contrib/llvm/tools/clang/utils/clang-completion-mode.el +++ /dev/null @@ -1,257 +0,0 @@ -;;; Clang Code-Completion minor mode, for use with C/Objective-C/C++. - -;;; Commentary: - -;; This minor mode uses Clang's command line interface for code -;; completion to provide code completion results for C, Objective-C, -;; and C++ source files. When enabled, Clang will provide -;; code-completion results in a secondary buffer based on the code -;; being typed. For example, after typing "struct " (triggered via the -;; space), Clang will provide the names of all structs visible from -;; the current scope. After typing "p->" (triggered via the ">"), -;; Clang will provide the names of all of the members of whatever -;; class/struct/union "p" points to. Note that this minor mode isn't -;; meant for serious use: it is meant to help experiment with code -;; completion based on Clang. It needs your help to make it better! -;; -;; To use the Clang code completion mode, first make sure that the -;; "clang" variable below refers to the "clang" executable, -;; which is typically installed in libexec/. Then, place -;; clang-completion-mode.el somewhere in your Emacs load path. You can -;; add a new load path to Emacs by adding some like the following to -;; your .emacs: -;; -;; (setq load-path (cons "~/.emacs.d" load-path)) -;; -;; Then, use -;; -;; M-x load-library -;; -;; to load the library in your Emacs session or add the following to -;; your .emacs to always load this mode (not recommended): -;; -;; (load-library "clang-completion-mode") -;; -;; Finally, to try Clang-based code completion in a particular buffer, -;; use M-x clang-completion-mode. When "Clang-CC" shows up in the mode -;; line, Clang's code-completion is enabled. -;; -;; Clang's code completion is based on parsing the complete source -;; file up to the point where the cursor is located. Therefore, Clang -;; needs all of the various compilation flags (include paths, dialect -;; options, etc.) to provide code-completion results. Currently, these -;; need to be placed into the clang-flags variable in a format -;; acceptable to clang. This is a hack: patches are welcome to -;; improve the interface between this Emacs mode and Clang! -;; - -;;; Code: -;;; The clang executable -(defcustom clang "clang" - "The location of the Clang compiler executable" - :type 'file - :group 'clang-completion-mode) - -;;; Extra compilation flags to pass to clang. -(defcustom clang-flags "" - "Extra flags to pass to the Clang executable. -This variable will typically contain include paths, e.g., -I~/MyProject." - :type 'string - :group 'clang-completion-mode) - -;;; The prefix header to use with Clang code completion. -(setq clang-completion-prefix-header "") - -;;; The substring we will use to filter completion results -(setq clang-completion-substring "") - -;;; The current completion buffer -(setq clang-completion-buffer nil) - -(setq clang-result-string "") - -;;; Compute the current line in the buffer -(defun current-line () - "Return the vertical position of point..." - (+ (count-lines (point-min) (point)) - (if (= (current-column) 0) 1 0) - -1)) - -;;; Set the Clang prefix header -(defun clang-prefix-header () - (interactive) - (setq clang-completion-prefix-header - (read-string "Clang prefix header> " "" clang-completion-prefix-header - ""))) - -;; Process "filter" that keeps track of the code-completion results -;; produced. We store all of the results in a string, then the -;; sentinel processes the entire string at once. -(defun clang-completion-stash-filter (proc string) - (setq clang-result-string (concat clang-result-string string))) - -;; Filter the given list based on a predicate. -(defun filter (condp lst) - (delq nil - (mapcar (lambda (x) (and (funcall condp x) x)) lst))) - -;; Determine whether -(defun is-completion-line (line) - (or (string-match "OVERLOAD:" line) - (string-match (concat "COMPLETION: " clang-completion-substring) line))) - -(defun clang-completion-display (buffer) - (let* ((all-lines (split-string clang-result-string "\n")) - (completion-lines (filter 'is-completion-line all-lines))) - (if (consp completion-lines) - (progn - ;; Erase the process buffer - (let ((cur (current-buffer))) - (set-buffer buffer) - (goto-char (point-min)) - (erase-buffer) - (set-buffer cur)) - - ;; Display the process buffer - (display-buffer buffer) - - ;; Insert the code-completion string into the process buffer. - (with-current-buffer buffer - (insert (mapconcat 'identity completion-lines "\n"))) - )))) - -;; Process "sentinal" that, on successful code completion, replaces the -;; contents of the code-completion buffer with the new code-completion results -;; and ensures that the buffer is visible. -(defun clang-completion-sentinel (proc event) - (let* ((all-lines (split-string clang-result-string "\n")) - (completion-lines (filter 'is-completion-line all-lines))) - (if (consp completion-lines) - (progn - ;; Erase the process buffer - (let ((cur (current-buffer))) - (set-buffer (process-buffer proc)) - (goto-char (point-min)) - (erase-buffer) - (set-buffer cur)) - - ;; Display the process buffer - (display-buffer (process-buffer proc)) - - ;; Insert the code-completion string into the process buffer. - (with-current-buffer (process-buffer proc) - (insert (mapconcat 'identity completion-lines "\n"))) - )))) - -(defun clang-complete () - (let* ((cc-point (concat (buffer-file-name) - ":" - (number-to-string (+ 1 (current-line))) - ":" - (number-to-string (+ 1 (current-column))))) - (cc-pch (if (equal clang-completion-prefix-header "") nil - (list "-include-pch" - (concat clang-completion-prefix-header ".pch")))) - (cc-flags (if (listp clang-flags) clang-flags nil)) - (cc-command (append `(,clang "-cc1" "-fsyntax-only") - cc-flags - cc-pch - `("-code-completion-at" ,cc-point) - (list (buffer-file-name)))) - (cc-buffer-name (concat "*Clang Completion for " (buffer-name) "*"))) - ;; Start the code-completion process - (if (buffer-file-name) - (progn - ;; If there is already a code-completion process, kill it first. - (let ((cc-proc (get-process "Clang Code-Completion"))) - (if cc-proc - (delete-process cc-proc))) - - (setq clang-completion-substring "") - (setq clang-result-string "") - (setq clang-completion-buffer cc-buffer-name) - - (let ((cc-proc (apply 'start-process - (append (list "Clang Code-Completion" cc-buffer-name) - cc-command)))) - (set-process-filter cc-proc 'clang-completion-stash-filter) - (set-process-sentinel cc-proc 'clang-completion-sentinel) - ))))) - -;; Code-completion when one of the trigger characters is typed into -;; the buffer, e.g., '(', ',' or '.'. -(defun clang-complete-self-insert (arg) - (interactive "p") - (self-insert-command arg) - (save-buffer) - (clang-complete)) - -;; When the user has typed a character that requires the filter to be -;; updated, do so (and update the display of results). -(defun clang-update-filter () - (setq clang-completion-substring (thing-at-point 'symbol)) - (if (get-process "Clang Code-Completion") - () - (clang-completion-display clang-completion-buffer) - )) - -;; Invoked when the user types an alphanumeric character or "_" to -;; update the filter for the currently-active code completion. -(defun clang-filter-self-insert (arg) - (interactive "p") - (self-insert-command arg) - (clang-update-filter) - ) - -;; Invoked when the user types the backspace key to update the filter -;; for the currently-active code completion. -(defun clang-backspace () - (interactive) - (delete-backward-char 1) - (clang-update-filter)) - -;; Invoked when the user types the delete key to update the filter -;; for the currently-active code completion. -(defun clang-delete () - (interactive) - (delete-backward-char 1) - (clang-update-filter)) - -;; Set up the keymap for the Clang minor mode. -(defvar clang-completion-mode-map nil - "Keymap for Clang Completion Mode.") - -(if (null clang-completion-mode-map) - (fset 'clang-completion-mode-map - (setq clang-completion-mode-map (make-sparse-keymap)))) - -(if (not (assq 'clang-completion-mode minor-mode-map-alist)) - (setq minor-mode-map-alist - (cons (cons 'clang-completion-mode clang-completion-mode-map) - minor-mode-map-alist))) - -;; Punctuation characters trigger code completion. -(dolist (char '("(" "," "." ">" ":" "=" ")" " ")) - (define-key clang-completion-mode-map char 'clang-complete-self-insert)) - -;; Alphanumeric characters (and "_") filter the results of the -;; currently-active code completion. -(dolist (char '("A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" - "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z" - "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" - "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z" - "_" "0" "1" "2" "3" "4" "5" "6" "7" "8" "9")) - (define-key clang-completion-mode-map char 'clang-filter-self-insert)) - -;; Delete and backspace filter the results of the currently-active -;; code completion. -(define-key clang-completion-mode-map [(backspace)] 'clang-backspace) -(define-key clang-completion-mode-map [(delete)] 'clang-delete) - -;; Set up the Clang minor mode. -(define-minor-mode clang-completion-mode - "Clang code-completion mode" - nil - " Clang" - clang-completion-mode-map) - diff --git a/contrib/llvm/tools/clang/utils/token-delta.py b/contrib/llvm/tools/clang/utils/token-delta.py deleted file mode 100755 index 327fa92..0000000 --- a/contrib/llvm/tools/clang/utils/token-delta.py +++ /dev/null @@ -1,251 +0,0 @@ -#!/usr/bin/env python - -import os -import re -import subprocess -import sys -import tempfile - -### - -class DeltaAlgorithm(object): - def __init__(self): - self.cache = set() - - def test(self, changes): - abstract - - ### - - def getTestResult(self, changes): - # There is no reason to cache successful tests because we will - # always reduce the changeset when we see one. - - changeset = frozenset(changes) - if changeset in self.cache: - return False - elif not self.test(changes): - self.cache.add(changeset) - return False - else: - return True - - def run(self, changes, force=False): - # Make sure the initial test passes, if not then (a) either - # the user doesn't expect monotonicity, and we may end up - # doing O(N^2) tests, or (b) the test is wrong. Avoid the - # O(N^2) case unless user requests it. - if not force: - if not self.getTestResult(changes): - raise ValueError,'Initial test passed to delta fails.' - - # Check empty set first to quickly find poor test functions. - if self.getTestResult(set()): - return set() - else: - return self.delta(changes, self.split(changes)) - - def split(self, S): - """split(set) -> [sets] - - Partition a set into one or two pieces. - """ - - # There are many ways to split, we could do a better job with more - # context information (but then the API becomes grosser). - L = list(S) - mid = len(L)//2 - if mid==0: - return L, - else: - return L[:mid],L[mid:] - - def delta(self, c, sets): - # assert(reduce(set.union, sets, set()) == c) - - # If there is nothing left we can remove, we are done. - if len(sets) <= 1: - return c - - # Look for a passing subset. - res = self.search(c, sets) - if res is not None: - return res - - # Otherwise, partition sets if possible; if not we are done. - refined = sum(map(list, map(self.split, sets)), []) - if len(refined) == len(sets): - return c - - return self.delta(c, refined) - - def search(self, c, sets): - for i,S in enumerate(sets): - # If test passes on this subset alone, recurse. - if self.getTestResult(S): - return self.delta(S, self.split(S)) - - # Otherwise if we have more than two sets, see if test - # pases without this subset. - if len(sets) > 2: - complement = sum(sets[:i] + sets[i+1:],[]) - if self.getTestResult(complement): - return self.delta(complement, sets[:i] + sets[i+1:]) - -### - -class Token: - def __init__(self, type, data, flags, file, line, column): - self.type = type - self.data = data - self.flags = flags - self.file = file - self.line = line - self.column = column - -kTokenRE = re.compile(r"""([a-z_]+) '(.*)'\t(.*)\tLoc=<(.*):(.*):(.*)>""", - re.DOTALL | re.MULTILINE) - -def getTokens(path): - p = subprocess.Popen(['clang','-dump-raw-tokens',path], - stdin=subprocess.PIPE, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - out,err = p.communicate() - - tokens = [] - collect = None - for ln in err.split('\n'): - # Silly programmers refuse to print in simple machine readable - # formats. Whatever. - if collect is None: - collect = ln - else: - collect = collect + '\n' + ln - if 'Loc=<' in ln and ln.endswith('>'): - ln,collect = collect,None - tokens.append(Token(*kTokenRE.match(ln).groups())) - - return tokens - -### - -class TMBDDelta(DeltaAlgorithm): - def __init__(self, testProgram, tokenLists, log): - def patchName(name, suffix): - base,ext = os.path.splitext(name) - return base + '.' + suffix + ext - super(TMBDDelta, self).__init__() - self.testProgram = testProgram - self.tokenLists = tokenLists - self.tempFiles = [patchName(f,'tmp') - for f,_ in self.tokenLists] - self.targetFiles = [patchName(f,'ok') - for f,_ in self.tokenLists] - self.log = log - self.numTests = 0 - - def writeFiles(self, changes, fileNames): - assert len(fileNames) == len(self.tokenLists) - byFile = [[] for i in self.tokenLists] - for i,j in changes: - byFile[i].append(j) - - for i,(file,tokens) in enumerate(self.tokenLists): - f = open(fileNames[i],'w') - for j in byFile[i]: - f.write(tokens[j]) - f.close() - - return byFile - - def test(self, changes): - self.numTests += 1 - - byFile = self.writeFiles(changes, self.tempFiles) - - if self.log: - print >>sys.stderr, 'TEST - ', - if self.log > 1: - for i,(file,_) in enumerate(self.tokenLists): - indices = byFile[i] - if i: - sys.stderr.write('\n ') - sys.stderr.write('%s:%d tokens: [' % (file,len(byFile[i]))) - prev = None - for j in byFile[i]: - if prev is None or j != prev + 1: - if prev: - sys.stderr.write('%d][' % prev) - sys.stderr.write(str(j)) - sys.stderr.write(':') - prev = j - if byFile[i]: - sys.stderr.write(str(byFile[i][-1])) - sys.stderr.write('] ') - else: - print >>sys.stderr, ', '.join(['%s:%d tokens' % (file, len(byFile[i])) - for i,(file,_) in enumerate(self.tokenLists)]), - - p = subprocess.Popen([self.testProgram] + self.tempFiles) - res = p.wait() == 0 - - if res: - self.writeFiles(changes, self.targetFiles) - - if self.log: - print >>sys.stderr, '=> %s' % res - else: - if res: - print '\nSUCCESS (%d tokens)' % len(changes) - else: - sys.stderr.write('.') - - return res - - def run(self): - res = super(TMBDDelta, self).run([(i,j) - for i,(file,tokens) in enumerate(self.tokenLists) - for j in range(len(tokens))]) - self.writeFiles(res, self.targetFiles) - if not self.log: - print >>sys.stderr - return res - -def tokenBasedMultiDelta(program, files, log): - # Read in the lists of tokens. - tokenLists = [(file, [t.data for t in getTokens(file)]) - for file in files] - - numTokens = sum([len(tokens) for _,tokens in tokenLists]) - print "Delta on %s with %d tokens." % (', '.join(files), numTokens) - - tbmd = TMBDDelta(program, tokenLists, log) - - res = tbmd.run() - - print "Finished %s with %d tokens (in %d tests)." % (', '.join(tbmd.targetFiles), - len(res), - tbmd.numTests) - -def main(): - from optparse import OptionParser, OptionGroup - parser = OptionParser("%prog <test program> {files+}") - parser.add_option("", "--debug", dest="debugLevel", - help="set debug level [default %default]", - action="store", type=int, default=0) - (opts, args) = parser.parse_args() - - if len(args) <= 1: - parser.error('Invalid number of arguments.') - - program,files = args[0],args[1:] - - md = tokenBasedMultiDelta(program, files, log=opts.debugLevel) - -if __name__ == '__main__': - try: - main() - except KeyboardInterrupt: - print >>sys.stderr,'Interrupted.' - os._exit(1) # Avoid freeing our giant cache. diff --git a/contrib/llvm/tools/clang/utils/valgrind/x86_64-pc-linux-gnu_gcc-4.3.3.supp b/contrib/llvm/tools/clang/utils/valgrind/x86_64-pc-linux-gnu_gcc-4.3.3.supp deleted file mode 100644 index a86be6c..0000000 --- a/contrib/llvm/tools/clang/utils/valgrind/x86_64-pc-linux-gnu_gcc-4.3.3.supp +++ /dev/null @@ -1,23 +0,0 @@ -{ - libstdcxx_overlapped_memcpy_in_stable_sort_1 - Memcheck:Overlap - fun:memcpy - ... - fun:_ZSt11stable_sortIN9__gnu_cxx17__normal_iteratorIPSt4pairIPKN4llvm5ValueEjESt6vectorIS7_SaIS7_EEEEN12_GLOBAL__N_116CstSortPredicateEEvT_SF_T0_ -} - -{ - libstdcxx_overlapped_memcpy_in_stable_sort_2 - Memcheck:Overlap - fun:memcpy - ... - fun:_ZSt11stable_sortIN9__gnu_cxx17__normal_iteratorIPSt4pairIPKN4llvm5ValueEjESt6vectorIS7_SaIS7_EEEEN12_GLOBAL__N_116CstSortPredicateEEvT_SF_T0_ -} - -{ - libstdcxx_overlapped_memcpy_in_stable_sort_3 - Memcheck:Overlap - fun:memcpy - ... - fun:_ZSt11stable_sortIN9__gnu_cxx17__normal_iteratorIPSt4pairIPKN4llvm4TypeEjESt6vectorIS7_SaIS7_EEEEPFbRKS7_SE_EEvT_SH_T0_ -} diff --git a/contrib/llvm/tools/edis/CMakeLists.txt b/contrib/llvm/tools/edis/CMakeLists.txt deleted file mode 100644 index 2019995..0000000 --- a/contrib/llvm/tools/edis/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -set(LLVM_NO_RTTI 1) - -include_directories(${CMAKE_CURRENT_BINARY_DIR}) - -add_llvm_library(EnhancedDisassembly - ../../include/llvm-c/EnhancedDisassembly.h - EDMain.cpp -) - -set_target_properties(EnhancedDisassembly - PROPERTIES - LINKER_LANGUAGE CXX) - diff --git a/contrib/llvm/tools/edis/EDMain.cpp b/contrib/llvm/tools/edis/EDMain.cpp deleted file mode 100644 index 16855b3..0000000 --- a/contrib/llvm/tools/edis/EDMain.cpp +++ /dev/null @@ -1,284 +0,0 @@ -//===-- EDMain.cpp - LLVM Enhanced Disassembly C API ----------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the enhanced disassembler's public C API. -// -//===----------------------------------------------------------------------===// - -// FIXME: This code isn't layered right, the headers should be moved to -// include llvm/MC/MCDisassembler or something. -#include "../../lib/MC/MCDisassembler/EDDisassembler.h" -#include "../../lib/MC/MCDisassembler/EDInst.h" -#include "../../lib/MC/MCDisassembler/EDOperand.h" -#include "../../lib/MC/MCDisassembler/EDToken.h" -#include "llvm-c/EnhancedDisassembly.h" -using namespace llvm; - -int EDGetDisassembler(EDDisassemblerRef *disassembler, - const char *triple, - EDAssemblySyntax_t syntax) { - EDDisassembler::initialize(); - - EDDisassembler::AssemblySyntax Syntax; - switch (syntax) { - default: assert(0 && "Unknown assembly syntax!"); - case kEDAssemblySyntaxX86Intel: - Syntax = EDDisassembler::kEDAssemblySyntaxX86Intel; - break; - case kEDAssemblySyntaxX86ATT: - Syntax = EDDisassembler::kEDAssemblySyntaxX86ATT; - break; - case kEDAssemblySyntaxARMUAL: - Syntax = EDDisassembler::kEDAssemblySyntaxARMUAL; - break; - } - - EDDisassemblerRef ret = EDDisassembler::getDisassembler(triple, Syntax); - - if (!ret) - return -1; - *disassembler = ret; - return 0; -} - -int EDGetRegisterName(const char** regName, - EDDisassemblerRef disassembler, - unsigned regID) { - const char *name = ((EDDisassembler*)disassembler)->nameWithRegisterID(regID); - if (!name) - return -1; - *regName = name; - return 0; -} - -int EDRegisterIsStackPointer(EDDisassemblerRef disassembler, - unsigned regID) { - return ((EDDisassembler*)disassembler)->registerIsStackPointer(regID) ? 1 : 0; -} - -int EDRegisterIsProgramCounter(EDDisassemblerRef disassembler, - unsigned regID) { - return ((EDDisassembler*)disassembler)->registerIsProgramCounter(regID) ? 1:0; -} - -unsigned int EDCreateInsts(EDInstRef *insts, - unsigned int count, - EDDisassemblerRef disassembler, - ::EDByteReaderCallback byteReader, - uint64_t address, - void *arg) { - unsigned int index; - - for (index = 0; index < count; ++index) { - EDInst *inst = ((EDDisassembler*)disassembler)->createInst(byteReader, - address, arg); - - if (!inst) - return index; - - insts[index] = inst; - address += inst->byteSize(); - } - - return count; -} - -void EDReleaseInst(EDInstRef inst) { - delete ((EDInst*)inst); -} - -int EDInstByteSize(EDInstRef inst) { - return ((EDInst*)inst)->byteSize(); -} - -int EDGetInstString(const char **buf, - EDInstRef inst) { - return ((EDInst*)inst)->getString(*buf); -} - -int EDInstID(unsigned *instID, EDInstRef inst) { - *instID = ((EDInst*)inst)->instID(); - return 0; -} - -int EDInstIsBranch(EDInstRef inst) { - return ((EDInst*)inst)->isBranch(); -} - -int EDInstIsMove(EDInstRef inst) { - return ((EDInst*)inst)->isMove(); -} - -int EDBranchTargetID(EDInstRef inst) { - return ((EDInst*)inst)->branchTargetID(); -} - -int EDMoveSourceID(EDInstRef inst) { - return ((EDInst*)inst)->moveSourceID(); -} - -int EDMoveTargetID(EDInstRef inst) { - return ((EDInst*)inst)->moveTargetID(); -} - -int EDNumTokens(EDInstRef inst) { - return ((EDInst*)inst)->numTokens(); -} - -int EDGetToken(EDTokenRef *token, - EDInstRef inst, - int index) { - return ((EDInst*)inst)->getToken(*(EDToken**)token, index); -} - -int EDGetTokenString(const char **buf, - EDTokenRef token) { - return ((EDToken*)token)->getString(*buf); -} - -int EDOperandIndexForToken(EDTokenRef token) { - return ((EDToken*)token)->operandID(); -} - -int EDTokenIsWhitespace(EDTokenRef token) { - return ((EDToken*)token)->type() == EDToken::kTokenWhitespace; -} - -int EDTokenIsPunctuation(EDTokenRef token) { - return ((EDToken*)token)->type() == EDToken::kTokenPunctuation; -} - -int EDTokenIsOpcode(EDTokenRef token) { - return ((EDToken*)token)->type() == EDToken::kTokenOpcode; -} - -int EDTokenIsLiteral(EDTokenRef token) { - return ((EDToken*)token)->type() == EDToken::kTokenLiteral; -} - -int EDTokenIsRegister(EDTokenRef token) { - return ((EDToken*)token)->type() == EDToken::kTokenRegister; -} - -int EDTokenIsNegativeLiteral(EDTokenRef token) { - if (((EDToken*)token)->type() != EDToken::kTokenLiteral) - return -1; - - return ((EDToken*)token)->literalSign(); -} - -int EDLiteralTokenAbsoluteValue(uint64_t *value, EDTokenRef token) { - if (((EDToken*)token)->type() != EDToken::kTokenLiteral) - return -1; - - return ((EDToken*)token)->literalAbsoluteValue(*value); -} - -int EDRegisterTokenValue(unsigned *registerID, - EDTokenRef token) { - if (((EDToken*)token)->type() != EDToken::kTokenRegister) - return -1; - - return ((EDToken*)token)->registerID(*registerID); -} - -int EDNumOperands(EDInstRef inst) { - return ((EDInst*)inst)->numOperands(); -} - -int EDGetOperand(EDOperandRef *operand, - EDInstRef inst, - int index) { - return ((EDInst*)inst)->getOperand(*(EDOperand**)operand, index); -} - -int EDOperandIsRegister(EDOperandRef operand) { - return ((EDOperand*)operand)->isRegister(); -} - -int EDOperandIsImmediate(EDOperandRef operand) { - return ((EDOperand*)operand)->isImmediate(); -} - -int EDOperandIsMemory(EDOperandRef operand) { - return ((EDOperand*)operand)->isMemory(); -} - -int EDRegisterOperandValue(unsigned *value, EDOperandRef operand) { - if (!((EDOperand*)operand)->isRegister()) - return -1; - *value = ((EDOperand*)operand)->regVal(); - return 0; -} - -int EDImmediateOperandValue(uint64_t *value, EDOperandRef operand) { - if (!((EDOperand*)operand)->isImmediate()) - return -1; - *value = ((EDOperand*)operand)->immediateVal(); - return 0; -} - -int EDEvaluateOperand(uint64_t *result, EDOperandRef operand, - ::EDRegisterReaderCallback regReader, void *arg) { - return ((EDOperand*)operand)->evaluate(*result, regReader, arg); -} - -#ifdef __BLOCKS__ - -struct ByteReaderWrapper { - EDByteBlock_t byteBlock; -}; - -static int readerWrapperCallback(uint8_t *byte, - uint64_t address, - void *arg) { - struct ByteReaderWrapper *wrapper = (struct ByteReaderWrapper *)arg; - return wrapper->byteBlock(byte, address); -} - -unsigned int EDBlockCreateInsts(EDInstRef *insts, - int count, - EDDisassemblerRef disassembler, - EDByteBlock_t byteBlock, - uint64_t address) { - struct ByteReaderWrapper wrapper; - wrapper.byteBlock = byteBlock; - - return EDCreateInsts(insts, - count, - disassembler, - readerWrapperCallback, - address, - (void*)&wrapper); -} - -int EDBlockEvaluateOperand(uint64_t *result, EDOperandRef operand, - EDRegisterBlock_t regBlock) { - return ((EDOperand*)operand)->evaluate(*result, regBlock); -} - -int EDBlockVisitTokens(EDInstRef inst, ::EDTokenVisitor_t visitor) { - return ((EDInst*)inst)->visitTokens((llvm::EDTokenVisitor_t)visitor); -} - -#else - -extern "C" unsigned int EDBlockCreateInsts() { - return 0; -} - -extern "C" int EDBlockEvaluateOperand() { - return -1; -} - -extern "C" int EDBlockVisitTokens() { - return -1; -} - -#endif diff --git a/contrib/llvm/tools/edis/EnhancedDisassembly.exports b/contrib/llvm/tools/edis/EnhancedDisassembly.exports deleted file mode 100644 index 7050f7f..0000000 --- a/contrib/llvm/tools/edis/EnhancedDisassembly.exports +++ /dev/null @@ -1,36 +0,0 @@ -EDGetDisassembler -EDGetRegisterName -EDRegisterIsStackPointer -EDRegisterIsProgramCounter -EDCreateInsts -EDReleaseInst -EDInstByteSize -EDGetInstString -EDInstIsBranch -EDInstIsMove -EDBranchTargetID -EDMoveSourceID -EDMoveTargetID -EDNumTokens -EDGetToken -EDGetTokenString -EDOperandIndexForToken -EDTokenIsWhitespace -EDTokenIsPunctuation -EDTokenIsOpcode -EDTokenIsLiteral -EDTokenIsRegister -EDTokenIsNegativeLiteral -EDLiteralTokenAbsoluteValue -EDRegisterTokenValue -EDNumOperands -EDGetOperand -EDOperandIsRegister -EDOperandIsImmediate -EDOperandIsMemory -EDRegisterOperandValue -EDImmediateOperandValue -EDEvaluateOperand -EDBlockCreateInsts -EDBlockEvaluateOperand -EDBlockVisitTokens diff --git a/contrib/llvm/tools/edis/Makefile b/contrib/llvm/tools/edis/Makefile deleted file mode 100644 index 92484bf..0000000 --- a/contrib/llvm/tools/edis/Makefile +++ /dev/null @@ -1,54 +0,0 @@ -##===- tools/ed/Makefile -----------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL = ../.. -LIBRARYNAME = EnhancedDisassembly -LINK_LIBS_IN_SHARED = 1 -SHARED_LIBRARY = 1 - -EXPORTED_SYMBOL_FILE = $(PROJ_SRC_DIR)/EnhancedDisassembly.exports - -# 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 := mcdisassembler - -# If the X86 target is enabled, link in the asmprinter and disassembler. -ifneq ($(filter $(TARGETS_TO_BUILD), X86),) -LINK_COMPONENTS += x86asmprinter x86disassembler -endif - -# If the X86 target is enabled, link in the asmprinter and disassembler. -ifneq ($(filter $(TARGETS_TO_BUILD), ARM),) -LINK_COMPONENTS += armasmprinter armdisassembler -endif - -include $(LEVEL)/Makefile.common - -ifeq ($(HOST_OS),Darwin) - # extra options to override libtool defaults - LLVMLibsOptions := $(LLVMLibsOptions) \ - -Wl,-dead_strip - - ifdef EDIS_VERSION - LLVMLibsOptions := $(LLVMLibsOptions) -Wl,-current_version -Wl,$(EDIS_VERSION) \ - -Wl,-compatibility_version -Wl,1 - endif - - # Mac OS X 10.4 and earlier tools do not allow a second -install_name on command line - DARWIN_VERS := $(shell echo $(TARGET_TRIPLE) | sed 's/.*darwin\([0-9]*\).*/\1/') - ifneq ($(DARWIN_VERS),8) - LLVMLibsOptions := $(LLVMLibsOptions) \ - -Wl,-install_name \ - -Wl,"@rpath/lib$(LIBRARYNAME)$(SHLIBEXT)" - endif -endif - diff --git a/contrib/llvm/tools/gold/Makefile b/contrib/llvm/tools/gold/Makefile deleted file mode 100644 index 1627346..0000000 --- a/contrib/llvm/tools/gold/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -#===- tools/gold/Makefile ----------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL = ../.. -LIBRARYNAME = LLVMgold - -EXPORTED_SYMBOL_FILE = $(PROJ_SRC_DIR)/gold.exports - -# 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_LIBS_IN_SHARED=1 -SHARED_LIBRARY = 1 -BUILD_ARCHIVE = 0 -LOADABLE_MODULE = 1 - -LINK_COMPONENTS := support system -LIBS += -llto - -# Because off_t is used in the public API, the largefile parts are required for -# ABI compatibility. -CXXFLAGS+=-I$(BINUTILS_INCDIR) -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -lLTO - -include $(LEVEL)/Makefile.common diff --git a/contrib/llvm/tools/gold/README.txt b/contrib/llvm/tools/gold/README.txt deleted file mode 100644 index a906a90..0000000 --- a/contrib/llvm/tools/gold/README.txt +++ /dev/null @@ -1,21 +0,0 @@ -This directory contains a plugin that is designed to work with binutils -gold linker. At present time, this is not the default linker in -binutils, and the default build of gold does not support plugins. - -Obtaining binutils: - - cvs -z 9 -d :pserver:anoncvs@sourceware.org:/cvs/src login - {enter "anoncvs" as the password} - cvs -z 9 -d :pserver:anoncvs@sourceware.org:/cvs/src co binutils - -This will create a src/ directory. Make a build/ directory and from -there configure binutils with "../src/configure --enable-gold --enable-plugins". -Then build binutils with "make all-gold". - -To build the LLVMgold plugin, configure LLVM with the option ---with-binutils-include=/path/to/binutils/src/include/ --enable-pic. To use the -plugin, run "ld-new --plugin /path/to/LLVMgold.so". -Without PIC libLTO and LLVMgold are not being built (because they would fail -link on x86-64 with a relocation error: PIC and non-PIC can't be combined). -As an alternative to passing --enable-pic, you can use 'make ENABLE_PIC=1' in -your entire LLVM build. diff --git a/contrib/llvm/tools/gold/gold-plugin.cpp b/contrib/llvm/tools/gold/gold-plugin.cpp deleted file mode 100644 index 4b58fae..0000000 --- a/contrib/llvm/tools/gold/gold-plugin.cpp +++ /dev/null @@ -1,519 +0,0 @@ -//===-- gold-plugin.cpp - Plugin to gold for Link Time Optimization ------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This is a gold plugin for LLVM. It provides an LLVM implementation of the -// interface described in http://gcc.gnu.org/wiki/whopr/driver . -// -//===----------------------------------------------------------------------===// - -#include "llvm/Config/config.h" -#include "plugin-api.h" - -#include "llvm-c/lto.h" - -#include "llvm/Support/raw_ostream.h" -#include "llvm/System/Errno.h" -#include "llvm/System/Path.h" -#include "llvm/System/Program.h" - -#include <cerrno> -#include <cstdlib> -#include <cstring> -#include <fstream> -#include <list> -#include <vector> - -using namespace llvm; - -namespace { - ld_plugin_status discard_message(int level, const char *format, ...) { - // Die loudly. Recent versions of Gold pass ld_plugin_message as the first - // callback in the transfer vector. This should never be called. - abort(); - } - - ld_plugin_add_symbols add_symbols = NULL; - ld_plugin_get_symbols get_symbols = NULL; - ld_plugin_add_input_file add_input_file = NULL; - ld_plugin_add_input_library add_input_library = NULL; - ld_plugin_set_extra_library_path set_extra_library_path = NULL; - ld_plugin_message message = discard_message; - - int api_version = 0; - int gold_version = 0; - - struct claimed_file { - lto_module_t M; - void *handle; - std::vector<ld_plugin_symbol> syms; - }; - - lto_codegen_model output_type = LTO_CODEGEN_PIC_MODEL_STATIC; - std::string output_name = ""; - std::list<claimed_file> Modules; - std::vector<sys::Path> Cleanup; -} - -namespace options { - enum generate_bc { BC_NO, BC_ALSO, BC_ONLY }; - static bool generate_api_file = false; - static generate_bc generate_bc_file = BC_NO; - static std::string bc_path; - static std::string as_path; - static std::vector<std::string> as_args; - static std::vector<std::string> pass_through; - static std::string extra_library_path; - static std::string triple; - static std::string mcpu; - // Additional options to pass into the code generator. - // Note: This array will contain all plugin options which are not claimed - // as plugin exclusive to pass to the code generator. - // For example, "generate-api-file" and "as"options are for the plugin - // use only and will not be passed. - static std::vector<std::string> extra; - - static void process_plugin_option(const char* opt_) - { - if (opt_ == NULL) - return; - llvm::StringRef opt = opt_; - - if (opt == "generate-api-file") { - generate_api_file = true; - } else if (opt.startswith("mcpu=")) { - mcpu = opt.substr(strlen("mcpu=")); - } else if (opt.startswith("as=")) { - if (!as_path.empty()) { - (*message)(LDPL_WARNING, "Path to as specified twice. " - "Discarding %s", opt_); - } else { - as_path = opt.substr(strlen("as=")); - } - } else if (opt.startswith("as-arg=")) { - llvm::StringRef item = opt.substr(strlen("as-arg=")); - as_args.push_back(item.str()); - } else if (opt.startswith("extra-library-path=")) { - extra_library_path = opt.substr(strlen("extra_library_path=")); - } else if (opt.startswith("pass-through=")) { - llvm::StringRef item = opt.substr(strlen("pass-through=")); - pass_through.push_back(item.str()); - } else if (opt.startswith("mtriple=")) { - triple = opt.substr(strlen("mtriple=")); - } else if (opt == "emit-llvm") { - generate_bc_file = BC_ONLY; - } else if (opt == "also-emit-llvm") { - generate_bc_file = BC_ALSO; - } else if (opt.startswith("also-emit-llvm=")) { - llvm::StringRef path = opt.substr(strlen("also-emit-llvm=")); - generate_bc_file = BC_ALSO; - if (!bc_path.empty()) { - (*message)(LDPL_WARNING, "Path to the output IL file specified twice. " - "Discarding %s", opt_); - } else { - bc_path = path; - } - } else { - // Save this option to pass to the code generator. - extra.push_back(opt); - } - } -} - -static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file, - int *claimed); -static ld_plugin_status all_symbols_read_hook(void); -static ld_plugin_status cleanup_hook(void); - -extern "C" ld_plugin_status onload(ld_plugin_tv *tv); -ld_plugin_status onload(ld_plugin_tv *tv) { - // We're given a pointer to the first transfer vector. We read through them - // until we find one where tv_tag == LDPT_NULL. The REGISTER_* tagged values - // contain pointers to functions that we need to call to register our own - // hooks. The others are addresses of functions we can use to call into gold - // for services. - - bool registeredClaimFile = false; - - for (; tv->tv_tag != LDPT_NULL; ++tv) { - switch (tv->tv_tag) { - case LDPT_API_VERSION: - api_version = tv->tv_u.tv_val; - break; - case LDPT_GOLD_VERSION: // major * 100 + minor - gold_version = tv->tv_u.tv_val; - break; - case LDPT_OUTPUT_NAME: - output_name = tv->tv_u.tv_string; - break; - case LDPT_LINKER_OUTPUT: - switch (tv->tv_u.tv_val) { - case LDPO_REL: // .o - case LDPO_DYN: // .so - output_type = LTO_CODEGEN_PIC_MODEL_DYNAMIC; - break; - case LDPO_EXEC: // .exe - output_type = LTO_CODEGEN_PIC_MODEL_STATIC; - break; - default: - (*message)(LDPL_ERROR, "Unknown output file type %d", - tv->tv_u.tv_val); - return LDPS_ERR; - } - // TODO: add an option to disable PIC. - //output_type = LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC; - break; - case LDPT_OPTION: - options::process_plugin_option(tv->tv_u.tv_string); - break; - case LDPT_REGISTER_CLAIM_FILE_HOOK: { - ld_plugin_register_claim_file callback; - callback = tv->tv_u.tv_register_claim_file; - - if ((*callback)(claim_file_hook) != LDPS_OK) - return LDPS_ERR; - - registeredClaimFile = true; - } break; - case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK: { - ld_plugin_register_all_symbols_read callback; - callback = tv->tv_u.tv_register_all_symbols_read; - - if ((*callback)(all_symbols_read_hook) != LDPS_OK) - return LDPS_ERR; - } break; - case LDPT_REGISTER_CLEANUP_HOOK: { - ld_plugin_register_cleanup callback; - callback = tv->tv_u.tv_register_cleanup; - - if ((*callback)(cleanup_hook) != LDPS_OK) - return LDPS_ERR; - } break; - case LDPT_ADD_SYMBOLS: - add_symbols = tv->tv_u.tv_add_symbols; - break; - case LDPT_GET_SYMBOLS: - get_symbols = tv->tv_u.tv_get_symbols; - break; - case LDPT_ADD_INPUT_FILE: - add_input_file = tv->tv_u.tv_add_input_file; - break; - case LDPT_ADD_INPUT_LIBRARY: - add_input_library = tv->tv_u.tv_add_input_file; - break; - case LDPT_SET_EXTRA_LIBRARY_PATH: - set_extra_library_path = tv->tv_u.tv_set_extra_library_path; - break; - case LDPT_MESSAGE: - message = tv->tv_u.tv_message; - break; - default: - break; - } - } - - if (!registeredClaimFile) { - (*message)(LDPL_ERROR, "register_claim_file not passed to LLVMgold."); - return LDPS_ERR; - } - if (!add_symbols) { - (*message)(LDPL_ERROR, "add_symbols not passed to LLVMgold."); - return LDPS_ERR; - } - - return LDPS_OK; -} - -/// claim_file_hook - called by gold to see whether this file is one that -/// our plugin can handle. We'll try to open it and register all the symbols -/// with add_symbol if possible. -static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file, - int *claimed) { - void *buf = NULL; - if (file->offset) { - // Gold has found what might be IR part-way inside of a file, such as - // an .a archive. - if (lseek(file->fd, file->offset, SEEK_SET) == -1) { - (*message)(LDPL_ERROR, - "Failed to seek to archive member of %s at offset %d: %s\n", - file->name, - file->offset, sys::StrError(errno).c_str()); - return LDPS_ERR; - } - buf = malloc(file->filesize); - if (!buf) { - (*message)(LDPL_ERROR, - "Failed to allocate buffer for archive member of size: %d\n", - file->filesize); - return LDPS_ERR; - } - if (read(file->fd, buf, file->filesize) != file->filesize) { - (*message)(LDPL_ERROR, - "Failed to read archive member of %s at offset %d: %s\n", - file->name, - file->offset, - sys::StrError(errno).c_str()); - free(buf); - return LDPS_ERR; - } - if (!lto_module_is_object_file_in_memory(buf, file->filesize)) { - free(buf); - return LDPS_OK; - } - } else if (!lto_module_is_object_file(file->name)) - return LDPS_OK; - - *claimed = 1; - Modules.resize(Modules.size() + 1); - claimed_file &cf = Modules.back(); - - cf.M = buf ? lto_module_create_from_memory(buf, file->filesize) : - lto_module_create(file->name); - free(buf); - if (!cf.M) { - (*message)(LDPL_ERROR, "Failed to create LLVM module: %s", - lto_get_error_message()); - return LDPS_ERR; - } - - if (!options::triple.empty()) - lto_module_set_target_triple(cf.M, options::triple.c_str()); - - cf.handle = file->handle; - unsigned sym_count = lto_module_get_num_symbols(cf.M); - cf.syms.reserve(sym_count); - - for (unsigned i = 0; i != sym_count; ++i) { - lto_symbol_attributes attrs = lto_module_get_symbol_attribute(cf.M, i); - if ((attrs & LTO_SYMBOL_SCOPE_MASK) == LTO_SYMBOL_SCOPE_INTERNAL) - continue; - - cf.syms.push_back(ld_plugin_symbol()); - ld_plugin_symbol &sym = cf.syms.back(); - sym.name = const_cast<char *>(lto_module_get_symbol_name(cf.M, i)); - sym.version = NULL; - - int scope = attrs & LTO_SYMBOL_SCOPE_MASK; - switch (scope) { - case LTO_SYMBOL_SCOPE_HIDDEN: - sym.visibility = LDPV_HIDDEN; - break; - case LTO_SYMBOL_SCOPE_PROTECTED: - sym.visibility = LDPV_PROTECTED; - break; - case 0: // extern - case LTO_SYMBOL_SCOPE_DEFAULT: - sym.visibility = LDPV_DEFAULT; - break; - default: - (*message)(LDPL_ERROR, "Unknown scope attribute: %d", scope); - return LDPS_ERR; - } - - int definition = attrs & LTO_SYMBOL_DEFINITION_MASK; - switch (definition) { - case LTO_SYMBOL_DEFINITION_REGULAR: - sym.def = LDPK_DEF; - break; - case LTO_SYMBOL_DEFINITION_UNDEFINED: - sym.def = LDPK_UNDEF; - break; - case LTO_SYMBOL_DEFINITION_TENTATIVE: - sym.def = LDPK_COMMON; - break; - case LTO_SYMBOL_DEFINITION_WEAK: - sym.def = LDPK_WEAKDEF; - break; - case LTO_SYMBOL_DEFINITION_WEAKUNDEF: - sym.def = LDPK_WEAKUNDEF; - break; - default: - (*message)(LDPL_ERROR, "Unknown definition attribute: %d", definition); - return LDPS_ERR; - } - - // LLVM never emits COMDAT. - sym.size = 0; - sym.comdat_key = NULL; - - sym.resolution = LDPR_UNKNOWN; - } - - cf.syms.reserve(cf.syms.size()); - - if (!cf.syms.empty()) { - if ((*add_symbols)(cf.handle, cf.syms.size(), &cf.syms[0]) != LDPS_OK) { - (*message)(LDPL_ERROR, "Unable to add symbols!"); - return LDPS_ERR; - } - } - - return LDPS_OK; -} - -/// all_symbols_read_hook - gold informs us that all symbols have been read. -/// At this point, we use get_symbols to see if any of our definitions have -/// been overridden by a native object file. Then, perform optimization and -/// codegen. -static ld_plugin_status all_symbols_read_hook(void) { - lto_code_gen_t cg = lto_codegen_create(); - - for (std::list<claimed_file>::iterator I = Modules.begin(), - E = Modules.end(); I != E; ++I) - lto_codegen_add_module(cg, I->M); - - std::ofstream api_file; - if (options::generate_api_file) { - api_file.open("apifile.txt", std::ofstream::out | std::ofstream::trunc); - if (!api_file.is_open()) { - (*message)(LDPL_FATAL, "Unable to open apifile.txt for writing."); - abort(); - } - } - - // If we don't preserve any symbols, libLTO will assume that all symbols are - // needed. Keep all symbols unless we're producing a final executable. - bool anySymbolsPreserved = false; - for (std::list<claimed_file>::iterator I = Modules.begin(), - E = Modules.end(); I != E; ++I) { - (*get_symbols)(I->handle, I->syms.size(), &I->syms[0]); - for (unsigned i = 0, e = I->syms.size(); i != e; i++) { - if (I->syms[i].resolution == LDPR_PREVAILING_DEF) { - lto_codegen_add_must_preserve_symbol(cg, I->syms[i].name); - anySymbolsPreserved = true; - - if (options::generate_api_file) - api_file << I->syms[i].name << "\n"; - } - } - } - - if (options::generate_api_file) - api_file.close(); - - if (!anySymbolsPreserved) { - // All of the IL is unnecessary! - lto_codegen_dispose(cg); - return LDPS_OK; - } - - lto_codegen_set_pic_model(cg, output_type); - lto_codegen_set_debug_model(cg, LTO_DEBUG_MODEL_DWARF); - if (!options::as_path.empty()) { - sys::Path p = sys::Program::FindProgramByName(options::as_path); - lto_codegen_set_assembler_path(cg, p.c_str()); - } - if (!options::as_args.empty()) { - std::vector<const char *> as_args_p; - for (std::vector<std::string>::iterator I = options::as_args.begin(), - E = options::as_args.end(); I != E; ++I) { - as_args_p.push_back(I->c_str()); - } - lto_codegen_set_assembler_args(cg, &as_args_p[0], as_args_p.size()); - } - if (!options::mcpu.empty()) - lto_codegen_set_cpu(cg, options::mcpu.c_str()); - - // Pass through extra options to the code generator. - if (!options::extra.empty()) { - for (std::vector<std::string>::iterator it = options::extra.begin(); - it != options::extra.end(); ++it) { - lto_codegen_debug_options(cg, (*it).c_str()); - } - } - - - if (options::generate_bc_file != options::BC_NO) { - std::string path; - if (options::generate_bc_file == options::BC_ONLY) - path = output_name; - else if (!options::bc_path.empty()) - path = options::bc_path; - else - path = output_name + ".bc"; - bool err = lto_codegen_write_merged_modules(cg, path.c_str()); - if (err) - (*message)(LDPL_FATAL, "Failed to write the output file."); - if (options::generate_bc_file == options::BC_ONLY) - exit(0); - } - size_t bufsize = 0; - const char *buffer = static_cast<const char *>(lto_codegen_compile(cg, - &bufsize)); - - std::string ErrMsg; - - sys::Path uniqueObjPath("/tmp/llvmgold.o"); - if (uniqueObjPath.createTemporaryFileOnDisk(true, &ErrMsg)) { - (*message)(LDPL_ERROR, "%s", ErrMsg.c_str()); - return LDPS_ERR; - } - tool_output_file objFile(uniqueObjPath.c_str(), ErrMsg, - raw_fd_ostream::F_Binary); - if (!ErrMsg.empty()) { - (*message)(LDPL_ERROR, "%s", ErrMsg.c_str()); - return LDPS_ERR; - } - - objFile.os().write(buffer, bufsize); - objFile.os().close(); - if (objFile.os().has_error()) { - (*message)(LDPL_ERROR, "Error writing output file '%s'", - uniqueObjPath.c_str()); - objFile.os().clear_error(); - return LDPS_ERR; - } - objFile.keep(); - - lto_codegen_dispose(cg); - - if ((*add_input_file)(uniqueObjPath.c_str()) != LDPS_OK) { - (*message)(LDPL_ERROR, "Unable to add .o file to the link."); - (*message)(LDPL_ERROR, "File left behind in: %s", uniqueObjPath.c_str()); - return LDPS_ERR; - } - - if (!options::extra_library_path.empty() && - set_extra_library_path(options::extra_library_path.c_str()) != LDPS_OK) { - (*message)(LDPL_ERROR, "Unable to set the extra library path."); - return LDPS_ERR; - } - - for (std::vector<std::string>::iterator i = options::pass_through.begin(), - e = options::pass_through.end(); - i != e; ++i) { - std::string &item = *i; - const char *item_p = item.c_str(); - if (llvm::StringRef(item).startswith("-l")) { - if (add_input_library(item_p + 2) != LDPS_OK) { - (*message)(LDPL_ERROR, "Unable to add library to the link."); - return LDPS_ERR; - } - } else { - if (add_input_file(item_p) != LDPS_OK) { - (*message)(LDPL_ERROR, "Unable to add .o file to the link."); - return LDPS_ERR; - } - } - } - - Cleanup.push_back(uniqueObjPath); - - return LDPS_OK; -} - -static ld_plugin_status cleanup_hook(void) { - std::string ErrMsg; - - for (int i = 0, e = Cleanup.size(); i != e; ++i) - if (Cleanup[i].eraseFromDisk(false, &ErrMsg)) - (*message)(LDPL_ERROR, "Failed to delete '%s': %s", Cleanup[i].c_str(), - ErrMsg.c_str()); - - return LDPS_OK; -} diff --git a/contrib/llvm/tools/gold/gold.exports b/contrib/llvm/tools/gold/gold.exports deleted file mode 100644 index 277a33a..0000000 --- a/contrib/llvm/tools/gold/gold.exports +++ /dev/null @@ -1 +0,0 @@ -onload diff --git a/contrib/llvm/tools/llc/CMakeLists.txt b/contrib/llvm/tools/llc/CMakeLists.txt deleted file mode 100644 index 683f298..0000000 --- a/contrib/llvm/tools/llc/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} bitreader asmparser) - -add_llvm_tool(llc - llc.cpp - ) diff --git a/contrib/llvm/tools/llc/Makefile b/contrib/llvm/tools/llc/Makefile deleted file mode 100644 index 7319aad..0000000 --- a/contrib/llvm/tools/llc/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -#===- tools/llc/Makefile -----------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL = ../.. -TOOLNAME = 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 asmparser - -include $(LLVM_SRC_ROOT)/Makefile.rules - diff --git a/contrib/llvm/tools/llc/llc.cpp b/contrib/llvm/tools/llc/llc.cpp deleted file mode 100644 index 8bcc2d8..0000000 --- a/contrib/llvm/tools/llc/llc.cpp +++ /dev/null @@ -1,330 +0,0 @@ -//===-- llc.cpp - Implement the LLVM Native Code Generator ----------------===// -// -// The LLVM Compiler Infrastructure -// -// This file 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/LLVMContext.h" -#include "llvm/Module.h" -#include "llvm/PassManager.h" -#include "llvm/Pass.h" -#include "llvm/ADT/Triple.h" -#include "llvm/Support/IRReader.h" -#include "llvm/CodeGen/LinkAllAsmWriterComponents.h" -#include "llvm/CodeGen/LinkAllCodegenComponents.h" -#include "llvm/Config/config.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/FormattedStream.h" -#include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/PluginLoader.h" -#include "llvm/Support/PrettyStackTrace.h" -#include "llvm/System/Host.h" -#include "llvm/System/Signals.h" -#include "llvm/Target/SubtargetFeature.h" -#include "llvm/Target/TargetData.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetRegistry.h" -#include "llvm/Target/TargetSelect.h" -#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")); - -// Determine optimization level. -static cl::opt<char> -OptLevel("O", - cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] " - "(default = '-O2')"), - cl::Prefix, - cl::ZeroOrMore, - cl::init(' ')); - -static cl::opt<std::string> -TargetTriple("mtriple", cl::desc("Override target triple for module")); - -static cl::opt<std::string> -MArch("march", cl::desc("Architecture to generate code for (see --version)")); - -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,...")); - -static cl::opt<bool> -RelaxAll("mc-relax-all", - cl::desc("When used with filetype=obj, " - "relax all fixups in the emitted object file")); - -cl::opt<TargetMachine::CodeGenFileType> -FileType("filetype", cl::init(TargetMachine::CGFT_AssemblyFile), - cl::desc("Choose a file type (not all types are supported by all targets):"), - cl::values( - clEnumValN(TargetMachine::CGFT_AssemblyFile, "asm", - "Emit an assembly ('.s') file"), - clEnumValN(TargetMachine::CGFT_ObjectFile, "obj", - "Emit a native object ('.o') file [experimental]"), - clEnumValN(TargetMachine::CGFT_Null, "null", - "Emit nothing, for performance testing"), - clEnumValEnd)); - -cl::opt<bool> NoVerify("disable-verify", cl::Hidden, - cl::desc("Do not verify input module")); - - -static cl::opt<bool> -DisableRedZone("disable-red-zone", - cl::desc("Do not emit code that uses the red zone."), - cl::init(false)); - -static cl::opt<bool> -NoImplicitFloats("no-implicit-float", - cl::desc("Don't generate implicit floating point instructions (x86-only)"), - cl::init(false)); - -// 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') || - (IFN[Len-2] == 'l' && IFN[Len-1] == 'l'))) { - outputFilename = std::string(IFN.begin(), IFN.end()-3); // s/.bc/.s/ - } else { - outputFilename = IFN; - } - return outputFilename; -} - -static tool_output_file *GetOutputStream(const char *TargetName, - Triple::OSType OS, - const char *ProgName) { - // If we don't yet have an output filename, make one. - if (OutputFilename.empty()) { - if (InputFilename == "-") - OutputFilename = "-"; - else { - OutputFilename = GetFileNameRoot(InputFilename); - - switch (FileType) { - default: assert(0 && "Unknown file type"); - case TargetMachine::CGFT_AssemblyFile: - if (TargetName[0] == 'c') { - if (TargetName[1] == 0) - OutputFilename += ".cbe.c"; - else if (TargetName[1] == 'p' && TargetName[2] == 'p') - OutputFilename += ".cpp"; - else - OutputFilename += ".s"; - } else - OutputFilename += ".s"; - break; - case TargetMachine::CGFT_ObjectFile: - if (OS == Triple::Win32) - OutputFilename += ".obj"; - else - OutputFilename += ".o"; - break; - case TargetMachine::CGFT_Null: - OutputFilename += ".null"; - break; - } - } - } - - // Decide if we need "binary" output. - bool Binary = false; - switch (FileType) { - default: assert(0 && "Unknown file type"); - case TargetMachine::CGFT_AssemblyFile: - break; - case TargetMachine::CGFT_ObjectFile: - case TargetMachine::CGFT_Null: - Binary = true; - break; - } - - // Open the file. - std::string error; - unsigned OpenFlags = 0; - if (Binary) OpenFlags |= raw_fd_ostream::F_Binary; - tool_output_file *FDOut = new tool_output_file(OutputFilename.c_str(), error, - OpenFlags); - if (!error.empty()) { - errs() << error << '\n'; - delete FDOut; - return 0; - } - - return FDOut; -} - -// main - Entry point for the llc compiler. -// -int main(int argc, char **argv) { - sys::PrintStackTraceOnErrorSignal(); - PrettyStackTraceProgram X(argc, argv); - - // Enable debug stream buffering. - EnableDebugBuffering = true; - - LLVMContext &Context = getGlobalContext(); - llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. - - // Initialize targets first, so that --version shows registered targets. - InitializeAllTargets(); - InitializeAllAsmPrinters(); - InitializeAllAsmParsers(); - - cl::ParseCommandLineOptions(argc, argv, "llvm system compiler\n"); - - // Load the module to be compiled... - SMDiagnostic Err; - std::auto_ptr<Module> M; - - M.reset(ParseIRFile(InputFilename, Err, Context)); - if (M.get() == 0) { - Err.Print(argv[0], errs()); - return 1; - } - Module &mod = *M.get(); - - // If we are supposed to override the target triple, do so now. - if (!TargetTriple.empty()) - mod.setTargetTriple(Triple::normalize(TargetTriple)); - - Triple TheTriple(mod.getTargetTriple()); - if (TheTriple.getTriple().empty()) - TheTriple.setTriple(sys::getHostTriple()); - - // Allocate target machine. First, check whether the user has explicitly - // specified an architecture to compile for. If so we have to look it up by - // name, because it might be a backend that has no mapping to a target triple. - const Target *TheTarget = 0; - if (!MArch.empty()) { - for (TargetRegistry::iterator it = TargetRegistry::begin(), - ie = TargetRegistry::end(); it != ie; ++it) { - if (MArch == it->getName()) { - TheTarget = &*it; - break; - } - } - - if (!TheTarget) { - errs() << argv[0] << ": error: invalid target '" << MArch << "'.\n"; - return 1; - } - - // Adjust the triple to match (if known), otherwise stick with the - // module/host triple. - Triple::ArchType Type = Triple::getArchTypeForLLVMName(MArch); - if (Type != Triple::UnknownArch) - TheTriple.setArch(Type); - } else { - std::string Err; - TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), Err); - if (TheTarget == 0) { - errs() << 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(TheTarget->createTargetMachine(TheTriple.getTriple(), FeaturesStr)); - assert(target.get() && "Could not allocate target machine!"); - TargetMachine &Target = *target.get(); - - // Figure out where we are going to send the output... - OwningPtr<tool_output_file> Out - (GetOutputStream(TheTarget->getName(), TheTriple.getOS(), argv[0])); - if (!Out) return 1; - - CodeGenOpt::Level OLvl = CodeGenOpt::Default; - switch (OptLevel) { - default: - errs() << argv[0] << ": invalid optimization level.\n"; - return 1; - case ' ': break; - case '0': OLvl = CodeGenOpt::None; break; - case '1': OLvl = CodeGenOpt::Less; break; - case '2': OLvl = CodeGenOpt::Default; break; - case '3': OLvl = CodeGenOpt::Aggressive; break; - } - - // Build up all of the passes that we want to do to the module. - PassManager PM; - - // Add the target data from the target machine, if it exists, or the module. - if (const TargetData *TD = Target.getTargetData()) - PM.add(new TargetData(*TD)); - else - PM.add(new TargetData(&mod)); - - // Override default to generate verbose assembly. - Target.setAsmVerbosityDefault(true); - - if (RelaxAll) { - if (FileType != TargetMachine::CGFT_ObjectFile) - errs() << argv[0] - << ": warning: ignoring -mc-relax-all because filetype != obj"; - else - Target.setMCRelaxAll(true); - } - - { - formatted_raw_ostream FOS(Out->os()); - - // Ask the target to add backend passes as necessary. - if (Target.addPassesToEmitFile(PM, FOS, FileType, OLvl, NoVerify)) { - errs() << argv[0] << ": target does not support generation of this" - << " file type!\n"; - return 1; - } - - PM.run(mod); - } - - // Declare success. - Out->keep(); - - return 0; -} diff --git a/contrib/llvm/tools/lli/CMakeLists.txt b/contrib/llvm/tools/lli/CMakeLists.txt deleted file mode 100644 index ce70d46e..0000000 --- a/contrib/llvm/tools/lli/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -set(LLVM_LINK_COMPONENTS jit interpreter nativecodegen bitreader selectiondag) - -add_llvm_tool(lli - lli.cpp - ) diff --git a/contrib/llvm/tools/lli/Makefile b/contrib/llvm/tools/lli/Makefile deleted file mode 100644 index 8f6eeed..0000000 --- a/contrib/llvm/tools/lli/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -##===- tools/lli/Makefile ------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL := ../.. -TOOLNAME := lli -LINK_COMPONENTS := jit interpreter nativecodegen bitreader selectiondag - -# Enable JIT support -include $(LEVEL)/Makefile.common diff --git a/contrib/llvm/tools/lli/lli.cpp b/contrib/llvm/tools/lli/lli.cpp deleted file mode 100644 index 4c37780..0000000 --- a/contrib/llvm/tools/lli/lli.cpp +++ /dev/null @@ -1,254 +0,0 @@ -//===- lli.cpp - LLVM Interpreter / Dynamic compiler ----------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file 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 interpreter if no JIT is available for this platform. -// -//===----------------------------------------------------------------------===// - -#include "llvm/LLVMContext.h" -#include "llvm/Module.h" -#include "llvm/Type.h" -#include "llvm/ADT/Triple.h" -#include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/CodeGen/LinkAllCodegenComponents.h" -#include "llvm/ExecutionEngine/GenericValue.h" -#include "llvm/ExecutionEngine/Interpreter.h" -#include "llvm/ExecutionEngine/JIT.h" -#include "llvm/ExecutionEngine/JITEventListener.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/PluginLoader.h" -#include "llvm/Support/PrettyStackTrace.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/System/Process.h" -#include "llvm/System/Signals.h" -#include "llvm/Target/TargetSelect.h" -#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)); - - // Determine optimization level. - cl::opt<char> - OptLevel("O", - cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] " - "(default = '-O2')"), - cl::Prefix, - cl::ZeroOrMore, - cl::init(' ')); - - cl::opt<std::string> - TargetTriple("mtriple", cl::desc("Override target triple for module")); - - cl::opt<std::string> - MArch("march", - cl::desc("Architecture to generate assembly for (see --version)")); - - cl::opt<std::string> - MCPU("mcpu", - cl::desc("Target a specific cpu type (-mcpu=help for details)"), - cl::value_desc("cpu-name"), - cl::init("")); - - 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<std::string> - EntryFunc("entry-function", - cl::desc("Specify the entry function (default = 'main') " - "of the executable"), - cl::value_desc("function"), - cl::init("main")); - - 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")); - - cl::opt<bool> - NoLazyCompilation("disable-lazy-compilation", - cl::desc("Disable JIT lazy compilation"), - cl::init(false)); -} - -static ExecutionEngine *EE = 0; - -static void do_shutdown() { - delete EE; - llvm_shutdown(); -} - -//===----------------------------------------------------------------------===// -// main Driver function -// -int main(int argc, char **argv, char * const *envp) { - sys::PrintStackTraceOnErrorSignal(); - PrettyStackTraceProgram X(argc, argv); - - LLVMContext &Context = getGlobalContext(); - atexit(do_shutdown); // Call llvm_shutdown() on exit. - - // If we have a native target, initialize it to ensure it is linked in and - // usable by the JIT. - InitializeNativeTarget(); - - cl::ParseCommandLineOptions(argc, argv, - "llvm interpreter & dynamic compiler\n"); - - // If the user doesn't want core files, disable them. - if (DisableCoreFiles) - sys::Process::PreventCoreFiles(); - - // Load the bitcode... - std::string ErrorMsg; - Module *Mod = NULL; - if (MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFile,&ErrorMsg)){ - Mod = getLazyBitcodeModule(Buffer, Context, &ErrorMsg); - if (!Mod) delete Buffer; - } - - if (!Mod) { - errs() << argv[0] << ": error loading program '" << InputFile << "': " - << ErrorMsg << "\n"; - exit(1); - } - - // If not jitting lazily, load the whole bitcode file eagerly too. - if (NoLazyCompilation) { - if (Mod->MaterializeAllPermanently(&ErrorMsg)) { - errs() << argv[0] << ": bitcode didn't read correctly.\n"; - errs() << "Reason: " << ErrorMsg << "\n"; - exit(1); - } - } - - EngineBuilder builder(Mod); - builder.setMArch(MArch); - builder.setMCPU(MCPU); - builder.setMAttrs(MAttrs); - builder.setErrorStr(&ErrorMsg); - builder.setEngineKind(ForceInterpreter - ? EngineKind::Interpreter - : EngineKind::JIT); - - // If we are supposed to override the target triple, do so now. - if (!TargetTriple.empty()) - Mod->setTargetTriple(Triple::normalize(TargetTriple)); - - CodeGenOpt::Level OLvl = CodeGenOpt::Default; - switch (OptLevel) { - default: - errs() << argv[0] << ": invalid optimization level.\n"; - return 1; - case ' ': break; - case '0': OLvl = CodeGenOpt::None; break; - case '1': OLvl = CodeGenOpt::Less; break; - case '2': OLvl = CodeGenOpt::Default; break; - case '3': OLvl = CodeGenOpt::Aggressive; break; - } - builder.setOptLevel(OLvl); - - EE = builder.create(); - if (!EE) { - if (!ErrorMsg.empty()) - errs() << argv[0] << ": error creating EE: " << ErrorMsg << "\n"; - else - errs() << argv[0] << ": unknown error creating EE!\n"; - exit(1); - } - - EE->RegisterJITEventListener(createOProfileJITEventListener()); - - EE->DisableLazyCompilation(NoLazyCompilation); - - // 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 (StringRef(InputFile).endswith(".bc")) - 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 *EntryFn = Mod->getFunction(EntryFunc); - if (!EntryFn) { - errs() << '\'' << EntryFunc << "\' 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::getVoidTy(Context), - Type::getInt32Ty(Context), - NULL); - - // Reset errno to zero on entry to main. - errno = 0; - - // Run static constructors. - EE->runStaticConstructorsDestructors(false); - - if (NoLazyCompilation) { - for (Module::iterator I = Mod->begin(), E = Mod->end(); I != E; ++I) { - Function *Fn = &*I; - if (Fn != EntryFn && !Fn->isDeclaration()) - EE->getPointerToFunction(Fn); - } - } - - // Run main. - int Result = EE->runFunctionAsMain(EntryFn, 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); - errs() << "ERROR: exit(" << Result << ") returned!\n"; - abort(); - } else { - errs() << "ERROR: exit defined with wrong prototype!\n"; - abort(); - } -} diff --git a/contrib/llvm/tools/llvm-ar/CMakeLists.txt b/contrib/llvm/tools/llvm-ar/CMakeLists.txt deleted file mode 100644 index c8b0b72..0000000 --- a/contrib/llvm/tools/llvm-ar/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -set(LLVM_LINK_COMPONENTS archive) -set(LLVM_REQUIRES_EH 1) - -add_llvm_tool(llvm-ar - llvm-ar.cpp - ) - -# TODO: Support check-local. diff --git a/contrib/llvm/tools/llvm-ar/Makefile b/contrib/llvm/tools/llvm-ar/Makefile deleted file mode 100644 index e4fe4e8..0000000 --- a/contrib/llvm/tools/llvm-ar/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -##===- tools/llvm-ar/Makefile ------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -LEVEL = ../.. - -TOOLNAME = llvm-ar -LINK_COMPONENTS = archive -REQUIRES_EH := 1 - -# This tool has no plugins, optimize startup time. -TOOL_NO_EXPORTS = 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/contrib/llvm/tools/llvm-ar/llvm-ar.cpp b/contrib/llvm/tools/llvm-ar/llvm-ar.cpp deleted file mode 100644 index 021a369..0000000 --- a/contrib/llvm/tools/llvm-ar/llvm-ar.cpp +++ /dev/null @@ -1,779 +0,0 @@ -//===-- llvm-ar.cpp - LLVM archive librarian utility ----------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file 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/LLVMContext.h" -#include "llvm/Module.h" -#include "llvm/Bitcode/Archive.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/PrettyStackTrace.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/System/Signals.h" -#include <iostream> -#include <algorithm> -#include <iomanip> -#include <memory> -#include <fstream> -using namespace llvm; - -// Option for compatibility with AIX, 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 'q': ++NumOperations; Operation = QuickAppend; 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().str() << "\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().str().substr(4); - std::cout << " " << I->getPath().str() << "\n"; - } else { - std::cout << I->getPath().str() << "\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().str()) { - 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->str()); - 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().str()) { - 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().str()) - insert_spot = I; - else if (AddAfter && RelPos == I->getPath().str()) { - 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) { - // Print a stack trace if we signal out. - sys::PrintStackTraceOnErrorSignal(); - PrettyStackTraceProgram X(argc, argv); - LLVMContext &Context = getGlobalContext(); - llvm_shutdown_obj Y; // 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" - ); - - 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) - errs() << argv[0] << ": creating " << ArchivePath.str() << "\n"; - TheArchive = Archive::CreateEmpty(ArchivePath, Context); - TheArchive->writeToDisk(); - } else { - std::string Error; - TheArchive = Archive::OpenAndLoad(ArchivePath, Context, &Error); - if (TheArchive == 0) { - errs() << argv[0] << ": error loading '" << ArchivePath.str() << "': " - << 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: - errs() << argv[0] << ": No operation was selected.\n"; - break; - } - if (haveError) { - errs() << 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. - errs() << 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. - errs() << argv[0] << ": " << msg << "\n"; - exitCode = 2; - } catch (...) { - // This really shouldn't happen, but just in case .... - errs() << argv[0] << ": An unexpected unknown exception occurred.\n"; - exitCode = 3; - } - - // Return result code back to operating system. - return exitCode; -} diff --git a/contrib/llvm/tools/llvm-as/CMakeLists.txt b/contrib/llvm/tools/llvm-as/CMakeLists.txt deleted file mode 100644 index eef4a13..0000000 --- a/contrib/llvm/tools/llvm-as/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -set(LLVM_LINK_COMPONENTS asmparser bitwriter) -set(LLVM_REQUIRES_EH 1) - -add_llvm_tool(llvm-as - llvm-as.cpp - ) diff --git a/contrib/llvm/tools/llvm-as/Makefile b/contrib/llvm/tools/llvm-as/Makefile deleted file mode 100644 index e1e5853..0000000 --- a/contrib/llvm/tools/llvm-as/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -##===- tools/llvm-as/Makefile ------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL = ../.. -TOOLNAME = llvm-as -LINK_COMPONENTS := asmparser bitwriter - -# This tool has no plugins, optimize startup time. -TOOL_NO_EXPORTS = 1 - -include $(LEVEL)/Makefile.common diff --git a/contrib/llvm/tools/llvm-as/llvm-as.cpp b/contrib/llvm/tools/llvm-as/llvm-as.cpp deleted file mode 100644 index 1eaa4b3..0000000 --- a/contrib/llvm/tools/llvm-as/llvm-as.cpp +++ /dev/null @@ -1,119 +0,0 @@ -//===--- llvm-as.cpp - The low-level LLVM assembler -----------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file 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/LLVMContext.h" -#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/PrettyStackTrace.h" -#include "llvm/Support/SourceMgr.h" -#include "llvm/Support/SystemUtils.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/System/Signals.h" -#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("Enable binary output on terminals")); - -static cl::opt<bool> -DisableOutput("disable-output", cl::desc("Disable output"), cl::init(false)); - -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!)")); - -static void WriteOutputFile(const Module *M) { - // Infer the output filename if needed. - if (OutputFilename.empty()) { - if (InputFilename == "-") { - OutputFilename = "-"; - } 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"; - } - } - - std::string ErrorInfo; - OwningPtr<tool_output_file> Out - (new tool_output_file(OutputFilename.c_str(), ErrorInfo, - raw_fd_ostream::F_Binary)); - if (!ErrorInfo.empty()) { - errs() << ErrorInfo << '\n'; - exit(1); - } - - if (Force || !CheckBitcodeOutputToConsole(Out->os(), true)) - WriteBitcodeToFile(M, Out->os()); - - // Declare success. - Out->keep(); -} - -int main(int argc, char **argv) { - // Print a stack trace if we signal out. - sys::PrintStackTraceOnErrorSignal(); - PrettyStackTraceProgram X(argc, argv); - LLVMContext &Context = getGlobalContext(); - llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. - cl::ParseCommandLineOptions(argc, argv, "llvm .ll -> .bc assembler\n"); - - // Parse the file now... - SMDiagnostic Err; - std::auto_ptr<Module> M(ParseAssemblyFile(InputFilename, Err, Context)); - if (M.get() == 0) { - Err.Print(argv[0], errs()); - return 1; - } - - if (!DisableVerify) { - std::string Err; - if (verifyModule(*M.get(), ReturnStatusAction, &Err)) { - errs() << argv[0] - << ": assembly parsed, but does not verify as correct!\n"; - errs() << Err; - return 1; - } - } - - if (DumpAsm) errs() << "Here's the assembly:\n" << *M.get(); - - if (!DisableOutput) - WriteOutputFile(M.get()); - - return 0; -} diff --git a/contrib/llvm/tools/llvm-bcanalyzer/CMakeLists.txt b/contrib/llvm/tools/llvm-bcanalyzer/CMakeLists.txt deleted file mode 100644 index 732bc32..0000000 --- a/contrib/llvm/tools/llvm-bcanalyzer/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -set(LLVM_LINK_COMPONENTS bitreader) -set(LLVM_REQUIRES_EH 1) - -add_llvm_tool(llvm-bcanalyzer - llvm-bcanalyzer.cpp - ) diff --git a/contrib/llvm/tools/llvm-bcanalyzer/Makefile b/contrib/llvm/tools/llvm-bcanalyzer/Makefile deleted file mode 100644 index 488387d..0000000 --- a/contrib/llvm/tools/llvm-bcanalyzer/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -##===- tools/llvm-bcanalyzer/Makefile ----------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -LEVEL = ../.. - -TOOLNAME = llvm-bcanalyzer -LINK_COMPONENTS := bitreader - -# This tool has no plugins, optimize startup time. -TOOL_NO_EXPORTS = 1 - -include $(LEVEL)/Makefile.common diff --git a/contrib/llvm/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp b/contrib/llvm/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp deleted file mode 100644 index 9c0d675..0000000 --- a/contrib/llvm/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp +++ /dev/null @@ -1,625 +0,0 @@ -//===-- llvm-bcanalyzer.cpp - Bitcode Analyzer --------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file 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/Bitcode/ReaderWriter.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/Format.h" -#include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/PrettyStackTrace.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/System/Signals.h" -#include <cstdio> -#include <map> -#include <algorithm> -using namespace llvm; - -static cl::opt<std::string> - InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-")); - -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, - const BitstreamReader &StreamFile) { - // Standard blocks for all bitcode files. - if (BlockID < bitc::FIRST_APPLICATION_BLOCKID) { - if (BlockID == bitc::BLOCKINFO_BLOCK_ID) - return "BLOCKINFO_BLOCK"; - return 0; - } - - // Check to see if we have a blockinfo record for this block, with a name. - if (const BitstreamReader::BlockInfo *Info = - StreamFile.getBlockInfo(BlockID)) { - if (!Info->Name.empty()) - return Info->Name.c_str(); - } - - - 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"; - case bitc::METADATA_BLOCK_ID: return "METADATA_BLOCK"; - case bitc::METADATA_ATTACHMENT_ID: return "METADATA_ATTACHMENT_BLOCK"; - } -} - -/// GetCodeName - Return a symbolic code name if known, otherwise return -/// null. -static const char *GetCodeName(unsigned CodeID, unsigned BlockID, - const BitstreamReader &StreamFile) { - // 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::BLOCKINFO_CODE_SETBID: return "SETBID"; - case bitc::BLOCKINFO_CODE_BLOCKNAME: return "BLOCKNAME"; - case bitc::BLOCKINFO_CODE_SETRECORDNAME: return "SETRECORDNAME"; - } - } - return 0; - } - - // Check to see if we have a blockinfo record for this record, with a name. - if (const BitstreamReader::BlockInfo *Info = - StreamFile.getBlockInfo(BlockID)) { - for (unsigned i = 0, e = Info->RecordNames.size(); i != e; ++i) - if (Info->RecordNames[i].first == CodeID) - return Info->RecordNames[i].second.c_str(); - } - - - 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::MODULE_CODE_GCNAME: return "GCNAME"; - } - 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::TYPE_CODE_X86_FP80: return "X86_FP80"; - case bitc::TYPE_CODE_FP128: return "FP128"; - case bitc::TYPE_CODE_PPC_FP128: return "PPC_FP128"; - case bitc::TYPE_CODE_METADATA: return "METADATA"; - } - - 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_INBOUNDS_GEP: return "CE_INBOUNDS_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::CST_CODE_CE_SHUFVEC_EX: return "CE_SHUFVEC_EX"; - } - 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_INBOUNDS_GEP: return "INST_INBOUNDS_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::FUNC_CODE_INST_STORE2: return "INST_STORE2"; - case bitc::FUNC_CODE_INST_GETRESULT: return "INST_GETRESULT"; - case bitc::FUNC_CODE_INST_EXTRACTVAL: return "INST_EXTRACTVAL"; - case bitc::FUNC_CODE_INST_INSERTVAL: return "INST_INSERTVAL"; - case bitc::FUNC_CODE_INST_CMP2: return "INST_CMP2"; - case bitc::FUNC_CODE_INST_VSELECT: return "INST_VSELECT"; - case bitc::FUNC_CODE_DEBUG_LOC: return "DEBUG_LOC"; - case bitc::FUNC_CODE_DEBUG_LOC_AGAIN: return "DEBUG_LOC_AGAIN"; - case bitc::FUNC_CODE_INST_CALL2: return "INST_CALL2"; - case bitc::FUNC_CODE_DEBUG_LOC2: return "DEBUG_LOC2"; - } - 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"; - } - case bitc::METADATA_ATTACHMENT_ID: - switch(CodeID) { - default:return 0; - case bitc::METADATA_ATTACHMENT: return "METADATA_ATTACHMENT"; - } - case bitc::METADATA_BLOCK_ID: - switch(CodeID) { - default:return 0; - case bitc::METADATA_STRING: return "METADATA_STRING"; - case bitc::METADATA_NODE: return "METADATA_NODE"; - case bitc::METADATA_FN_NODE: return "METADATA_FN_NODE"; - case bitc::METADATA_NAME: return "METADATA_NAME"; - case bitc::METADATA_NAMED_NODE: return "METADATA_NAMED_NODE"; - case bitc::METADATA_KIND: return "METADATA_KIND"; - case bitc::METADATA_ATTACHMENT: return "METADATA_ATTACHMENT"; - case bitc::METADATA_NODE2: return "METADATA_NODE2"; - case bitc::METADATA_FN_NODE2: return "METADATA_FN_NODE2"; - case bitc::METADATA_NAMED_NODE2: return "METADATA_NAMED_NODE2"; - case bitc::METADATA_ATTACHMENT2: return "METADATA_ATTACHMENT2"; - } - } -} - -struct PerRecordStats { - unsigned NumInstances; - unsigned NumAbbrev; - uint64_t TotalBits; - - PerRecordStats() : NumInstances(0), NumAbbrev(0), TotalBits(0) {} -}; - -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<PerRecordStats> 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) { - errs() << Err << "\n"; - return true; -} - -/// ParseBlock - Read a block, updating statistics, etc. -static bool ParseBlock(BitstreamCursor &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) errs() << 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) { - errs() << Indent << "<"; - if ((BlockName = GetBlockName(BlockID, *Stream.getBitStreamReader()))) - errs() << BlockName; - else - errs() << "UnknownBlock" << BlockID; - - if (NonSymbolic && BlockName) - errs() << " BlockID=" << BlockID; - - errs() << " 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"); - - uint64_t RecordStartBit = Stream.GetCurrentBitNo(); - - // 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) { - errs() << Indent << "</"; - if (BlockName) - errs() << BlockName << ">\n"; - else - errs() << "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: - Record.clear(); - - ++BlockStats.NumRecords; - if (AbbrevID != bitc::UNABBREV_RECORD) - ++BlockStats.NumAbbreviatedRecords; - - const char *BlobStart = 0; - unsigned BlobLen = 0; - unsigned Code = Stream.ReadRecord(AbbrevID, Record, BlobStart, BlobLen); - - - - // Increment the # occurrences of this code. - if (BlockStats.CodeFreq.size() <= Code) - BlockStats.CodeFreq.resize(Code+1); - BlockStats.CodeFreq[Code].NumInstances++; - BlockStats.CodeFreq[Code].TotalBits += - Stream.GetCurrentBitNo()-RecordStartBit; - if (AbbrevID != bitc::UNABBREV_RECORD) - BlockStats.CodeFreq[Code].NumAbbrev++; - - if (Dump) { - errs() << Indent << " <"; - if (const char *CodeName = - GetCodeName(Code, BlockID, *Stream.getBitStreamReader())) - errs() << CodeName; - else - errs() << "UnknownCode" << Code; - if (NonSymbolic && - GetCodeName(Code, BlockID, *Stream.getBitStreamReader())) - errs() << " codeid=" << Code; - if (AbbrevID != bitc::UNABBREV_RECORD) - errs() << " abbrevid=" << AbbrevID; - - for (unsigned i = 0, e = Record.size(); i != e; ++i) - errs() << " op" << i << "=" << (int64_t)Record[i]; - - errs() << "/>"; - - if (BlobStart) { - errs() << " blob data = "; - bool BlobIsPrintable = true; - for (unsigned i = 0; i != BlobLen; ++i) - if (!isprint(BlobStart[i])) { - BlobIsPrintable = false; - break; - } - - if (BlobIsPrintable) - errs() << "'" << std::string(BlobStart, BlobStart+BlobLen) <<"'"; - else - errs() << "unprintable, " << BlobLen << " bytes."; - } - - errs() << "\n"; - } - - break; - } - } -} - -static void PrintSize(double Bits) { - fprintf(stderr, "%.2f/%.2fB/%lluW", Bits, Bits/8,(unsigned long long)Bits/32); -} -static void PrintSize(uint64_t Bits) { - fprintf(stderr, "%llub/%.2fB/%lluW", (unsigned long long)Bits, - (double)Bits/8, (unsigned long long)Bits/32); -} - - -/// AnalyzeBitcode - Analyze the bitcode file specified by InputFilename. -static int AnalyzeBitcode() { - // Read the input file. - MemoryBuffer *MemBuf = MemoryBuffer::getFileOrSTDIN(InputFilename.c_str()); - - if (MemBuf == 0) - return Error("Error reading '" + InputFilename + "'."); - - if (MemBuf->getBufferSize() & 3) - return Error("Bitcode stream should be a multiple of 4 bytes in length"); - - unsigned char *BufPtr = (unsigned char *)MemBuf->getBufferStart(); - unsigned char *EndBufPtr = BufPtr+MemBuf->getBufferSize(); - - // If we have a wrapper header, parse it and ignore the non-bc file contents. - // The magic number is 0x0B17C0DE stored in little endian. - if (isBitcodeWrapper(BufPtr, EndBufPtr)) - if (SkipBitcodeWrapperHeader(BufPtr, EndBufPtr)) - return Error("Invalid bitcode wrapper header"); - - BitstreamReader StreamFile(BufPtr, EndBufPtr); - BitstreamCursor Stream(StreamFile); - StreamFile.CollectBlockInfoNames(); - - // 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) errs() << "\n\n"; - - uint64_t BufferSizeBits = (EndBufPtr-BufPtr)*CHAR_BIT; - // Print a summary of the read file. - errs() << "Summary of " << InputFilename << ":\n"; - errs() << " Total size: "; - PrintSize(BufferSizeBits); - errs() << "\n"; - errs() << " Stream type: "; - switch (CurStreamType) { - default: assert(0 && "Unknown bitstream type"); - case UnknownBitstream: errs() << "unknown\n"; break; - case LLVMIRBitstream: errs() << "LLVM IR\n"; break; - } - errs() << " # Toplevel Blocks: " << NumTopBlocks << "\n"; - errs() << "\n"; - - // Emit per-block stats. - errs() << "Per-block Summary:\n"; - for (std::map<unsigned, PerBlockIDStats>::iterator I = BlockIDStats.begin(), - E = BlockIDStats.end(); I != E; ++I) { - errs() << " Block ID #" << I->first; - if (const char *BlockName = GetBlockName(I->first, StreamFile)) - errs() << " (" << BlockName << ")"; - errs() << ":\n"; - - const PerBlockIDStats &Stats = I->second; - errs() << " Num Instances: " << Stats.NumInstances << "\n"; - errs() << " Total Size: "; - PrintSize(Stats.NumBits); - errs() << "\n"; - double pct = (Stats.NumBits * 100.0) / BufferSizeBits; - errs() << " Percent of file: " << format("%2.4f%%", pct) << "\n"; - if (Stats.NumInstances > 1) { - errs() << " Average Size: "; - PrintSize(Stats.NumBits/(double)Stats.NumInstances); - errs() << "\n"; - errs() << " Tot/Avg SubBlocks: " << Stats.NumSubBlocks << "/" - << Stats.NumSubBlocks/(double)Stats.NumInstances << "\n"; - errs() << " Tot/Avg Abbrevs: " << Stats.NumAbbrevs << "/" - << Stats.NumAbbrevs/(double)Stats.NumInstances << "\n"; - errs() << " Tot/Avg Records: " << Stats.NumRecords << "/" - << Stats.NumRecords/(double)Stats.NumInstances << "\n"; - } else { - errs() << " Num SubBlocks: " << Stats.NumSubBlocks << "\n"; - errs() << " Num Abbrevs: " << Stats.NumAbbrevs << "\n"; - errs() << " Num Records: " << Stats.NumRecords << "\n"; - } - if (Stats.NumRecords) { - double pct = (Stats.NumAbbreviatedRecords * 100.0) / Stats.NumRecords; - errs() << " Percent Abbrevs: " << format("%2.4f%%", pct) << "\n"; - } - errs() << "\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].NumInstances) - FreqPairs.push_back(std::make_pair(Freq, i)); - std::stable_sort(FreqPairs.begin(), FreqPairs.end()); - std::reverse(FreqPairs.begin(), FreqPairs.end()); - - errs() << "\tRecord Histogram:\n"; - fprintf(stderr, "\t\t Count # Bits %% Abv Record Kind\n"); - for (unsigned i = 0, e = FreqPairs.size(); i != e; ++i) { - const PerRecordStats &RecStats = Stats.CodeFreq[FreqPairs[i].second]; - - fprintf(stderr, "\t\t%7d %9llu ", RecStats.NumInstances, - (unsigned long long)RecStats.TotalBits); - - if (RecStats.NumAbbrev) - fprintf(stderr, "%7.2f ", - (double)RecStats.NumAbbrev/RecStats.NumInstances*100); - else - fprintf(stderr, " "); - - if (const char *CodeName = - GetCodeName(FreqPairs[i].second, I->first, StreamFile)) - fprintf(stderr, "%s\n", CodeName); - else - fprintf(stderr, "UnknownCode%d\n", FreqPairs[i].second); - } - errs() << "\n"; - - } - } - return 0; -} - - -int main(int argc, char **argv) { - // Print a stack trace if we signal out. - sys::PrintStackTraceOnErrorSignal(); - PrettyStackTraceProgram X(argc, argv); - llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. - cl::ParseCommandLineOptions(argc, argv, "llvm-bcanalyzer file analyzer\n"); - - return AnalyzeBitcode(); -} diff --git a/contrib/llvm/tools/llvm-config/CMakeLists.txt b/contrib/llvm/tools/llvm-config/CMakeLists.txt deleted file mode 100644 index 663cae5..0000000 --- a/contrib/llvm/tools/llvm-config/CMakeLists.txt +++ /dev/null @@ -1,146 +0,0 @@ -include(TestBigEndian) - -include(FindPerl) -if( NOT PERL_FOUND ) - message(FATAL_ERROR "Perl required but not found!") -endif( NOT PERL_FOUND ) - -set(PERL ${PERL_EXECUTABLE}) -set(VERSION PACKAGE_VERSION) -set(PREFIX ${LLVM_BINARY_DIR}) # TODO: Root for `make install'. -set(abs_top_srcdir ${LLVM_MAIN_SRC_DIR}) -set(abs_top_builddir ${LLVM_BINARY_DIR}) -execute_process(COMMAND date - OUTPUT_VARIABLE LLVM_CONFIGTIME - OUTPUT_STRIP_TRAILING_WHITESPACE) -# LLVM_ON_UNIX and LLVM_ON_WIN32 already set. -# those are set to blank by `autoconf' on MinGW, so it seems they are not required: -#set(LLVMGCCDIR "") -#set(LLVMGCC "") -#set(LLVMGXX "") -test_big_endian(IS_BIG_ENDIAN) -if( IS_BIG_ENDIAN ) - set(ENDIAN "big") -else( IS_BIG_ENDIAN ) - set(ENDIAN "little") -endif( IS_BIG_ENDIAN ) -set(SHLIBEXT ${LTDL_SHLIB_EXT}) -#EXEEXT already set. -set(OS "${CMAKE_SYSTEM}") -set(ARCH "${LLVM_NATIVE_ARCH}") - -get_system_libs(LLVM_SYSTEM_LIBS_LIST) -foreach(l ${LLVM_SYSTEM_LIBS_LIST}) - set(LLVM_SYSTEM_LIBS ${LLVM_SYSTEM_LIBS} "-l${l}") -endforeach() - -foreach(c ${LLVM_TARGETS_TO_BUILD}) - set(TARGETS_BUILT "${TARGETS_BUILT} ${c}") -endforeach(c) -set(TARGETS_TO_BUILD ${TARGETS_BUILT}) -set(TARGET_HAS_JIT "1") # TODO - -# Avoids replacement at config-time: -set(LLVM_CPPFLAGS "@LLVM_CPPFLAGS@") -set(LLVM_CFLAGS "@LLVM_CFLAGS@") -set(LLVM_CXXFLAGS "@LLVM_CXXFLAGS@") -set(LLVM_LDFLAGS "@LLVM_LDFLAGS@") -set(LIBS "@LIBS@") -set(LLVM_BUILDMODE "@LLVM_BUILDMODE@") - -configure_file( - ${CMAKE_CURRENT_SOURCE_DIR}/llvm-config.in.in - ${CMAKE_CURRENT_BINARY_DIR}/llvm-config.in - @ONLY -) - -set(LIBDEPS ${CMAKE_CURRENT_BINARY_DIR}/LibDeps.txt) -set(LIBDEPS_TMP ${CMAKE_CURRENT_BINARY_DIR}/LibDeps.txt.tmp) -set(FINAL_LIBDEPS ${CMAKE_CURRENT_BINARY_DIR}/FinalLibDeps.txt) -set(LLVM_CONFIG ${LLVM_TOOLS_BINARY_DIR}/llvm-config) -set(LLVM_CONFIG_IN ${CMAKE_CURRENT_BINARY_DIR}/llvm-config.in) - -if( CMAKE_CROSSCOMPILING ) - set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY) -endif() - -find_program(NM_PATH nm PATH_SUFFIXES /bin) - -if( NOT NM_PATH ) - message(FATAL_ERROR "`nm' not found") -endif() - -add_custom_command(OUTPUT ${LIBDEPS_TMP} - COMMAND ${PERL_EXECUTABLE} ${LLVM_MAIN_SRC_DIR}/utils/GenLibDeps.pl -flat ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR} ${NM_PATH} > ${LIBDEPS_TMP} - DEPENDS ${llvm_libs} - COMMENT "Regenerating ${LIBDEPS_TMP}") - -add_custom_command(OUTPUT ${LIBDEPS} - COMMAND ${CMAKE_COMMAND} -E copy_if_different ${LIBDEPS_TMP} ${LIBDEPS} - DEPENDS ${LIBDEPS_TMP} - COMMENT "Updating ${LIBDEPS} if necessary...") - -add_custom_command(OUTPUT ${FINAL_LIBDEPS} - COMMAND ${PERL_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/find-cycles.pl < ${LIBDEPS} > ${FINAL_LIBDEPS} || ${CMAKE_COMMAND} -E remove -f ${FINAL_LIBDEPS} - DEPENDS ${LIBDEPS} - COMMENT "Checking for cyclic dependencies between LLVM libraries.") - -set(C_FLGS "${CMAKE_C_FLAGS_${uppercase_CMAKE_BUILD_TYPE}} ${LLVM_DEFINITIONS}") -set(CXX_FLGS "${CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE}} ${LLVM_DEFINITIONS}") -set(CPP_FLGS "${CMAKE_CPP_FLAGS_${uppercase_CMAKE_BUILD_TYPE}} ${LLVM_DEFINITIONS}") - -add_custom_command(OUTPUT ${LLVM_CONFIG} - COMMAND echo 's!@LLVM_CPPFLAGS@!${CPP_FLGS}!' > temp.sed - COMMAND echo 's!@LLVM_CFLAGS@!${C_FLGS}!' >> temp.sed - COMMAND echo 's!@LLVM_CXXFLAGS@!${CXX_FLGS}!' >> temp.sed - # TODO: Use general flags for linking! not just for shared libs: - COMMAND echo 's!@LLVM_LDFLAGS@!${CMAKE_SHARED_LINKER_FLAGS}!' >> temp.sed - COMMAND echo 's!@LIBS@!${LLVM_SYSTEM_LIBS}!' >> temp.sed - COMMAND echo 's!@LLVM_BUILDMODE@!${CMAKE_BUILD_TYPE}!' >> temp.sed - COMMAND sed -f temp.sed < ${LLVM_CONFIG_IN} > ${LLVM_CONFIG} - COMMAND ${CMAKE_COMMAND} -E remove -f temp.sed - COMMAND cat ${FINAL_LIBDEPS} >> ${LLVM_CONFIG} - COMMAND chmod +x ${LLVM_CONFIG} - DEPENDS ${FINAL_LIBDEPS} ${LLVM_CONFIG_IN} - COMMENT "Building llvm-config script." - ) - -add_custom_target(llvm-config.target ALL - DEPENDS ${LLVM_CONFIG}) - -add_dependencies(llvm-config.target ${llvm_lib_targets}) - -# Make sure that llvm-config builds before the llvm tools, so we have -# LibDeps.txt and can use it for updating the hard-coded library -# dependencies on cmake/modules/LLVMLibDeps.cmake when the tools' -# build fail due to outdated dependencies: -set(LLVM_COMMON_DEPENDS ${LLVM_COMMON_DEPENDS} llvm-config.target) - -install(FILES ${LLVM_CONFIG} - PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE - WORLD_READ WORLD_EXECUTE - DESTINATION bin) - - -# Regeneration of library dependencies. - -# See the comments at the end of cmake/modules/LLVMConfig.cmake for -# notes and guidelines. - -set(LLVMLibDeps ${LLVM_MAIN_SRC_DIR}/cmake/modules/LLVMLibDeps.cmake) -set(LLVMLibDeps_TMP ${CMAKE_CURRENT_BINARY_DIR}/LLVMLibDeps.cmake.tmp) - -add_custom_command(OUTPUT ${LLVMLibDeps_TMP} - COMMAND sed -e s'@\\.a@@g' -e s'@\\.so@@g' -e 's@libLLVM@LLVM@g' -e 's@: @ @' -e 's@\\\(.*\\\)@set\(MSVC_LIB_DEPS_\\1\)@' ${FINAL_LIBDEPS} > ${LLVMLibDeps_TMP} - COMMAND ${CMAKE_COMMAND} -E copy_if_different ${LLVMLibDeps_TMP} ${LLVMLibDeps} - DEPENDS ${FINAL_LIBDEPS} - COMMENT "Updating cmake library dependencies file ${LLVMLibDeps}" - ) - -if( LLVM_TARGETS_TO_BUILD STREQUAL LLVM_ALL_TARGETS ) - add_custom_target(llvmlibdeps.target ALL DEPENDS ${LLVMLibDeps_TMP}) - add_dependencies(llvmlibdeps.target llvm-config.target) - set(LLVM_COMMON_DEPENDS ${LLVM_COMMON_DEPENDS} llvmlibdeps.target) -endif() - -set(LLVM_COMMON_DEPENDS ${LLVM_COMMON_DEPENDS} PARENT_SCOPE) diff --git a/contrib/llvm/tools/llvm-config/Makefile b/contrib/llvm/tools/llvm-config/Makefile deleted file mode 100644 index c7f7b32..0000000 --- a/contrib/llvm/tools/llvm-config/Makefile +++ /dev/null @@ -1,131 +0,0 @@ -##===- tools/llvm-config/Makefile --------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file 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 - -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 - -llvm-config-perobj: llvm-config.in $(GenLibDeps) $(LibDir) $(wildcard $(LibDir)/*.a) - $(Echo) "Generating llvm-config-perobj" - $(Verb) $(PERL) $(GenLibDeps) -perobj -flat $(LibDir) "$(NM_PATH)" >PerobjDeps.txt - $(Echo) "Checking for cyclic dependencies between LLVM objects." - $(Verb) $(PERL) $(PROJ_SRC_DIR)/find-cycles.pl < PerobjDepsIncl.txt > PerobjDepsInclFinal.txt || rm -f $@ - $(Verb) $(ECHO) 's/@LLVM_CPPFLAGS@/$(subst /,\/,$(SUB_CPPFLAGS))/' \ - > temp.sed - $(Verb) $(ECHO) 's/@LLVM_CFLAGS@/$(subst /,\/,$(SUB_CFLAGS))/' \ - >> temp.sed - $(Verb) $(ECHO) 's/@LLVM_CXXFLAGS@/$(subst /,\/,$(SUB_CXXFLAGS))/' \ - >> temp.sed - $(Verb) $(ECHO) 's/@LLVM_LDFLAGS@/$(subst /,\/,$(SUB_LDFLAGS))/' \ - >> temp.sed - $(Verb) $(ECHO) 's/@LLVM_BUILDMODE@/$(subst /,\/,$(BuildMode))/' \ - >> temp.sed - $(Verb) $(SED) -f temp.sed < $< > $@ - $(Verb) $(RM) temp.sed - $(Verb) cat PerobjDepsFinal.txt >> $@ - $(Verb) chmod +x $@ - -llvm-config-perobjincl: llvm-config.in $(GenLibDeps) $(LibDir) $(wildcard $(LibDir)/*.a) - $(Echo) "Generating llvm-config-perobjincl" - $(Verb) $(PERL) $(GenLibDeps) -perobj -perobjincl -flat $(LibDir) "$(NM_PATH)" >PerobjDepsIncl.txt - $(Echo) "Checking for cyclic dependencies between LLVM objects." - $(Verb) $(PERL) $(PROJ_SRC_DIR)/find-cycles.pl < PerobjDepsIncl.txt > PerobjDepsInclFinal.txt - $(Verb) $(ECHO) 's/@LLVM_CPPFLAGS@/$(subst /,\/,$(SUB_CPPFLAGS))/' \ - > temp.sed - $(Verb) $(ECHO) 's/@LLVM_CFLAGS@/$(subst /,\/,$(SUB_CFLAGS))/' \ - >> temp.sed - $(Verb) $(ECHO) 's/@LLVM_CXXFLAGS@/$(subst /,\/,$(SUB_CXXFLAGS))/' \ - >> temp.sed - $(Verb) $(ECHO) 's/@LLVM_LDFLAGS@/$(subst /,\/,$(SUB_LDFLAGS))/' \ - >> temp.sed - $(Verb) $(ECHO) 's/@LLVM_BUILDMODE@/$(subst /,\/,$(BuildMode))/' \ - >> temp.sed - $(Verb) $(SED) -f temp.sed < $< > $@ - $(Verb) $(RM) temp.sed - $(Verb) cat PerobjDepsInclFinal.txt >> $@ - $(Verb) chmod +x $@ - -# Build our final script. -$(ToolDir)/llvm-config: llvm-config.in $(FinalLibDeps) - $(Echo) "Building llvm-config script." - $(Verb) $(ECHO) 's/@LLVM_CPPFLAGS@/$(subst /,\/,$(SUB_CPPFLAGS))/' \ - > temp.sed - $(Verb) $(ECHO) 's/@LLVM_CFLAGS@/$(subst /,\/,$(SUB_CFLAGS))/' \ - >> temp.sed - $(Verb) $(ECHO) 's/@LLVM_CXXFLAGS@/$(subst /,\/,$(SUB_CXXFLAGS))/' \ - >> temp.sed - $(Verb) $(ECHO) 's/@LLVM_LDFLAGS@/$(subst /,\/,$(SUB_LDFLAGS))/' \ - >> temp.sed - $(Verb) $(ECHO) 's/@LLVM_BUILDMODE@/$(subst /,\/,$(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) $(DESTDIR)$(PROJ_bindir) - $(Verb) $(ScriptInstall) $(ToolDir)/llvm-config $(DESTDIR)$(PROJ_bindir) - diff --git a/contrib/llvm/tools/llvm-config/find-cycles.pl b/contrib/llvm/tools/llvm-config/find-cycles.pl deleted file mode 100755 index 5cbf5b4..0000000 --- a/contrib/llvm/tools/llvm-config/find-cycles.pl +++ /dev/null @@ -1,170 +0,0 @@ -#!/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. - } elsif (@modules > 1) { - $cycles_found = $cycles_found + 1; - print STDERR "find-cycles.pl: Circular dependency between *.o files:\n"; - print STDERR "find-cycles.pl: ", join(' ', @modules), "\n"; - push @modules, @modules; # WORKAROUND: Duplicate *.o 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/contrib/llvm/tools/llvm-config/llvm-config.in.in b/contrib/llvm/tools/llvm-config/llvm-config.in.in deleted file mode 100644 index d435d57..0000000 --- a/contrib/llvm/tools/llvm-config/llvm-config.in.in +++ /dev/null @@ -1,460 +0,0 @@ -#!@PERL@ -##===- tools/llvm-config ---------------------------------------*- perl -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file 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; -use Cwd 'abs_path'; - -#---- 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 $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 = abs_path("$RUN_DIR/.."); -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 = abs_path("$ABS_OBJ_ROOT") if (-d $ABS_OBJ_ROOT); -chomp($ABS_OBJ_ROOT); - -my $INCLUDEDIR = "$ABS_RUN_DIR/include"; -my $INCLUDEOPTION = "-I$INCLUDEDIR"; -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"; - # We need include files from both the srcdir and objdir. - $INCLUDEOPTION = "-I$INCLUDEDIR -I$LLVM_OBJ_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 "$INCLUDEOPTION $CPPFLAGS\n"; - } elsif ($arg eq "--cflags") { - $has_opt = 1; print "$INCLUDEOPTION $CFLAGS\n"; - } elsif ($arg eq "--cxxflags") { - $has_opt = 1; print "$INCLUDEOPTION $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 abs_path("$LLVM_OBJ_ROOT/"); - } elsif ($arg eq "--src-root") { - $has_opt = 1; print abs_path("$LLVM_SRC_ROOT/"); - } 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 target-specific entries - foreach my $target (@TARGETS_BUILT) { - # FIXME: Temporary, until we don't switch all targets - if (defined $NAME_MAP{$target.'asmprinter'}) { - $NAME_MAP{$target} = [$target.'info', - $target.'asmprinter', - $target.'codegen'] - } else { - $NAME_MAP{$target} = [$target.'info', - $NAME_MAP{$target}[0]] - } - - if (defined $NAME_MAP{$target.'asmparser'}) { - push @{$NAME_MAP{$target}},$target.'asmparser' - } - - if (defined $NAME_MAP{$target.'disassembler'}) { - push @{$NAME_MAP{$target}},$target.'disassembler' - } - } - - # Add virtual entries. - $NAME_MAP{'native'} = have_native_backend() ? [$ARCH] : []; - $NAME_MAP{'nativecodegen'} = have_native_backend() ? [$ARCH.'codegen'] : []; - $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/contrib/llvm/tools/llvm-diff/CMakeLists.txt b/contrib/llvm/tools/llvm-diff/CMakeLists.txt deleted file mode 100644 index f6d65c9..0000000 --- a/contrib/llvm/tools/llvm-diff/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -set(LLVM_LINK_COMPONENTS support asmparser bitreader) - -add_llvm_tool(llvm-diff - llvm-diff.cpp - DifferenceEngine.cpp - ) diff --git a/contrib/llvm/tools/llvm-diff/DifferenceEngine.cpp b/contrib/llvm/tools/llvm-diff/DifferenceEngine.cpp deleted file mode 100644 index b0a24d0..0000000 --- a/contrib/llvm/tools/llvm-diff/DifferenceEngine.cpp +++ /dev/null @@ -1,676 +0,0 @@ -//===-- DifferenceEngine.cpp - Structural function/module comparison ------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This header defines the implementation of the LLVM difference -// engine, which structurally compares global values within a module. -// -//===----------------------------------------------------------------------===// - -#include "DifferenceEngine.h" - -#include "llvm/Function.h" -#include "llvm/Instructions.h" -#include "llvm/Module.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/DenseSet.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/ADT/StringSet.h" -#include "llvm/Support/CallSite.h" -#include "llvm/Support/CFG.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Support/type_traits.h" - -#include <utility> - -using namespace llvm; - -namespace { - -/// A priority queue, implemented as a heap. -template <class T, class Sorter, unsigned InlineCapacity> -class PriorityQueue { - Sorter Precedes; - llvm::SmallVector<T, InlineCapacity> Storage; - -public: - PriorityQueue(const Sorter &Precedes) : Precedes(Precedes) {} - - /// Checks whether the heap is empty. - bool empty() const { return Storage.empty(); } - - /// Insert a new value on the heap. - void insert(const T &V) { - unsigned Index = Storage.size(); - Storage.push_back(V); - if (Index == 0) return; - - T *data = Storage.data(); - while (true) { - unsigned Target = (Index + 1) / 2 - 1; - if (!Precedes(data[Index], data[Target])) return; - std::swap(data[Index], data[Target]); - if (Target == 0) return; - Index = Target; - } - } - - /// Remove the minimum value in the heap. Only valid on a non-empty heap. - T remove_min() { - assert(!empty()); - T tmp = Storage[0]; - - unsigned NewSize = Storage.size() - 1; - if (NewSize) { - // Move the slot at the end to the beginning. - if (isPodLike<T>::value) - Storage[0] = Storage[NewSize]; - else - std::swap(Storage[0], Storage[NewSize]); - - // Bubble the root up as necessary. - unsigned Index = 0; - while (true) { - // With a 1-based index, the children would be Index*2 and Index*2+1. - unsigned R = (Index + 1) * 2; - unsigned L = R - 1; - - // If R is out of bounds, we're done after this in any case. - if (R >= NewSize) { - // If L is also out of bounds, we're done immediately. - if (L >= NewSize) break; - - // Otherwise, test whether we should swap L and Index. - if (Precedes(Storage[L], Storage[Index])) - std::swap(Storage[L], Storage[Index]); - break; - } - - // Otherwise, we need to compare with the smaller of L and R. - // Prefer R because it's closer to the end of the array. - unsigned IndexToTest = (Precedes(Storage[L], Storage[R]) ? L : R); - - // If Index is >= the min of L and R, then heap ordering is restored. - if (!Precedes(Storage[IndexToTest], Storage[Index])) - break; - - // Otherwise, keep bubbling up. - std::swap(Storage[IndexToTest], Storage[Index]); - Index = IndexToTest; - } - } - Storage.pop_back(); - - return tmp; - } -}; - -/// A function-scope difference engine. -class FunctionDifferenceEngine { - DifferenceEngine &Engine; - - /// The current mapping from old local values to new local values. - DenseMap<Value*, Value*> Values; - - /// The current mapping from old blocks to new blocks. - DenseMap<BasicBlock*, BasicBlock*> Blocks; - - DenseSet<std::pair<Value*, Value*> > TentativeValues; - - unsigned getUnprocPredCount(BasicBlock *Block) const { - unsigned Count = 0; - for (pred_iterator I = pred_begin(Block), E = pred_end(Block); I != E; ++I) - if (!Blocks.count(*I)) Count++; - return Count; - } - - typedef std::pair<BasicBlock*, BasicBlock*> BlockPair; - - /// A type which sorts a priority queue by the number of unprocessed - /// predecessor blocks it has remaining. - /// - /// This is actually really expensive to calculate. - struct QueueSorter { - const FunctionDifferenceEngine &fde; - explicit QueueSorter(const FunctionDifferenceEngine &fde) : fde(fde) {} - - bool operator()(const BlockPair &Old, const BlockPair &New) { - return fde.getUnprocPredCount(Old.first) - < fde.getUnprocPredCount(New.first); - } - }; - - /// A queue of unified blocks to process. - PriorityQueue<BlockPair, QueueSorter, 20> Queue; - - /// Try to unify the given two blocks. Enqueues them for processing - /// if they haven't already been processed. - /// - /// Returns true if there was a problem unifying them. - bool tryUnify(BasicBlock *L, BasicBlock *R) { - BasicBlock *&Ref = Blocks[L]; - - if (Ref) { - if (Ref == R) return false; - - Engine.logf("successor %l cannot be equivalent to %r; " - "it's already equivalent to %r") - << L << R << Ref; - return true; - } - - Ref = R; - Queue.insert(BlockPair(L, R)); - return false; - } - - /// Unifies two instructions, given that they're known not to have - /// structural differences. - void unify(Instruction *L, Instruction *R) { - DifferenceEngine::Context C(Engine, L, R); - - bool Result = diff(L, R, true, true); - assert(!Result && "structural differences second time around?"); - (void) Result; - if (!L->use_empty()) - Values[L] = R; - } - - void processQueue() { - while (!Queue.empty()) { - BlockPair Pair = Queue.remove_min(); - diff(Pair.first, Pair.second); - } - } - - void diff(BasicBlock *L, BasicBlock *R) { - DifferenceEngine::Context C(Engine, L, R); - - BasicBlock::iterator LI = L->begin(), LE = L->end(); - BasicBlock::iterator RI = R->begin(), RE = R->end(); - - llvm::SmallVector<std::pair<Instruction*,Instruction*>, 20> TentativePairs; - - do { - assert(LI != LE && RI != RE); - Instruction *LeftI = &*LI, *RightI = &*RI; - - // If the instructions differ, start the more sophisticated diff - // algorithm at the start of the block. - if (diff(LeftI, RightI, false, false)) { - TentativeValues.clear(); - return runBlockDiff(L->begin(), R->begin()); - } - - // Otherwise, tentatively unify them. - if (!LeftI->use_empty()) - TentativeValues.insert(std::make_pair(LeftI, RightI)); - - ++LI, ++RI; - } while (LI != LE); // This is sufficient: we can't get equality of - // terminators if there are residual instructions. - - // Unify everything in the block, non-tentatively this time. - TentativeValues.clear(); - for (LI = L->begin(), RI = R->begin(); LI != LE; ++LI, ++RI) - unify(&*LI, &*RI); - } - - bool matchForBlockDiff(Instruction *L, Instruction *R); - void runBlockDiff(BasicBlock::iterator LI, BasicBlock::iterator RI); - - bool diffCallSites(CallSite L, CallSite R, bool Complain) { - // FIXME: call attributes - if (!equivalentAsOperands(L.getCalledValue(), R.getCalledValue())) { - if (Complain) Engine.log("called functions differ"); - return true; - } - if (L.arg_size() != R.arg_size()) { - if (Complain) Engine.log("argument counts differ"); - return true; - } - for (unsigned I = 0, E = L.arg_size(); I != E; ++I) - if (!equivalentAsOperands(L.getArgument(I), R.getArgument(I))) { - if (Complain) - Engine.logf("arguments %l and %r differ") - << L.getArgument(I) << R.getArgument(I); - return true; - } - return false; - } - - bool diff(Instruction *L, Instruction *R, bool Complain, bool TryUnify) { - // FIXME: metadata (if Complain is set) - - // Different opcodes always imply different operations. - if (L->getOpcode() != R->getOpcode()) { - if (Complain) Engine.log("different instruction types"); - return true; - } - - if (isa<CmpInst>(L)) { - if (cast<CmpInst>(L)->getPredicate() - != cast<CmpInst>(R)->getPredicate()) { - if (Complain) Engine.log("different predicates"); - return true; - } - } else if (isa<CallInst>(L)) { - return diffCallSites(CallSite(L), CallSite(R), Complain); - } else if (isa<PHINode>(L)) { - // FIXME: implement. - - // This is really wierd; type uniquing is broken? - if (L->getType() != R->getType()) { - if (!L->getType()->isPointerTy() || !R->getType()->isPointerTy()) { - if (Complain) Engine.log("different phi types"); - return true; - } - } - return false; - - // Terminators. - } else if (isa<InvokeInst>(L)) { - InvokeInst *LI = cast<InvokeInst>(L); - InvokeInst *RI = cast<InvokeInst>(R); - if (diffCallSites(CallSite(LI), CallSite(RI), Complain)) - return true; - - if (TryUnify) { - tryUnify(LI->getNormalDest(), RI->getNormalDest()); - tryUnify(LI->getUnwindDest(), RI->getUnwindDest()); - } - return false; - - } else if (isa<BranchInst>(L)) { - BranchInst *LI = cast<BranchInst>(L); - BranchInst *RI = cast<BranchInst>(R); - if (LI->isConditional() != RI->isConditional()) { - if (Complain) Engine.log("branch conditionality differs"); - return true; - } - - if (LI->isConditional()) { - if (!equivalentAsOperands(LI->getCondition(), RI->getCondition())) { - if (Complain) Engine.log("branch conditions differ"); - return true; - } - if (TryUnify) tryUnify(LI->getSuccessor(1), RI->getSuccessor(1)); - } - if (TryUnify) tryUnify(LI->getSuccessor(0), RI->getSuccessor(0)); - return false; - - } else if (isa<SwitchInst>(L)) { - SwitchInst *LI = cast<SwitchInst>(L); - SwitchInst *RI = cast<SwitchInst>(R); - if (!equivalentAsOperands(LI->getCondition(), RI->getCondition())) { - if (Complain) Engine.log("switch conditions differ"); - return true; - } - if (TryUnify) tryUnify(LI->getDefaultDest(), RI->getDefaultDest()); - - bool Difference = false; - - DenseMap<ConstantInt*,BasicBlock*> LCases; - for (unsigned I = 1, E = LI->getNumCases(); I != E; ++I) - LCases[LI->getCaseValue(I)] = LI->getSuccessor(I); - for (unsigned I = 1, E = RI->getNumCases(); I != E; ++I) { - ConstantInt *CaseValue = RI->getCaseValue(I); - BasicBlock *LCase = LCases[CaseValue]; - if (LCase) { - if (TryUnify) tryUnify(LCase, RI->getSuccessor(I)); - LCases.erase(CaseValue); - } else if (!Difference) { - if (Complain) - Engine.logf("right switch has extra case %r") << CaseValue; - Difference = true; - } - } - if (!Difference) - for (DenseMap<ConstantInt*,BasicBlock*>::iterator - I = LCases.begin(), E = LCases.end(); I != E; ++I) { - if (Complain) - Engine.logf("left switch has extra case %l") << I->first; - Difference = true; - } - return Difference; - } else if (isa<UnreachableInst>(L)) { - return false; - } - - if (L->getNumOperands() != R->getNumOperands()) { - if (Complain) Engine.log("instructions have different operand counts"); - return true; - } - - for (unsigned I = 0, E = L->getNumOperands(); I != E; ++I) { - Value *LO = L->getOperand(I), *RO = R->getOperand(I); - if (!equivalentAsOperands(LO, RO)) { - if (Complain) Engine.logf("operands %l and %r differ") << LO << RO; - return true; - } - } - - return false; - } - - bool equivalentAsOperands(Constant *L, Constant *R) { - // Use equality as a preliminary filter. - if (L == R) - return true; - - if (L->getValueID() != R->getValueID()) - return false; - - // Ask the engine about global values. - if (isa<GlobalValue>(L)) - return Engine.equivalentAsOperands(cast<GlobalValue>(L), - cast<GlobalValue>(R)); - - // Compare constant expressions structurally. - if (isa<ConstantExpr>(L)) - return equivalentAsOperands(cast<ConstantExpr>(L), - cast<ConstantExpr>(R)); - - // Nulls of the "same type" don't always actually have the same - // type; I don't know why. Just white-list them. - if (isa<ConstantPointerNull>(L)) - return true; - - // Block addresses only match if we've already encountered the - // block. FIXME: tentative matches? - if (isa<BlockAddress>(L)) - return Blocks[cast<BlockAddress>(L)->getBasicBlock()] - == cast<BlockAddress>(R)->getBasicBlock(); - - return false; - } - - bool equivalentAsOperands(ConstantExpr *L, ConstantExpr *R) { - if (L == R) - return true; - if (L->getOpcode() != R->getOpcode()) - return false; - - switch (L->getOpcode()) { - case Instruction::ICmp: - case Instruction::FCmp: - if (L->getPredicate() != R->getPredicate()) - return false; - break; - - case Instruction::GetElementPtr: - // FIXME: inbounds? - break; - - default: - break; - } - - if (L->getNumOperands() != R->getNumOperands()) - return false; - - for (unsigned I = 0, E = L->getNumOperands(); I != E; ++I) - if (!equivalentAsOperands(L->getOperand(I), R->getOperand(I))) - return false; - - return true; - } - - bool equivalentAsOperands(Value *L, Value *R) { - // Fall out if the values have different kind. - // This possibly shouldn't take priority over oracles. - if (L->getValueID() != R->getValueID()) - return false; - - // Value subtypes: Argument, Constant, Instruction, BasicBlock, - // InlineAsm, MDNode, MDString, PseudoSourceValue - - if (isa<Constant>(L)) - return equivalentAsOperands(cast<Constant>(L), cast<Constant>(R)); - - if (isa<Instruction>(L)) - return Values[L] == R || TentativeValues.count(std::make_pair(L, R)); - - if (isa<Argument>(L)) - return Values[L] == R; - - if (isa<BasicBlock>(L)) - return Blocks[cast<BasicBlock>(L)] != R; - - // Pretend everything else is identical. - return true; - } - - // Avoid a gcc warning about accessing 'this' in an initializer. - FunctionDifferenceEngine *this_() { return this; } - -public: - FunctionDifferenceEngine(DifferenceEngine &Engine) : - Engine(Engine), Queue(QueueSorter(*this_())) {} - - void diff(Function *L, Function *R) { - if (L->arg_size() != R->arg_size()) - Engine.log("different argument counts"); - - // Map the arguments. - for (Function::arg_iterator - LI = L->arg_begin(), LE = L->arg_end(), - RI = R->arg_begin(), RE = R->arg_end(); - LI != LE && RI != RE; ++LI, ++RI) - Values[&*LI] = &*RI; - - tryUnify(&*L->begin(), &*R->begin()); - processQueue(); - } -}; - -struct DiffEntry { - DiffEntry() : Cost(0) {} - - unsigned Cost; - llvm::SmallVector<char, 8> Path; // actually of DifferenceEngine::DiffChange -}; - -bool FunctionDifferenceEngine::matchForBlockDiff(Instruction *L, - Instruction *R) { - return !diff(L, R, false, false); -} - -void FunctionDifferenceEngine::runBlockDiff(BasicBlock::iterator LStart, - BasicBlock::iterator RStart) { - BasicBlock::iterator LE = LStart->getParent()->end(); - BasicBlock::iterator RE = RStart->getParent()->end(); - - unsigned NL = std::distance(LStart, LE); - - SmallVector<DiffEntry, 20> Paths1(NL+1); - SmallVector<DiffEntry, 20> Paths2(NL+1); - - DiffEntry *Cur = Paths1.data(); - DiffEntry *Next = Paths2.data(); - - const unsigned LeftCost = 2; - const unsigned RightCost = 2; - const unsigned MatchCost = 0; - - assert(TentativeValues.empty()); - - // Initialize the first column. - for (unsigned I = 0; I != NL+1; ++I) { - Cur[I].Cost = I * LeftCost; - for (unsigned J = 0; J != I; ++J) - Cur[I].Path.push_back(DifferenceEngine::DC_left); - } - - for (BasicBlock::iterator RI = RStart; RI != RE; ++RI) { - // Initialize the first row. - Next[0] = Cur[0]; - Next[0].Cost += RightCost; - Next[0].Path.push_back(DifferenceEngine::DC_right); - - unsigned Index = 1; - for (BasicBlock::iterator LI = LStart; LI != LE; ++LI, ++Index) { - if (matchForBlockDiff(&*LI, &*RI)) { - Next[Index] = Cur[Index-1]; - Next[Index].Cost += MatchCost; - Next[Index].Path.push_back(DifferenceEngine::DC_match); - TentativeValues.insert(std::make_pair(&*LI, &*RI)); - } else if (Next[Index-1].Cost <= Cur[Index].Cost) { - Next[Index] = Next[Index-1]; - Next[Index].Cost += LeftCost; - Next[Index].Path.push_back(DifferenceEngine::DC_left); - } else { - Next[Index] = Cur[Index]; - Next[Index].Cost += RightCost; - Next[Index].Path.push_back(DifferenceEngine::DC_right); - } - } - - std::swap(Cur, Next); - } - - // We don't need the tentative values anymore; everything from here - // on out should be non-tentative. - TentativeValues.clear(); - - SmallVectorImpl<char> &Path = Cur[NL].Path; - BasicBlock::iterator LI = LStart, RI = RStart; - - DifferenceEngine::DiffLogBuilder Diff(Engine); - - // Drop trailing matches. - while (Path.back() == DifferenceEngine::DC_match) - Path.pop_back(); - - // Skip leading matches. - SmallVectorImpl<char>::iterator - PI = Path.begin(), PE = Path.end(); - while (PI != PE && *PI == DifferenceEngine::DC_match) { - unify(&*LI, &*RI); - ++PI, ++LI, ++RI; - } - - for (; PI != PE; ++PI) { - switch (static_cast<DifferenceEngine::DiffChange>(*PI)) { - case DifferenceEngine::DC_match: - assert(LI != LE && RI != RE); - { - Instruction *L = &*LI, *R = &*RI; - unify(L, R); - Diff.addMatch(L, R); - } - ++LI; ++RI; - break; - - case DifferenceEngine::DC_left: - assert(LI != LE); - Diff.addLeft(&*LI); - ++LI; - break; - - case DifferenceEngine::DC_right: - assert(RI != RE); - Diff.addRight(&*RI); - ++RI; - break; - } - } - - // Finishing unifying and complaining about the tails of the block, - // which should be matches all the way through. - while (LI != LE) { - assert(RI != RE); - unify(&*LI, &*RI); - ++LI, ++RI; - } - - // If the terminators have different kinds, but one is an invoke and the - // other is an unconditional branch immediately following a call, unify - // the results and the destinations. - TerminatorInst *LTerm = LStart->getParent()->getTerminator(); - TerminatorInst *RTerm = RStart->getParent()->getTerminator(); - if (isa<BranchInst>(LTerm) && isa<InvokeInst>(RTerm)) { - if (cast<BranchInst>(LTerm)->isConditional()) return; - BasicBlock::iterator I = LTerm; - if (I == LStart->getParent()->begin()) return; - --I; - if (!isa<CallInst>(*I)) return; - CallInst *LCall = cast<CallInst>(&*I); - InvokeInst *RInvoke = cast<InvokeInst>(RTerm); - if (!equivalentAsOperands(LCall->getCalledValue(), RInvoke->getCalledValue())) - return; - if (!LCall->use_empty()) - Values[LCall] = RInvoke; - tryUnify(LTerm->getSuccessor(0), RInvoke->getNormalDest()); - } else if (isa<InvokeInst>(LTerm) && isa<BranchInst>(RTerm)) { - if (cast<BranchInst>(RTerm)->isConditional()) return; - BasicBlock::iterator I = RTerm; - if (I == RStart->getParent()->begin()) return; - --I; - if (!isa<CallInst>(*I)) return; - CallInst *RCall = cast<CallInst>(I); - InvokeInst *LInvoke = cast<InvokeInst>(LTerm); - if (!equivalentAsOperands(LInvoke->getCalledValue(), RCall->getCalledValue())) - return; - if (!LInvoke->use_empty()) - Values[LInvoke] = RCall; - tryUnify(LInvoke->getNormalDest(), RTerm->getSuccessor(0)); - } -} - -} - -void DifferenceEngine::diff(Function *L, Function *R) { - Context C(*this, L, R); - - // FIXME: types - // FIXME: attributes and CC - // FIXME: parameter attributes - - // If both are declarations, we're done. - if (L->empty() && R->empty()) - return; - else if (L->empty()) - log("left function is declaration, right function is definition"); - else if (R->empty()) - log("right function is declaration, left function is definition"); - else - FunctionDifferenceEngine(*this).diff(L, R); -} - -void DifferenceEngine::diff(Module *L, Module *R) { - StringSet<> LNames; - SmallVector<std::pair<Function*,Function*>, 20> Queue; - - for (Module::iterator I = L->begin(), E = L->end(); I != E; ++I) { - Function *LFn = &*I; - LNames.insert(LFn->getName()); - - if (Function *RFn = R->getFunction(LFn->getName())) - Queue.push_back(std::make_pair(LFn, RFn)); - else - logf("function %l exists only in left module") << LFn; - } - - for (Module::iterator I = R->begin(), E = R->end(); I != E; ++I) { - Function *RFn = &*I; - if (!LNames.count(RFn->getName())) - logf("function %r exists only in right module") << RFn; - } - - for (SmallVectorImpl<std::pair<Function*,Function*> >::iterator - I = Queue.begin(), E = Queue.end(); I != E; ++I) - diff(I->first, I->second); -} - -bool DifferenceEngine::equivalentAsOperands(GlobalValue *L, GlobalValue *R) { - if (globalValueOracle) return (*globalValueOracle)(L, R); - return L->getName() == R->getName(); -} diff --git a/contrib/llvm/tools/llvm-diff/DifferenceEngine.h b/contrib/llvm/tools/llvm-diff/DifferenceEngine.h deleted file mode 100644 index 6eefb06..0000000 --- a/contrib/llvm/tools/llvm-diff/DifferenceEngine.h +++ /dev/null @@ -1,179 +0,0 @@ -//===-- DifferenceEngine.h - Module comparator ------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This header defines the interface to the LLVM difference engine, -// which structurally compares functions within a module. -// -//===----------------------------------------------------------------------===// - -#ifndef _LLVM_DIFFERENCE_ENGINE_H_ -#define _LLVM_DIFFERENCE_ENGINE_H_ - -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringRef.h" - -#include <utility> - -namespace llvm { - class Function; - class GlobalValue; - class Instruction; - class LLVMContext; - class Module; - class Twine; - class Value; - - /// A class for performing structural comparisons of LLVM assembly. - class DifferenceEngine { - public: - /// A temporary-object class for building up log messages. - class LogBuilder { - DifferenceEngine &Engine; - - /// The use of a stored StringRef here is okay because - /// LogBuilder should be used only as a temporary, and as a - /// temporary it will be destructed before whatever temporary - /// might be initializing this format. - StringRef Format; - - SmallVector<Value*, 4> Arguments; - - public: - LogBuilder(DifferenceEngine &Engine, StringRef Format) - : Engine(Engine), Format(Format) {} - - LogBuilder &operator<<(Value *V) { - Arguments.push_back(V); - return *this; - } - - ~LogBuilder() { - Engine.consumer.logf(*this); - } - - StringRef getFormat() const { return Format; } - - unsigned getNumArguments() const { return Arguments.size(); } - Value *getArgument(unsigned I) const { return Arguments[I]; } - }; - - enum DiffChange { DC_match, DC_left, DC_right }; - - /// A temporary-object class for building up diff messages. - class DiffLogBuilder { - typedef std::pair<Instruction*,Instruction*> DiffRecord; - SmallVector<DiffRecord, 20> Diff; - - DifferenceEngine &Engine; - - public: - DiffLogBuilder(DifferenceEngine &Engine) : Engine(Engine) {} - ~DiffLogBuilder() { Engine.consumer.logd(*this); } - - void addMatch(Instruction *L, Instruction *R) { - Diff.push_back(DiffRecord(L, R)); - } - void addLeft(Instruction *L) { - // HACK: VS 2010 has a bug in the stdlib that requires this. - Diff.push_back(DiffRecord(L, DiffRecord::second_type(0))); - } - void addRight(Instruction *R) { - // HACK: VS 2010 has a bug in the stdlib that requires this. - Diff.push_back(DiffRecord(DiffRecord::first_type(0), R)); - } - - unsigned getNumLines() const { return Diff.size(); } - DiffChange getLineKind(unsigned I) const { - return (Diff[I].first ? (Diff[I].second ? DC_match : DC_left) - : DC_right); - } - Instruction *getLeft(unsigned I) const { return Diff[I].first; } - Instruction *getRight(unsigned I) const { return Diff[I].second; } - }; - - /// The interface for consumers of difference data. - struct Consumer { - /// Record that a local context has been entered. Left and - /// Right are IR "containers" of some sort which are being - /// considered for structural equivalence: global variables, - /// functions, blocks, instructions, etc. - virtual void enterContext(Value *Left, Value *Right) = 0; - - /// Record that a local context has been exited. - virtual void exitContext() = 0; - - /// Record a difference within the current context. - virtual void log(StringRef Text) = 0; - - /// Record a formatted difference within the current context. - virtual void logf(const LogBuilder &Log) = 0; - - /// Record a line-by-line instruction diff. - virtual void logd(const DiffLogBuilder &Log) = 0; - - protected: - virtual ~Consumer() {} - }; - - /// A RAII object for recording the current context. - struct Context { - Context(DifferenceEngine &Engine, Value *L, Value *R) : Engine(Engine) { - Engine.consumer.enterContext(L, R); - } - - ~Context() { - Engine.consumer.exitContext(); - } - - private: - DifferenceEngine &Engine; - }; - - /// An oracle for answering whether two values are equivalent as - /// operands. - struct Oracle { - virtual bool operator()(Value *L, Value *R) = 0; - - protected: - virtual ~Oracle() {} - }; - - DifferenceEngine(LLVMContext &context, Consumer &consumer) - : context(context), consumer(consumer), globalValueOracle(0) {} - - void diff(Module *L, Module *R); - void diff(Function *L, Function *R); - - void log(StringRef text) { - consumer.log(text); - } - - LogBuilder logf(StringRef text) { - return LogBuilder(*this, text); - } - - /// Installs an oracle to decide whether two global values are - /// equivalent as operands. Without an oracle, global values are - /// considered equivalent as operands precisely when they have the - /// same name. - void setGlobalValueOracle(Oracle *oracle) { - globalValueOracle = oracle; - } - - /// Determines whether two global values are equivalent. - bool equivalentAsOperands(GlobalValue *L, GlobalValue *R); - - private: - LLVMContext &context; - Consumer &consumer; - Oracle *globalValueOracle; - }; -} - -#endif diff --git a/contrib/llvm/tools/llvm-diff/Makefile b/contrib/llvm/tools/llvm-diff/Makefile deleted file mode 100644 index 58e49fa..0000000 --- a/contrib/llvm/tools/llvm-diff/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -##===- tools/llvm-diff/Makefile ----------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL = ../.. -TOOLNAME = llvm-diff -LINK_COMPONENTS := asmparser bitreader - -# This tool has no plugins, optimize startup time. -TOOL_NO_EXPORTS = 1 - -include $(LEVEL)/Makefile.common diff --git a/contrib/llvm/tools/llvm-diff/llvm-diff.cpp b/contrib/llvm/tools/llvm-diff/llvm-diff.cpp deleted file mode 100644 index 16a990f..0000000 --- a/contrib/llvm/tools/llvm-diff/llvm-diff.cpp +++ /dev/null @@ -1,331 +0,0 @@ -//===-- llvm-diff.cpp - Module comparator command-line driver ---*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the command-line driver for the difference engine. -// -//===----------------------------------------------------------------------===// - -#include "DifferenceEngine.h" - -#include "llvm/Instructions.h" -#include "llvm/LLVMContext.h" -#include "llvm/Module.h" -#include "llvm/Type.h" -#include "llvm/Assembly/Parser.h" -#include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Support/SourceMgr.h" - -#include <string> -#include <utility> - - -using namespace llvm; - -/// Reads a module from a file. If the filename ends in .ll, it is -/// interpreted as an assembly file; otherwise, it is interpreted as -/// bitcode. On error, messages are written to stderr and null is -/// returned. -static Module *ReadModule(LLVMContext &Context, StringRef Name) { - // LLVM assembly path. - if (Name.endswith(".ll")) { - SMDiagnostic Diag; - Module *M = ParseAssemblyFile(Name, Diag, Context); - if (M) return M; - - Diag.Print("llvmdiff", errs()); - return 0; - } - - // Bitcode path. - MemoryBuffer *Buffer = MemoryBuffer::getFile(Name); - - // ParseBitcodeFile takes ownership of the buffer if it succeeds. - std::string Error; - Module *M = ParseBitcodeFile(Buffer, Context, &Error); - if (M) return M; - - errs() << "error parsing " << Name << ": " << Error; - delete Buffer; - return 0; -} - -namespace { -struct DiffContext { - DiffContext(Value *L, Value *R) - : L(L), R(R), Differences(false), IsFunction(isa<Function>(L)) {} - Value *L; - Value *R; - bool Differences; - bool IsFunction; - DenseMap<Value*,unsigned> LNumbering; - DenseMap<Value*,unsigned> RNumbering; -}; - -void ComputeNumbering(Function *F, DenseMap<Value*,unsigned> &Numbering) { - unsigned IN = 0; - - // Arguments get the first numbers. - for (Function::arg_iterator - AI = F->arg_begin(), AE = F->arg_end(); AI != AE; ++AI) - if (!AI->hasName()) - Numbering[&*AI] = IN++; - - // Walk the basic blocks in order. - for (Function::iterator FI = F->begin(), FE = F->end(); FI != FE; ++FI) { - if (!FI->hasName()) - Numbering[&*FI] = IN++; - - // Walk the instructions in order. - for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; ++BI) - // void instructions don't get numbers. - if (!BI->hasName() && !BI->getType()->isVoidTy()) - Numbering[&*BI] = IN++; - } - - assert(!Numbering.empty() && "asked for numbering but numbering was no-op"); -} - -class DiffConsumer : public DifferenceEngine::Consumer { -private: - raw_ostream &out; - Module *LModule; - Module *RModule; - SmallVector<DiffContext, 5> contexts; - bool Differences; - unsigned Indent; - - void printValue(Value *V, bool isL) { - if (V->hasName()) { - out << (isa<GlobalValue>(V) ? '@' : '%') << V->getName(); - return; - } - if (V->getType()->isVoidTy()) { - if (isa<StoreInst>(V)) { - out << "store to "; - printValue(cast<StoreInst>(V)->getPointerOperand(), isL); - } else if (isa<CallInst>(V)) { - out << "call to "; - printValue(cast<CallInst>(V)->getCalledValue(), isL); - } else if (isa<InvokeInst>(V)) { - out << "invoke to "; - printValue(cast<InvokeInst>(V)->getCalledValue(), isL); - } else { - out << *V; - } - return; - } - - unsigned N = contexts.size(); - while (N > 0) { - --N; - DiffContext &ctxt = contexts[N]; - if (!ctxt.IsFunction) continue; - if (isL) { - if (ctxt.LNumbering.empty()) - ComputeNumbering(cast<Function>(ctxt.L), ctxt.LNumbering); - out << '%' << ctxt.LNumbering[V]; - return; - } else { - if (ctxt.RNumbering.empty()) - ComputeNumbering(cast<Function>(ctxt.R), ctxt.RNumbering); - out << '%' << ctxt.RNumbering[V]; - return; - } - } - - out << "<anonymous>"; - } - - void header() { - if (contexts.empty()) return; - for (SmallVectorImpl<DiffContext>::iterator - I = contexts.begin(), E = contexts.end(); I != E; ++I) { - if (I->Differences) continue; - if (isa<Function>(I->L)) { - // Extra newline between functions. - if (Differences) out << "\n"; - - Function *L = cast<Function>(I->L); - Function *R = cast<Function>(I->R); - if (L->getName() != R->getName()) - out << "in function " << L->getName() - << " / " << R->getName() << ":\n"; - else - out << "in function " << L->getName() << ":\n"; - } else if (isa<BasicBlock>(I->L)) { - BasicBlock *L = cast<BasicBlock>(I->L); - BasicBlock *R = cast<BasicBlock>(I->R); - if (L->hasName() && R->hasName() && L->getName() == R->getName()) - out << " in block %" << L->getName() << ":\n"; - else { - out << " in block "; - printValue(L, true); - out << " / "; - printValue(R, false); - out << ":\n"; - } - } else if (isa<Instruction>(I->L)) { - out << " in instruction "; - printValue(I->L, true); - out << " / "; - printValue(I->R, false); - out << ":\n"; - } - - I->Differences = true; - } - } - - void indent() { - unsigned N = Indent; - while (N--) out << ' '; - } - -public: - DiffConsumer(Module *L, Module *R) - : out(errs()), LModule(L), RModule(R), Differences(false), Indent(0) {} - - bool hadDifferences() const { return Differences; } - - void enterContext(Value *L, Value *R) { - contexts.push_back(DiffContext(L, R)); - Indent += 2; - } - void exitContext() { - Differences |= contexts.back().Differences; - contexts.pop_back(); - Indent -= 2; - } - - void log(StringRef text) { - header(); - indent(); - out << text << '\n'; - } - - void logf(const DifferenceEngine::LogBuilder &Log) { - header(); - indent(); - - unsigned arg = 0; - - StringRef format = Log.getFormat(); - while (true) { - size_t percent = format.find('%'); - if (percent == StringRef::npos) { - out << format; - break; - } - assert(format[percent] == '%'); - - if (percent > 0) out << format.substr(0, percent); - - switch (format[percent+1]) { - case '%': out << '%'; break; - case 'l': printValue(Log.getArgument(arg++), true); break; - case 'r': printValue(Log.getArgument(arg++), false); break; - default: llvm_unreachable("unknown format character"); - } - - format = format.substr(percent+2); - } - - out << '\n'; - } - - void logd(const DifferenceEngine::DiffLogBuilder &Log) { - header(); - - for (unsigned I = 0, E = Log.getNumLines(); I != E; ++I) { - indent(); - switch (Log.getLineKind(I)) { - case DifferenceEngine::DC_match: - out << " "; - Log.getLeft(I)->dump(); - //printValue(Log.getLeft(I), true); - break; - case DifferenceEngine::DC_left: - out << "< "; - Log.getLeft(I)->dump(); - //printValue(Log.getLeft(I), true); - break; - case DifferenceEngine::DC_right: - out << "> "; - Log.getRight(I)->dump(); - //printValue(Log.getRight(I), false); - break; - } - //out << "\n"; - } - } - -}; -} - -static void diffGlobal(DifferenceEngine &Engine, Module *L, Module *R, - StringRef Name) { - // Drop leading sigils from the global name. - if (Name.startswith("@")) Name = Name.substr(1); - - Function *LFn = L->getFunction(Name); - Function *RFn = R->getFunction(Name); - if (LFn && RFn) - Engine.diff(LFn, RFn); - else if (!LFn && !RFn) - errs() << "No function named @" << Name << " in either module\n"; - else if (!LFn) - errs() << "No function named @" << Name << " in left module\n"; - else - errs() << "No function named @" << Name << " in right module\n"; -} - -cl::opt<std::string> LeftFilename(cl::Positional, - cl::desc("<first file>"), - cl::Required); -cl::opt<std::string> RightFilename(cl::Positional, - cl::desc("<second file>"), - cl::Required); -cl::list<std::string> GlobalsToCompare(cl::Positional, - cl::desc("<globals to compare>")); - -int main(int argc, char **argv) { - cl::ParseCommandLineOptions(argc, argv); - - LLVMContext Context; - - // Load both modules. Die if that fails. - Module *LModule = ReadModule(Context, LeftFilename); - Module *RModule = ReadModule(Context, RightFilename); - if (!LModule || !RModule) return 1; - - DiffConsumer Consumer(LModule, RModule); - DifferenceEngine Engine(Context, Consumer); - - // If any global names were given, just diff those. - if (!GlobalsToCompare.empty()) { - for (unsigned I = 0, E = GlobalsToCompare.size(); I != E; ++I) - diffGlobal(Engine, LModule, RModule, GlobalsToCompare[I]); - - // Otherwise, diff everything in the module. - } else { - Engine.diff(LModule, RModule); - } - - delete LModule; - delete RModule; - - return Consumer.hadDifferences(); -} diff --git a/contrib/llvm/tools/llvm-dis/CMakeLists.txt b/contrib/llvm/tools/llvm-dis/CMakeLists.txt deleted file mode 100644 index d62a6b5..0000000 --- a/contrib/llvm/tools/llvm-dis/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -set(LLVM_LINK_COMPONENTS bitreader) -set(LLVM_REQUIRES_EH 1) - -add_llvm_tool(llvm-dis - llvm-dis.cpp - ) diff --git a/contrib/llvm/tools/llvm-dis/Makefile b/contrib/llvm/tools/llvm-dis/Makefile deleted file mode 100644 index 22c9ecc..0000000 --- a/contrib/llvm/tools/llvm-dis/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -##===- tools/llvm-dis/Makefile ------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -LEVEL = ../.. - -TOOLNAME = llvm-dis -LINK_COMPONENTS := bitreader - -# This tool has no plugins, optimize startup time. -TOOL_NO_EXPORTS = 1 - -include $(LEVEL)/Makefile.common diff --git a/contrib/llvm/tools/llvm-dis/llvm-dis.cpp b/contrib/llvm/tools/llvm-dis/llvm-dis.cpp deleted file mode 100644 index 9d2d31d..0000000 --- a/contrib/llvm/tools/llvm-dis/llvm-dis.cpp +++ /dev/null @@ -1,138 +0,0 @@ -//===-- llvm-dis.cpp - The low-level LLVM disassembler --------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file 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/LLVMContext.h" -#include "llvm/Module.h" -#include "llvm/Type.h" -#include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/Assembly/AssemblyAnnotationWriter.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/FormattedStream.h" -#include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/PrettyStackTrace.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/System/Signals.h" -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("Enable binary output on terminals")); - -static cl::opt<bool> -DontPrint("disable-output", cl::desc("Don't output the .ll file"), cl::Hidden); - -static cl::opt<bool> -ShowAnnotations("show-annotations", - cl::desc("Add informational comments to the .ll file")); - -namespace { - -class CommentWriter : public AssemblyAnnotationWriter { -public: - void emitFunctionAnnot(const Function *F, - formatted_raw_ostream &OS) { - OS << "; [#uses=" << F->getNumUses() << ']'; // Output # uses - OS << '\n'; - } - void printInfoComment(const Value &V, formatted_raw_ostream &OS) { - if (V.getType()->isVoidTy()) return; - - OS.PadToColumn(50); - OS << "; [#uses=" << V.getNumUses() << ']'; // Output # uses - } -}; - -} // end anon namespace - -int main(int argc, char **argv) { - // Print a stack trace if we signal out. - sys::PrintStackTraceOnErrorSignal(); - PrettyStackTraceProgram X(argc, argv); - - LLVMContext &Context = getGlobalContext(); - llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. - - - cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .ll disassembler\n"); - - std::string ErrorMessage; - std::auto_ptr<Module> M; - - if (MemoryBuffer *Buffer - = MemoryBuffer::getFileOrSTDIN(InputFilename, &ErrorMessage)) { - M.reset(ParseBitcodeFile(Buffer, Context, &ErrorMessage)); - delete Buffer; - } - - if (M.get() == 0) { - errs() << argv[0] << ": "; - if (ErrorMessage.size()) - errs() << ErrorMessage << "\n"; - else - errs() << "bitcode didn't read correctly.\n"; - return 1; - } - - // Just use stdout. We won't actually print anything on it. - if (DontPrint) - OutputFilename = "-"; - - if (OutputFilename.empty()) { // Unspecified output, infer it. - if (InputFilename == "-") { - OutputFilename = "-"; - } else { - const std::string &IFN = InputFilename; - int Len = IFN.length(); - // If the source ends in .bc, strip it off. - if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') - OutputFilename = std::string(IFN.begin(), IFN.end()-3)+".ll"; - else - OutputFilename = IFN+".ll"; - } - } - - std::string ErrorInfo; - OwningPtr<tool_output_file> - Out(new tool_output_file(OutputFilename.c_str(), ErrorInfo, - raw_fd_ostream::F_Binary)); - if (!ErrorInfo.empty()) { - errs() << ErrorInfo << '\n'; - return 1; - } - - OwningPtr<AssemblyAnnotationWriter> Annotator; - if (ShowAnnotations) - Annotator.reset(new CommentWriter()); - - // All that llvm-dis does is write the assembly to a file. - if (!DontPrint) - M->print(Out->os(), Annotator.get()); - - // Declare success. - Out->keep(); - - return 0; -} - diff --git a/contrib/llvm/tools/llvm-extract/CMakeLists.txt b/contrib/llvm/tools/llvm-extract/CMakeLists.txt deleted file mode 100644 index a4e3266..0000000 --- a/contrib/llvm/tools/llvm-extract/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -set(LLVM_LINK_COMPONENTS asmparser ipo bitreader bitwriter) - -add_llvm_tool(llvm-extract - llvm-extract.cpp - ) diff --git a/contrib/llvm/tools/llvm-extract/Makefile b/contrib/llvm/tools/llvm-extract/Makefile deleted file mode 100644 index 5672aa3..0000000 --- a/contrib/llvm/tools/llvm-extract/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -##===- tools/llvm-extract/Makefile -------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL = ../.. - -TOOLNAME = llvm-extract -LINK_COMPONENTS := ipo bitreader bitwriter asmparser - -# This tool has no plugins, optimize startup time. -TOOL_NO_EXPORTS = 1 - -include $(LEVEL)/Makefile.common diff --git a/contrib/llvm/tools/llvm-extract/llvm-extract.cpp b/contrib/llvm/tools/llvm-extract/llvm-extract.cpp deleted file mode 100644 index 91a59e5..0000000 --- a/contrib/llvm/tools/llvm-extract/llvm-extract.cpp +++ /dev/null @@ -1,147 +0,0 @@ -//===- llvm-extract.cpp - LLVM function extraction utility ----------------===// -// -// The LLVM Compiler Infrastructure -// -// This file 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/LLVMContext.h" -#include "llvm/Module.h" -#include "llvm/PassManager.h" -#include "llvm/Assembly/PrintModulePass.h" -#include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/Transforms/IPO.h" -#include "llvm/Target/TargetData.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/IRReader.h" -#include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/PrettyStackTrace.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Support/SystemUtils.h" -#include "llvm/System/Signals.h" -#include <memory> -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("Enable binary output on terminals")); - -static cl::opt<bool> -DeleteFn("delete", cl::desc("Delete specified Globals from Module")); - -// ExtractFuncs - The functions to extract from the module... -static cl::list<std::string> -ExtractFuncs("func", cl::desc("Specify function to extract"), - cl::ZeroOrMore, cl::value_desc("function")); - -// ExtractGlobals - The globals to extract from the module... -static cl::list<std::string> -ExtractGlobals("glob", cl::desc("Specify global to extract"), - cl::ZeroOrMore, cl::value_desc("global")); - -static cl::opt<bool> -OutputAssembly("S", - cl::desc("Write output as LLVM assembly"), cl::Hidden); - -int main(int argc, char **argv) { - // Print a stack trace if we signal out. - sys::PrintStackTraceOnErrorSignal(); - PrettyStackTraceProgram X(argc, argv); - - LLVMContext &Context = getGlobalContext(); - llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. - cl::ParseCommandLineOptions(argc, argv, "llvm extractor\n"); - - // Use lazy loading, since we only care about selected global values. - SMDiagnostic Err; - std::auto_ptr<Module> M; - M.reset(getLazyIRFileModule(InputFilename, Err, Context)); - - if (M.get() == 0) { - Err.Print(argv[0], errs()); - return 1; - } - - std::vector<GlobalValue *> GVs; - - // Figure out which globals we should extract. - for (size_t i = 0, e = ExtractGlobals.size(); i != e; ++i) { - GlobalValue *GV = M.get()->getNamedGlobal(ExtractGlobals[i]); - if (!GV) { - errs() << argv[0] << ": program doesn't contain global named '" - << ExtractGlobals[i] << "'!\n"; - return 1; - } - GVs.push_back(GV); - } - - // Figure out which functions we should extract. - for (size_t i = 0, e = ExtractFuncs.size(); i != e; ++i) { - GlobalValue *GV = M.get()->getFunction(ExtractFuncs[i]); - if (!GV) { - errs() << argv[0] << ": program doesn't contain function named '" - << ExtractFuncs[i] << "'!\n"; - return 1; - } - GVs.push_back(GV); - } - - // Materialize requisite global values. - for (size_t i = 0, e = GVs.size(); i != e; ++i) { - GlobalValue *GV = GVs[i]; - if (GV->isMaterializable()) { - std::string ErrInfo; - if (GV->Materialize(&ErrInfo)) { - errs() << argv[0] << ": error reading input: " << ErrInfo << "\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 - - Passes.add(createGVExtractionPass(GVs, DeleteFn)); - if (!DeleteFn) - Passes.add(createGlobalDCEPass()); // Delete unreachable globals - Passes.add(createStripDeadDebugInfoPass()); // Remove dead debug info - Passes.add(createDeadTypeEliminationPass()); // Remove dead types... - Passes.add(createStripDeadPrototypesPass()); // Remove dead func decls - - std::string ErrorInfo; - tool_output_file Out(OutputFilename.c_str(), ErrorInfo, - raw_fd_ostream::F_Binary); - if (!ErrorInfo.empty()) { - errs() << ErrorInfo << '\n'; - return 1; - } - - if (OutputAssembly) - Passes.add(createPrintModulePass(&Out.os())); - else if (Force || !CheckBitcodeOutputToConsole(Out.os(), true)) - Passes.add(createBitcodeWriterPass(Out.os())); - - Passes.run(*M.get()); - - // Declare success. - Out.keep(); - - return 0; -} diff --git a/contrib/llvm/tools/llvm-ld/CMakeLists.txt b/contrib/llvm/tools/llvm-ld/CMakeLists.txt deleted file mode 100644 index 2ae4a1d..0000000 --- a/contrib/llvm/tools/llvm-ld/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -set(LLVM_LINK_COMPONENTS ipo scalaropts linker archive bitwriter) - -add_llvm_tool(llvm-ld - Optimize.cpp - llvm-ld.cpp - ) diff --git a/contrib/llvm/tools/llvm-ld/Makefile b/contrib/llvm/tools/llvm-ld/Makefile deleted file mode 100644 index 1ef9bf1..0000000 --- a/contrib/llvm/tools/llvm-ld/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -##===- tools/llvm-ld/Makefile ------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL = ../.. - -TOOLNAME = llvm-ld -LINK_COMPONENTS = ipo scalaropts linker archive bitwriter - -include $(LEVEL)/Makefile.common diff --git a/contrib/llvm/tools/llvm-ld/Optimize.cpp b/contrib/llvm/tools/llvm-ld/Optimize.cpp deleted file mode 100644 index 3fb0079..0000000 --- a/contrib/llvm/tools/llvm-ld/Optimize.cpp +++ /dev/null @@ -1,128 +0,0 @@ -//===- Optimize.cpp - Optimize a complete program -------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file 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/Support/CommandLine.h" -#include "llvm/Support/StandardPasses.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/System/DynamicLibrary.h" -#include "llvm/Target/TargetData.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Support/PassNameParser.h" -#include "llvm/Support/PluginLoader.h" -using namespace llvm; - -// Pass Name Options as generated by the PassNameParser -static cl::list<const PassInfo*, bool, PassNameParser> - OptimizationList(cl::desc("Optimizations available:")); - -//Don't verify at the end -static cl::opt<bool> DontVerify("disable-verify", cl::ReallyHidden); - -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) - createStandardLTOPasses(&Passes, !DisableInternalize, !DisableInline, - VerifyEach); - - // 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 - errs() << "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, createAggressiveDCEPass()); - addPass(Passes, createGlobalDCEPass()); - } - - // Make sure everything is still good. - if (!DontVerify) - Passes.add(createVerifierPass()); - - // Run our queue of passes all at once now, efficiently. - Passes.run(*M); -} - -} diff --git a/contrib/llvm/tools/llvm-ld/llvm-ld.cpp b/contrib/llvm/tools/llvm-ld/llvm-ld.cpp deleted file mode 100644 index 3bbea9d..0000000 --- a/contrib/llvm/tools/llvm-ld/llvm-ld.cpp +++ /dev/null @@ -1,724 +0,0 @@ -//===- llvm-ld.cpp - LLVM 'ld' compatible linker --------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file 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. -// -// 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/LLVMContext.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/Support/CommandLine.h" -#include "llvm/Support/FileUtilities.h" -#include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/PrettyStackTrace.h" -#include "llvm/Support/SystemUtils.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/System/Signals.h" -#include "llvm/Config/config.h" -#include <memory> -#include <cstring> -using namespace llvm; - -// Rightly this should go in a header file but it just seems such a waste. -namespace llvm { -extern void Optimize(Module*); -} - -// 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<std::string> BitcodeOutputFilename("b", cl::init(""), - cl::desc("Override bitcode 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> FrameworkPaths("F", cl::Prefix, - cl::desc("Specify a framework 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")); - -static cl::list<std::string> Frameworks("framework", - cl::desc("Specify frameworks to link to"), - cl::value_desc("framework")); - -// 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<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")); - -static cl::opt<std::string> CO9("m", 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; - -/// FileRemover objects to clean up output files in the event of an error. -static FileRemover OutputRemover; -static FileRemover BitcodeOutputRemover; - -/// 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, Module *M, int errcode = 1) { - errs() << progname << ": " << Message << "\n"; - delete M; - 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) - errs() << "'" << *I << "'" << " "; - errs() << "\n"; -} - -/// 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) { - size_t len = strlen(envp[entries]) + 1; - newenv[entries] = new char[len]; - memcpy(newenv[entries], envp[entries], len); - ++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) - errs() << "Generating Bitcode To " << FileName << '\n'; - - // Create the output file. - std::string ErrorInfo; - tool_output_file Out(FileName.c_str(), ErrorInfo, - raw_fd_ostream::F_Binary); - if (!ErrorInfo.empty()) { - PrintAndExit(ErrorInfo, M); - return; - } - - // Write it out - WriteBitcodeToFile(M, Out.os()); - Out.keep(); -} - -/// 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()); - // We will use GCC to assemble the program so set the assembly syntax to AT&T, - // regardless of what the target in the bitcode file is. - args.push_back("-x86-asm-syntax=att"); - args.push_back("-o"); - args.push_back(OutputFilename.c_str()); - args.push_back(InputFilename.c_str()); - args.push_back(0); - - if (Verbose) { - errs() << "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("-o"); - args.push_back(OutputFile.c_str()); - args.push_back(InputFile.c_str()); - args.push_back(0); - - if (Verbose) { - errs() << "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. -/// FrameworksPaths - The list of directories in which to find frameworks. -/// Frameworks - The list of frameworks (dynamic 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 and framework paths - for (unsigned index = 0; index < LibPaths.size(); index++) { - args.push_back("-L" + LibPaths[index]); - } - for (unsigned index = 0; index < FrameworkPaths.size(); index++) { - args.push_back("-F" + FrameworkPaths[index]); - } - - // Add the requested options - for (unsigned index = 0; index < XLinker.size(); index++) - args.push_back(XLinker[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); - } - - // Add in frameworks to link. - for (unsigned index = 0; index < Frameworks.size(); index++) { - args.push_back("-framework"); - args.push_back(Frameworks[index]); - } - - // 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) { - errs() << "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_cast<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, Module *M) { - if (Verbose) - errs() << "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], - (void *)(intptr_t)&Optimize); - if (llvmstub.isEmpty()) - PrintAndExit("Could not find llvm-stub.exe executable!", M); - - if (0 != sys::CopyFile(sys::Path(OutputFilename), llvmstub, &ErrMsg)) - PrintAndExit(ErrMsg, M); - - return; -#endif - - // Output the script to start the program... - std::string ErrorInfo; - tool_output_file Out2(OutputFilename.c_str(), ErrorInfo); - if (!ErrorInfo.empty()) - PrintAndExit(ErrorInfo, M); - - Out2.os() << "#!/bin/sh\n"; - // Allow user to setenv LLVMINTERP if lli is not in their PATH. - Out2.os() << "lli=${LLVMINTERP-lli}\n"; - Out2.os() << "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) { - // try explicit -L arguments first: - sys::Path FullLibraryPath; - for (cl::list<std::string>::const_iterator P = LibPaths.begin(), - E = LibPaths.end(); P != E; ++P) { - FullLibraryPath = *P; - FullLibraryPath.appendComponent("lib" + *i); - FullLibraryPath.appendSuffix(&(LTDL_SHLIB_EXT[1])); - if (!FullLibraryPath.isEmpty()) { - if (!FullLibraryPath.isDynamicLibrary()) { - // Not a native shared library; mark as invalid - FullLibraryPath = sys::Path(); - } else break; - } - } - if (FullLibraryPath.isEmpty()) - FullLibraryPath = sys::Path::FindLibrary(*i); - if (!FullLibraryPath.isEmpty()) - Out2.os() << " -load=" << FullLibraryPath.str() << " \\\n"; - } - Out2.os() << " " << BitcodeOutputFilename << " ${1+\"$@\"}\n"; - Out2.keep(); -} - -// 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)); - } - } -} - -int main(int argc, char **argv, char **envp) { - // Print a stack trace if we signal out. - sys::PrintStackTraceOnErrorSignal(); - PrettyStackTraceProgram X(argc, argv); - - LLVMContext &Context = getGlobalContext(); - llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. - - // 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"); - -#if defined(_WIN32) || defined(__CYGWIN__) - if (!LinkAsLibrary) { - // Default to "a.exe" instead of "a.out". - if (OutputFilename.getNumOccurrences() == 0) - OutputFilename = "a.exe"; - - // If there is no suffix add an "exe" one. - sys::Path ExeFile( OutputFilename ); - if (ExeFile.getSuffix() == "") { - ExeFile.appendSuffix("exe"); - OutputFilename = ExeFile.str(); - } - } -#endif - - // Generate the bitcode for the optimized module. - // If -b wasn't specified, use the name specified - // with -o to construct BitcodeOutputFilename. - if (BitcodeOutputFilename.empty()) { - BitcodeOutputFilename = OutputFilename; - if (!LinkAsLibrary) BitcodeOutputFilename += ".bc"; - } - - // Arrange for the bitcode output file to be deleted on any errors. - BitcodeOutputRemover.setFile(sys::Path(BitcodeOutputFilename)); - sys::RemoveFileOnSignal(sys::Path(BitcodeOutputFilename)); - - // Arrange for the output file to be deleted on any errors. - if (!LinkAsLibrary) { - OutputRemover.setFile(sys::Path(OutputFilename)); - sys::RemoveFileOnSignal(sys::Path(OutputFilename)); - } - - // Construct a Linker (now that Verbose is set) - Linker TheLinker(progname, OutputFilename, Context, 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 output. - GenerateBitcode(Composite.get(), BitcodeOutputFilename); - - // 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.", Composite.get()); - } - // Get the program arguments - sys::Path tmp_output("opt_result"); - std::string ErrMsg; - if (tmp_output.createTemporaryFileOnDisk(true, &ErrMsg)) - PrintAndExit(ErrMsg, Composite.get()); - - const char* args[4]; - args[0] = I->c_str(); - args[1] = BitcodeOutputFilename.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()) { - sys::Path target(BitcodeOutputFilename); - target.eraseFromDisk(); - if (tmp_output.renamePathOnDisk(target, &ErrMsg)) - PrintAndExit(ErrMsg, Composite.get(), 2); - } else - PrintAndExit("Post-link optimization output is not bitcode", - Composite.get()); - } else { - PrintAndExit(ErrMsg, Composite.get()); - } - } - } - - // 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. - FileRemover AssemblyFileRemover(AssemblyFile); - sys::RemoveFileOnSignal(AssemblyFile); - - // Determine the locations of the llc and gcc programs. - sys::Path llc = FindExecutable("llc", argv[0], - (void *)(intptr_t)&Optimize); - if (llc.isEmpty()) - PrintAndExit("Failed to find llc", Composite.get()); - - sys::Path gcc = sys::Program::FindProgramByName("gcc"); - if (gcc.isEmpty()) - PrintAndExit("Failed to find gcc", Composite.get()); - - // Generate an assembly language file for the bitcode. - std::string ErrMsg; - if (0 != GenerateAssembly(AssemblyFile.str(), BitcodeOutputFilename, - llc, ErrMsg)) - PrintAndExit(ErrMsg, Composite.get()); - - if (0 != GenerateNative(OutputFilename, AssemblyFile.str(), - NativeLinkItems, gcc, envp, ErrMsg)) - PrintAndExit(ErrMsg, Composite.get()); - } else if (NativeCBE) { - sys::Path CFile (OutputFilename); - CFile.appendSuffix("cbe.c"); - - // Mark the output files for removal. - FileRemover CFileRemover(CFile); - sys::RemoveFileOnSignal(CFile); - - // Determine the locations of the llc and gcc programs. - sys::Path llc = FindExecutable("llc", argv[0], - (void *)(intptr_t)&Optimize); - if (llc.isEmpty()) - PrintAndExit("Failed to find llc", Composite.get()); - - sys::Path gcc = sys::Program::FindProgramByName("gcc"); - if (gcc.isEmpty()) - PrintAndExit("Failed to find gcc", Composite.get()); - - // Generate an assembly language file for the bitcode. - std::string ErrMsg; - if (GenerateCFile(CFile.str(), BitcodeOutputFilename, llc, ErrMsg)) - PrintAndExit(ErrMsg, Composite.get()); - - if (GenerateNative(OutputFilename, CFile.str(), - NativeLinkItems, gcc, envp, ErrMsg)) - PrintAndExit(ErrMsg, Composite.get()); - } else { - EmitShellScript(argv, Composite.get()); - } - - // Make the script executable... - std::string ErrMsg; - if (sys::Path(OutputFilename).makeExecutableOnDisk(&ErrMsg)) - PrintAndExit(ErrMsg, Composite.get()); - - // Make the bitcode file readable and directly executable in LLEE as well - if (sys::Path(BitcodeOutputFilename).makeExecutableOnDisk(&ErrMsg)) - PrintAndExit(ErrMsg, Composite.get()); - - if (sys::Path(BitcodeOutputFilename).makeReadableOnDisk(&ErrMsg)) - PrintAndExit(ErrMsg, Composite.get()); - } - - // Operations which may fail are now complete. - BitcodeOutputRemover.releaseFile(); - if (!LinkAsLibrary) - OutputRemover.releaseFile(); - - // Graceful exit - return 0; -} diff --git a/contrib/llvm/tools/llvm-link/CMakeLists.txt b/contrib/llvm/tools/llvm-link/CMakeLists.txt deleted file mode 100644 index 11933f7..0000000 --- a/contrib/llvm/tools/llvm-link/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -set(LLVM_LINK_COMPONENTS linker bitreader bitwriter asmparser) - -add_llvm_tool(llvm-link - llvm-link.cpp - ) diff --git a/contrib/llvm/tools/llvm-link/Makefile b/contrib/llvm/tools/llvm-link/Makefile deleted file mode 100644 index 2637018..0000000 --- a/contrib/llvm/tools/llvm-link/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -##===- tools/llvm-link/Makefile ----------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -LEVEL = ../.. - -TOOLNAME = llvm-link -LINK_COMPONENTS = linker bitreader bitwriter asmparser - -# This tool has no plugins, optimize startup time. -TOOL_NO_EXPORTS = 1 - -include $(LEVEL)/Makefile.common diff --git a/contrib/llvm/tools/llvm-link/llvm-link.cpp b/contrib/llvm/tools/llvm-link/llvm-link.cpp deleted file mode 100644 index e55d0de..0000000 --- a/contrib/llvm/tools/llvm-link/llvm-link.cpp +++ /dev/null @@ -1,141 +0,0 @@ -//===- llvm-link.cpp - Low-level LLVM linker ------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file 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/LLVMContext.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/PrettyStackTrace.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Support/SystemUtils.h" -#include "llvm/Support/IRReader.h" -#include "llvm/System/Signals.h" -#include "llvm/System/Path.h" -#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("Enable binary output on terminals")); - -static cl::opt<bool> -OutputAssembly("S", - cl::desc("Write output as LLVM assembly"), cl::Hidden); - -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 char *argv0, - const std::string &FN, - LLVMContext& Context) { - sys::Path Filename; - if (!Filename.set(FN)) { - errs() << "Invalid file name: '" << FN << "'\n"; - return std::auto_ptr<Module>(); - } - - SMDiagnostic Err; - if (Verbose) errs() << "Loading '" << Filename.c_str() << "'\n"; - Module* Result = 0; - - const std::string &FNStr = Filename.str(); - Result = ParseIRFile(FNStr, Err, Context); - if (Result) return std::auto_ptr<Module>(Result); // Load successful! - - Err.Print(argv0, errs()); - return std::auto_ptr<Module>(); -} - -int main(int argc, char **argv) { - // Print a stack trace if we signal out. - sys::PrintStackTraceOnErrorSignal(); - PrettyStackTraceProgram X(argc, argv); - - LLVMContext &Context = getGlobalContext(); - llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. - cl::ParseCommandLineOptions(argc, argv, "llvm linker\n"); - - unsigned BaseArg = 0; - std::string ErrorMessage; - - std::auto_ptr<Module> Composite(LoadFile(argv[0], - InputFilenames[BaseArg], Context)); - if (Composite.get() == 0) { - errs() << 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(argv[0], - InputFilenames[i], Context)); - if (M.get() == 0) { - errs() << argv[0] << ": error loading file '" <<InputFilenames[i]<< "'\n"; - return 1; - } - - if (Verbose) errs() << "Linking in '" << InputFilenames[i] << "'\n"; - - if (Linker::LinkModules(Composite.get(), M.get(), &ErrorMessage)) { - errs() << 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) errs() << "Here's the assembly:\n" << *Composite; - - std::string ErrorInfo; - tool_output_file Out(OutputFilename.c_str(), ErrorInfo, - raw_fd_ostream::F_Binary); - if (!ErrorInfo.empty()) { - errs() << ErrorInfo << '\n'; - return 1; - } - - if (verifyModule(*Composite)) { - errs() << argv[0] << ": linked module is broken!\n"; - return 1; - } - - if (Verbose) errs() << "Writing bitcode...\n"; - if (OutputAssembly) { - Out.os() << *Composite; - } else if (Force || !CheckBitcodeOutputToConsole(Out.os(), true)) - WriteBitcodeToFile(Composite.get(), Out.os()); - - // Declare success. - Out.keep(); - - return 0; -} diff --git a/contrib/llvm/tools/llvm-mc/CMakeLists.txt b/contrib/llvm/tools/llvm-mc/CMakeLists.txt deleted file mode 100644 index 805caf4..0000000 --- a/contrib/llvm/tools/llvm-mc/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} support MC MCParser MCDisassembler) - -add_llvm_tool(llvm-mc - llvm-mc.cpp - Disassembler.cpp - ) diff --git a/contrib/llvm/tools/llvm-mc/Disassembler.cpp b/contrib/llvm/tools/llvm-mc/Disassembler.cpp deleted file mode 100644 index 13080b4..0000000 --- a/contrib/llvm/tools/llvm-mc/Disassembler.cpp +++ /dev/null @@ -1,338 +0,0 @@ -//===- Disassembler.cpp - Disassembler for hex strings --------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This class implements the disassembler of strings of bytes written in -// hexadecimal, from standard input or from a file. -// -//===----------------------------------------------------------------------===// - -#include "Disassembler.h" -#include "../../lib/MC/MCDisassembler/EDDisassembler.h" -#include "../../lib/MC/MCDisassembler/EDInst.h" -#include "../../lib/MC/MCDisassembler/EDOperand.h" -#include "../../lib/MC/MCDisassembler/EDToken.h" -#include "llvm/MC/MCAsmInfo.h" -#include "llvm/MC/MCDisassembler.h" -#include "llvm/MC/MCInst.h" -#include "llvm/MC/MCInstPrinter.h" -#include "llvm/Target/TargetRegistry.h" -#include "llvm/ADT/OwningPtr.h" -#include "llvm/ADT/Triple.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/MemoryObject.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Support/SourceMgr.h" -using namespace llvm; - -typedef std::vector<std::pair<unsigned char, const char*> > ByteArrayTy; - -namespace { -class VectorMemoryObject : public MemoryObject { -private: - const ByteArrayTy &Bytes; -public: - VectorMemoryObject(const ByteArrayTy &bytes) : Bytes(bytes) {} - - uint64_t getBase() const { return 0; } - uint64_t getExtent() const { return Bytes.size(); } - - int readByte(uint64_t Addr, uint8_t *Byte) const { - if (Addr > getExtent()) - return -1; - *Byte = Bytes[Addr].first; - return 0; - } -}; -} - -static bool PrintInsts(const MCDisassembler &DisAsm, - MCInstPrinter &Printer, const ByteArrayTy &Bytes, - SourceMgr &SM, raw_ostream &Out) { - // Wrap the vector in a MemoryObject. - VectorMemoryObject memoryObject(Bytes); - - // Disassemble it to strings. - uint64_t Size; - uint64_t Index; - - for (Index = 0; Index < Bytes.size(); Index += Size) { - MCInst Inst; - - if (DisAsm.getInstruction(Inst, Size, memoryObject, Index, - /*REMOVE*/ nulls())) { - Printer.printInst(&Inst, Out); - Out << "\n"; - } else { - SM.PrintMessage(SMLoc::getFromPointer(Bytes[Index].second), - "invalid instruction encoding", "warning"); - if (Size == 0) - Size = 1; // skip illegible bytes - } - } - - return false; -} - -static bool ByteArrayFromString(ByteArrayTy &ByteArray, - StringRef &Str, - SourceMgr &SM) { - while (!Str.empty()) { - // Strip horizontal whitespace. - if (size_t Pos = Str.find_first_not_of(" \t\r")) { - Str = Str.substr(Pos); - continue; - } - - // If this is the end of a line or start of a comment, remove the rest of - // the line. - if (Str[0] == '\n' || Str[0] == '#') { - // Strip to the end of line if we already processed any bytes on this - // line. This strips the comment and/or the \n. - if (Str[0] == '\n') { - Str = Str.substr(1); - } else { - Str = Str.substr(Str.find_first_of('\n')); - if (!Str.empty()) - Str = Str.substr(1); - } - continue; - } - - // Get the current token. - size_t Next = Str.find_first_of(" \t\n\r#"); - StringRef Value = Str.substr(0, Next); - - // Convert to a byte and add to the byte vector. - unsigned ByteVal; - if (Value.getAsInteger(0, ByteVal) || ByteVal > 255) { - // If we have an error, print it and skip to the end of line. - SM.PrintMessage(SMLoc::getFromPointer(Value.data()), - "invalid input token", "error"); - Str = Str.substr(Str.find('\n')); - ByteArray.clear(); - continue; - } - - ByteArray.push_back(std::make_pair((unsigned char)ByteVal, Value.data())); - Str = Str.substr(Next); - } - - return false; -} - -int Disassembler::disassemble(const Target &T, const std::string &Triple, - MemoryBuffer &Buffer, - raw_ostream &Out) { - // Set up disassembler. - OwningPtr<const MCAsmInfo> AsmInfo(T.createAsmInfo(Triple)); - - if (!AsmInfo) { - errs() << "error: no assembly info for target " << Triple << "\n"; - return -1; - } - - OwningPtr<const MCDisassembler> DisAsm(T.createMCDisassembler()); - if (!DisAsm) { - errs() << "error: no disassembler for target " << Triple << "\n"; - return -1; - } - - int AsmPrinterVariant = AsmInfo->getAssemblerDialect(); - OwningPtr<MCInstPrinter> IP(T.createMCInstPrinter(AsmPrinterVariant, - *AsmInfo)); - if (!IP) { - errs() << "error: no instruction printer for target " << Triple << '\n'; - return -1; - } - - bool ErrorOccurred = false; - - SourceMgr SM; - SM.AddNewSourceBuffer(&Buffer, SMLoc()); - - // Convert the input to a vector for disassembly. - ByteArrayTy ByteArray; - StringRef Str = Buffer.getBuffer(); - - ErrorOccurred |= ByteArrayFromString(ByteArray, Str, SM); - - if (!ByteArray.empty()) - ErrorOccurred |= PrintInsts(*DisAsm, *IP, ByteArray, SM, Out); - - return ErrorOccurred; -} - -static int byteArrayReader(uint8_t *B, uint64_t A, void *Arg) { - ByteArrayTy &ByteArray = *((ByteArrayTy*)Arg); - - if (A >= ByteArray.size()) - return -1; - - *B = ByteArray[A].first; - - return 0; -} - -static int verboseEvaluator(uint64_t *V, unsigned R, void *Arg) { - EDDisassembler &disassembler = *(EDDisassembler *)((void **)Arg)[0]; - raw_ostream &Out = *(raw_ostream *)((void **)Arg)[1]; - - if (const char *regName = disassembler.nameWithRegisterID(R)) - Out << "[" << regName << "/" << R << "]"; - - if (disassembler.registerIsStackPointer(R)) - Out << "(sp)"; - if (disassembler.registerIsProgramCounter(R)) - Out << "(pc)"; - - *V = 0; - return 0; -} - -int Disassembler::disassembleEnhanced(const std::string &TS, - MemoryBuffer &Buffer, - raw_ostream &Out) { - ByteArrayTy ByteArray; - StringRef Str = Buffer.getBuffer(); - SourceMgr SM; - - SM.AddNewSourceBuffer(&Buffer, SMLoc()); - - if (ByteArrayFromString(ByteArray, Str, SM)) { - return -1; - } - - Triple T(TS); - EDDisassembler::AssemblySyntax AS; - - switch (T.getArch()) { - default: - errs() << "error: no default assembly syntax for " << TS.c_str() << "\n"; - return -1; - case Triple::arm: - case Triple::thumb: - AS = EDDisassembler::kEDAssemblySyntaxARMUAL; - break; - case Triple::x86: - case Triple::x86_64: - AS = EDDisassembler::kEDAssemblySyntaxX86ATT; - break; - } - - EDDisassembler::initialize(); - EDDisassembler *disassembler = - EDDisassembler::getDisassembler(TS.c_str(), AS); - - if (disassembler == 0) { - errs() << "error: couldn't get disassembler for " << TS << '\n'; - return -1; - } - - EDInst *inst = - disassembler->createInst(byteArrayReader, 0, &ByteArray); - - if (inst == 0) { - errs() << "error: Didn't get an instruction\n"; - return -1; - } - - unsigned numTokens = inst->numTokens(); - if ((int)numTokens < 0) { - errs() << "error: couldn't count the instruction's tokens\n"; - return -1; - } - - for (unsigned tokenIndex = 0; tokenIndex != numTokens; ++tokenIndex) { - EDToken *token; - - if (inst->getToken(token, tokenIndex)) { - errs() << "error: Couldn't get token\n"; - return -1; - } - - const char *buf; - if (token->getString(buf)) { - errs() << "error: Couldn't get string for token\n"; - return -1; - } - - Out << '['; - int operandIndex = token->operandID(); - - if (operandIndex >= 0) - Out << operandIndex << "-"; - - switch (token->type()) { - default: Out << "?"; break; - case EDToken::kTokenWhitespace: Out << "w"; break; - case EDToken::kTokenPunctuation: Out << "p"; break; - case EDToken::kTokenOpcode: Out << "o"; break; - case EDToken::kTokenLiteral: Out << "l"; break; - case EDToken::kTokenRegister: Out << "r"; break; - } - - Out << ":" << buf; - - if (token->type() == EDToken::kTokenLiteral) { - Out << "="; - if (token->literalSign()) - Out << "-"; - uint64_t absoluteValue; - if (token->literalAbsoluteValue(absoluteValue)) { - errs() << "error: Couldn't get the value of a literal token\n"; - return -1; - } - Out << absoluteValue; - } else if (token->type() == EDToken::kTokenRegister) { - Out << "="; - unsigned regID; - if (token->registerID(regID)) { - errs() << "error: Couldn't get the ID of a register token\n"; - return -1; - } - Out << "r" << regID; - } - - Out << "]"; - } - - Out << " "; - - if (inst->isBranch()) - Out << "<br> "; - if (inst->isMove()) - Out << "<mov> "; - - unsigned numOperands = inst->numOperands(); - - if ((int)numOperands < 0) { - errs() << "error: Couldn't count operands\n"; - return -1; - } - - for (unsigned operandIndex = 0; operandIndex != numOperands; ++operandIndex) { - Out << operandIndex << ":"; - - EDOperand *operand; - if (inst->getOperand(operand, operandIndex)) { - errs() << "error: couldn't get operand\n"; - return -1; - } - - uint64_t evaluatedResult; - void *Arg[] = { disassembler, &Out }; - evaluatedResult = operand->evaluate(evaluatedResult, verboseEvaluator, Arg); - Out << "=" << evaluatedResult << " "; - } - - Out << '\n'; - - return 0; -} - diff --git a/contrib/llvm/tools/llvm-mc/Disassembler.h b/contrib/llvm/tools/llvm-mc/Disassembler.h deleted file mode 100644 index b56f2e9..0000000 --- a/contrib/llvm/tools/llvm-mc/Disassembler.h +++ /dev/null @@ -1,40 +0,0 @@ -//===- Disassembler.h - Text File Disassembler ----------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This class implements the disassembler of strings of bytes written in -// hexadecimal, from standard input or from a file. -// -//===----------------------------------------------------------------------===// - -#ifndef DISASSEMBLER_H -#define DISASSEMBLER_H - -#include <string> - -namespace llvm { - -class Target; -class MemoryBuffer; -class raw_ostream; - -class Disassembler { -public: - static int disassemble(const Target &target, - const std::string &tripleString, - MemoryBuffer &buffer, - raw_ostream &Out); - - static int disassembleEnhanced(const std::string &tripleString, - MemoryBuffer &buffer, - raw_ostream &Out); -}; - -} // namespace llvm - -#endif diff --git a/contrib/llvm/tools/llvm-mc/Makefile b/contrib/llvm/tools/llvm-mc/Makefile deleted file mode 100644 index 934a6e4..0000000 --- a/contrib/llvm/tools/llvm-mc/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -##===- tools/llvm-mc/Makefile ------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL = ../.. -TOOLNAME = llvm-mc - -# This tool has no plugins, optimize startup time. -TOOL_NO_EXPORTS = 1 - -# 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) MCDisassembler MCParser MC support - -include $(LLVM_SRC_ROOT)/Makefile.rules - diff --git a/contrib/llvm/tools/llvm-mc/llvm-mc.cpp b/contrib/llvm/tools/llvm-mc/llvm-mc.cpp deleted file mode 100644 index aef0a3d..0000000 --- a/contrib/llvm/tools/llvm-mc/llvm-mc.cpp +++ /dev/null @@ -1,410 +0,0 @@ -//===-- llvm-mc.cpp - Machine Code Hacking Driver -------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This utility is a simple driver that allows command line hacking on machine -// code. -// -//===----------------------------------------------------------------------===// - -#include "llvm/MC/MCParser/AsmLexer.h" -#include "llvm/MC/MCParser/MCAsmLexer.h" -#include "llvm/MC/MCContext.h" -#include "llvm/MC/MCCodeEmitter.h" -#include "llvm/MC/MCInstPrinter.h" -#include "llvm/MC/MCSectionMachO.h" -#include "llvm/MC/MCStreamer.h" -#include "llvm/Target/TargetAsmBackend.h" -#include "llvm/Target/TargetAsmParser.h" -#include "llvm/Target/TargetData.h" -#include "llvm/Target/TargetRegistry.h" -#include "llvm/Target/TargetMachine.h" // FIXME. -#include "llvm/Target/TargetSelect.h" -#include "llvm/ADT/OwningPtr.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/FileUtilities.h" -#include "llvm/Support/FormattedStream.h" -#include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/PrettyStackTrace.h" -#include "llvm/Support/SourceMgr.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/System/Host.h" -#include "llvm/System/Signals.h" -#include "Disassembler.h" -using namespace llvm; - -static cl::opt<std::string> -InputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-")); - -static cl::opt<std::string> -OutputFilename("o", cl::desc("Output filename"), - cl::value_desc("filename")); - -static cl::opt<bool> -ShowEncoding("show-encoding", cl::desc("Show instruction encodings")); - -static cl::opt<bool> -ShowInst("show-inst", cl::desc("Show internal instruction representation")); - -static cl::opt<bool> -ShowInstOperands("show-inst-operands", - cl::desc("Show instructions operands as parsed")); - -static cl::opt<unsigned> -OutputAsmVariant("output-asm-variant", - cl::desc("Syntax variant to use for output printing")); - -static cl::opt<bool> -RelaxAll("mc-relax-all", cl::desc("Relax all fixups")); - -static cl::opt<bool> -EnableLogging("enable-api-logging", cl::desc("Enable MC API logging")); - -enum OutputFileType { - OFT_Null, - OFT_AssemblyFile, - OFT_ObjectFile -}; -static cl::opt<OutputFileType> -FileType("filetype", cl::init(OFT_AssemblyFile), - cl::desc("Choose an output file type:"), - cl::values( - clEnumValN(OFT_AssemblyFile, "asm", - "Emit an assembly ('.s') file"), - clEnumValN(OFT_Null, "null", - "Don't emit anything (for timing purposes)"), - clEnumValN(OFT_ObjectFile, "obj", - "Emit a native object ('.o') file"), - clEnumValEnd)); - -static cl::list<std::string> -IncludeDirs("I", cl::desc("Directory of include files"), - cl::value_desc("directory"), cl::Prefix); - -static cl::opt<std::string> -ArchName("arch", cl::desc("Target arch to assemble for, " - "see -version for available targets")); - -static cl::opt<std::string> -TripleName("triple", cl::desc("Target triple to assemble for, " - "see -version for available targets")); - -static cl::opt<bool> -NoInitialTextSection("n", cl::desc( - "Don't assume assembly file starts in the text section")); - -enum ActionType { - AC_AsLex, - AC_Assemble, - AC_Disassemble, - AC_EDisassemble -}; - -static cl::opt<ActionType> -Action(cl::desc("Action to perform:"), - cl::init(AC_Assemble), - cl::values(clEnumValN(AC_AsLex, "as-lex", - "Lex tokens from a .s file"), - clEnumValN(AC_Assemble, "assemble", - "Assemble a .s file (default)"), - clEnumValN(AC_Disassemble, "disassemble", - "Disassemble strings of hex bytes"), - clEnumValN(AC_EDisassemble, "edis", - "Enhanced disassembly of strings of hex bytes"), - clEnumValEnd)); - -static const Target *GetTarget(const char *ProgName) { - // Figure out the target triple. - if (TripleName.empty()) - TripleName = sys::getHostTriple(); - if (!ArchName.empty()) { - llvm::Triple TT(TripleName); - TT.setArchName(ArchName); - TripleName = TT.str(); - } - - // Get the target specific parser. - std::string Error; - const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error); - if (TheTarget) - return TheTarget; - - errs() << ProgName << ": error: unable to get target for '" << TripleName - << "', see --version and --triple.\n"; - return 0; -} - -static tool_output_file *GetOutputStream() { - if (OutputFilename == "") - OutputFilename = "-"; - - std::string Err; - tool_output_file *Out = new tool_output_file(OutputFilename.c_str(), Err, - raw_fd_ostream::F_Binary); - if (!Err.empty()) { - errs() << Err << '\n'; - delete Out; - return 0; - } - - return Out; -} - -static int AsLexInput(const char *ProgName) { - std::string ErrorMessage; - MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename, - &ErrorMessage); - if (Buffer == 0) { - errs() << ProgName << ": "; - if (ErrorMessage.size()) - errs() << ErrorMessage << "\n"; - else - errs() << "input file didn't read correctly.\n"; - return 1; - } - - SourceMgr SrcMgr; - - // Tell SrcMgr about this buffer, which is what TGParser will pick up. - SrcMgr.AddNewSourceBuffer(Buffer, SMLoc()); - - // Record the location of the include directories so that the lexer can find - // it later. - SrcMgr.setIncludeDirs(IncludeDirs); - - const Target *TheTarget = GetTarget(ProgName); - if (!TheTarget) - return 1; - - llvm::OwningPtr<MCAsmInfo> MAI(TheTarget->createAsmInfo(TripleName)); - assert(MAI && "Unable to create target asm info!"); - - AsmLexer Lexer(*MAI); - Lexer.setBuffer(SrcMgr.getMemoryBuffer(0)); - - OwningPtr<tool_output_file> Out(GetOutputStream()); - if (!Out) - return 1; - - bool Error = false; - while (Lexer.Lex().isNot(AsmToken::Eof)) { - switch (Lexer.getKind()) { - default: - SrcMgr.PrintMessage(Lexer.getLoc(), "unknown token", "warning"); - Error = true; - break; - case AsmToken::Error: - Error = true; // error already printed. - break; - case AsmToken::Identifier: - Out->os() << "identifier: " << Lexer.getTok().getString() << '\n'; - break; - case AsmToken::String: - Out->os() << "string: " << Lexer.getTok().getString() << '\n'; - break; - case AsmToken::Integer: - Out->os() << "int: " << Lexer.getTok().getString() << '\n'; - break; - - case AsmToken::Amp: Out->os() << "Amp\n"; break; - case AsmToken::AmpAmp: Out->os() << "AmpAmp\n"; break; - case AsmToken::Caret: Out->os() << "Caret\n"; break; - case AsmToken::Colon: Out->os() << "Colon\n"; break; - case AsmToken::Comma: Out->os() << "Comma\n"; break; - case AsmToken::Dollar: Out->os() << "Dollar\n"; break; - case AsmToken::EndOfStatement: Out->os() << "EndOfStatement\n"; break; - case AsmToken::Eof: Out->os() << "Eof\n"; break; - case AsmToken::Equal: Out->os() << "Equal\n"; break; - case AsmToken::EqualEqual: Out->os() << "EqualEqual\n"; break; - case AsmToken::Exclaim: Out->os() << "Exclaim\n"; break; - case AsmToken::ExclaimEqual: Out->os() << "ExclaimEqual\n"; break; - case AsmToken::Greater: Out->os() << "Greater\n"; break; - case AsmToken::GreaterEqual: Out->os() << "GreaterEqual\n"; break; - case AsmToken::GreaterGreater: Out->os() << "GreaterGreater\n"; break; - case AsmToken::LParen: Out->os() << "LParen\n"; break; - case AsmToken::Less: Out->os() << "Less\n"; break; - case AsmToken::LessEqual: Out->os() << "LessEqual\n"; break; - case AsmToken::LessGreater: Out->os() << "LessGreater\n"; break; - case AsmToken::LessLess: Out->os() << "LessLess\n"; break; - case AsmToken::Minus: Out->os() << "Minus\n"; break; - case AsmToken::Percent: Out->os() << "Percent\n"; break; - case AsmToken::Pipe: Out->os() << "Pipe\n"; break; - case AsmToken::PipePipe: Out->os() << "PipePipe\n"; break; - case AsmToken::Plus: Out->os() << "Plus\n"; break; - case AsmToken::RParen: Out->os() << "RParen\n"; break; - case AsmToken::Slash: Out->os() << "Slash\n"; break; - case AsmToken::Star: Out->os() << "Star\n"; break; - case AsmToken::Tilde: Out->os() << "Tilde\n"; break; - } - } - - // Keep output if no errors. - if (Error == 0) Out->keep(); - - return Error; -} - -static int AssembleInput(const char *ProgName) { - const Target *TheTarget = GetTarget(ProgName); - if (!TheTarget) - return 1; - - std::string Error; - MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename, &Error); - if (Buffer == 0) { - errs() << ProgName << ": "; - if (Error.size()) - errs() << Error << "\n"; - else - errs() << "input file didn't read correctly.\n"; - return 1; - } - - SourceMgr SrcMgr; - - // Tell SrcMgr about this buffer, which is what the parser will pick up. - SrcMgr.AddNewSourceBuffer(Buffer, SMLoc()); - - // Record the location of the include directories so that the lexer can find - // it later. - SrcMgr.setIncludeDirs(IncludeDirs); - - - llvm::OwningPtr<MCAsmInfo> MAI(TheTarget->createAsmInfo(TripleName)); - assert(MAI && "Unable to create target asm info!"); - - MCContext Ctx(*MAI); - - // FIXME: We shouldn't need to do this (and link in codegen). - OwningPtr<TargetMachine> TM(TheTarget->createTargetMachine(TripleName, "")); - - if (!TM) { - errs() << ProgName << ": error: could not create target for triple '" - << TripleName << "'.\n"; - return 1; - } - - OwningPtr<tool_output_file> Out(GetOutputStream()); - if (!Out) - return 1; - - formatted_raw_ostream FOS(Out->os()); - OwningPtr<MCStreamer> Str; - - if (FileType == OFT_AssemblyFile) { - MCInstPrinter *IP = - TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI); - MCCodeEmitter *CE = 0; - if (ShowEncoding) - CE = TheTarget->createCodeEmitter(*TM, Ctx); - Str.reset(createAsmStreamer(Ctx, FOS, - TM->getTargetData()->isLittleEndian(), - /*asmverbose*/true, IP, CE, ShowInst)); - } else if (FileType == OFT_Null) { - Str.reset(createNullStreamer(Ctx)); - } else { - assert(FileType == OFT_ObjectFile && "Invalid file type!"); - MCCodeEmitter *CE = TheTarget->createCodeEmitter(*TM, Ctx); - TargetAsmBackend *TAB = TheTarget->createAsmBackend(TripleName); - Str.reset(TheTarget->createObjectStreamer(TripleName, Ctx, *TAB, - FOS, CE, RelaxAll)); - } - - if (EnableLogging) { - Str.reset(createLoggingStreamer(Str.take(), errs())); - } - - OwningPtr<MCAsmParser> Parser(createMCAsmParser(*TheTarget, SrcMgr, Ctx, - *Str.get(), *MAI)); - OwningPtr<TargetAsmParser> TAP(TheTarget->createAsmParser(*Parser, *TM)); - if (!TAP) { - errs() << ProgName - << ": error: this target does not support assembly parsing.\n"; - return 1; - } - - Parser->setShowParsedOperands(ShowInstOperands); - Parser->setTargetParser(*TAP.get()); - - int Res = Parser->Run(NoInitialTextSection); - - // Keep output if no errors. - if (Res == 0) Out->keep(); - - return Res; -} - -static int DisassembleInput(const char *ProgName, bool Enhanced) { - const Target *TheTarget = GetTarget(ProgName); - if (!TheTarget) - return 0; - - std::string ErrorMessage; - - MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename, - &ErrorMessage); - - if (Buffer == 0) { - errs() << ProgName << ": "; - if (ErrorMessage.size()) - errs() << ErrorMessage << "\n"; - else - errs() << "input file didn't read correctly.\n"; - return 1; - } - - OwningPtr<tool_output_file> Out(GetOutputStream()); - if (!Out) - return 1; - - int Res; - if (Enhanced) - Res = Disassembler::disassembleEnhanced(TripleName, *Buffer, Out->os()); - else - Res = Disassembler::disassemble(*TheTarget, TripleName, *Buffer, Out->os()); - - // Keep output if no errors. - if (Res == 0) Out->keep(); - - return Res; -} - - -int main(int argc, char **argv) { - // Print a stack trace if we signal out. - sys::PrintStackTraceOnErrorSignal(); - PrettyStackTraceProgram X(argc, argv); - llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. - - // Initialize targets and assembly printers/parsers. - llvm::InitializeAllTargetInfos(); - // FIXME: We shouldn't need to initialize the Target(Machine)s. - llvm::InitializeAllTargets(); - llvm::InitializeAllAsmPrinters(); - llvm::InitializeAllAsmParsers(); - llvm::InitializeAllDisassemblers(); - - cl::ParseCommandLineOptions(argc, argv, "llvm machine code playground\n"); - TripleName = Triple::normalize(TripleName); - - switch (Action) { - default: - case AC_AsLex: - return AsLexInput(argv[0]); - case AC_Assemble: - return AssembleInput(argv[0]); - case AC_Disassemble: - return DisassembleInput(argv[0], false); - case AC_EDisassemble: - return DisassembleInput(argv[0], true); - } - - return 0; -} - diff --git a/contrib/llvm/tools/llvm-nm/CMakeLists.txt b/contrib/llvm/tools/llvm-nm/CMakeLists.txt deleted file mode 100644 index 45cf1b6..0000000 --- a/contrib/llvm/tools/llvm-nm/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -set(LLVM_LINK_COMPONENTS archive bitreader) - -add_llvm_tool(llvm-nm - llvm-nm.cpp - ) diff --git a/contrib/llvm/tools/llvm-nm/Makefile b/contrib/llvm/tools/llvm-nm/Makefile deleted file mode 100644 index ecf5f8c..0000000 --- a/contrib/llvm/tools/llvm-nm/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -##===- tools/llvm-nm/Makefile ------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -LEVEL = ../.. - -TOOLNAME = llvm-nm -LINK_COMPONENTS = archive bitreader - -# This tool has no plugins, optimize startup time. -TOOL_NO_EXPORTS = 1 - -include $(LEVEL)/Makefile.common diff --git a/contrib/llvm/tools/llvm-nm/llvm-nm.cpp b/contrib/llvm/tools/llvm-nm/llvm-nm.cpp deleted file mode 100644 index daa8571..0000000 --- a/contrib/llvm/tools/llvm-nm/llvm-nm.cpp +++ /dev/null @@ -1,199 +0,0 @@ -//===-- llvm-nm.cpp - Symbol table dumping utility for llvm ---------------===// -// -// The LLVM Compiler Infrastructure -// -// This file 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/LLVMContext.h" -#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/Support/PrettyStackTrace.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/System/Signals.h" -#include <algorithm> -#include <cctype> -#include <cerrno> -#include <cstring> -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.hasCommonLinkage()) 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) { - // Private linkage and available_externally linkage don't exist in symtab. - if (GV.hasPrivateLinkage() || - GV.hasLinkerPrivateLinkage() || - GV.hasLinkerPrivateWeakLinkage() || - GV.hasLinkerPrivateWeakDefAutoLinkage() || - GV.hasAvailableExternallyLinkage()) - return; - - const std::string SymbolAddrStr = " "; // Not used yet... - char TypeChar = TypeCharForSymbol(GV); - if ((TypeChar != 'U') && UndefinedOnly) - return; - if ((TypeChar == 'U') && DefinedOnly) - return; - if (GV.hasLocalLinkage () && ExternalOnly) - return; - if (OutputFormat == posix) { - outs() << GV.getName () << " " << TypeCharForSymbol(GV) << " " - << SymbolAddrStr << "\n"; - } else if (OutputFormat == bsd) { - outs() << SymbolAddrStr << " " << TypeCharForSymbol(GV) << " " - << GV.getName () << "\n"; - } else if (OutputFormat == sysv) { - std::string PaddedName (GV.getName ()); - while (PaddedName.length () < 20) - PaddedName += " "; - outs() << PaddedName << "|" << SymbolAddrStr << "| " - << TypeCharForSymbol(GV) - << " | | | |\n"; - } -} - -static void DumpSymbolNamesFromModule(Module *M) { - const std::string &Filename = M->getModuleIdentifier (); - if (OutputFormat == posix && MultipleFiles) { - outs() << Filename << ":\n"; - } else if (OutputFormat == bsd && MultipleFiles) { - outs() << "\n" << Filename << ":\n"; - } else if (OutputFormat == sysv) { - outs() << "\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) { - LLVMContext &Context = getGlobalContext(); - 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(), Context, &ErrorMessage); - - if (Result) { - DumpSymbolNamesFromModule(Result); - delete Result; - } else - errs() << ToolName << ": " << Filename << ": " << ErrorMessage << "\n"; - - } else if (aPath.isArchive()) { - std::string ErrMsg; - Archive* archive = Archive::OpenAndLoad(sys::Path(Filename), Context, - &ErrorMessage); - if (!archive) - errs() << ToolName << ": " << Filename << ": " << ErrorMessage << "\n"; - std::vector<Module *> Modules; - if (archive->getAllModules(Modules, &ErrorMessage)) { - errs() << ToolName << ": " << Filename << ": " << ErrorMessage << "\n"; - return; - } - MultipleFiles = true; - std::for_each (Modules.begin(), Modules.end(), DumpSymbolNamesFromModule); - } else { - errs() << ToolName << ": " << Filename << ": " - << "unrecognizable file type\n"; - return; - } -} - -int main(int argc, char **argv) { - // Print a stack trace if we signal out. - sys::PrintStackTraceOnErrorSignal(); - PrettyStackTraceProgram X(argc, argv); - - llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. - cl::ParseCommandLineOptions(argc, argv, "llvm symbol table dumper\n"); - - 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/contrib/llvm/tools/llvm-prof/CMakeLists.txt b/contrib/llvm/tools/llvm-prof/CMakeLists.txt deleted file mode 100644 index 442112b..0000000 --- a/contrib/llvm/tools/llvm-prof/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -set(LLVM_LINK_COMPONENTS bitreader analysis) - -add_llvm_tool(llvm-prof - llvm-prof.cpp - ) diff --git a/contrib/llvm/tools/llvm-prof/Makefile b/contrib/llvm/tools/llvm-prof/Makefile deleted file mode 100644 index 86eb54d..0000000 --- a/contrib/llvm/tools/llvm-prof/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -##===- tools/llvm-prof/Makefile ----------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -LEVEL = ../.. - -TOOLNAME = llvm-prof -LINK_COMPONENTS = bitreader analysis - -# This tool has no plugins, optimize startup time. -TOOL_NO_EXPORTS = 1 - -include $(LEVEL)/Makefile.common diff --git a/contrib/llvm/tools/llvm-prof/llvm-prof.cpp b/contrib/llvm/tools/llvm-prof/llvm-prof.cpp deleted file mode 100644 index 1c63d97..0000000 --- a/contrib/llvm/tools/llvm-prof/llvm-prof.cpp +++ /dev/null @@ -1,291 +0,0 @@ -//===- llvm-prof.cpp - Read in and process llvmprof.out data files --------===// -// -// The LLVM Compiler Infrastructure -// -// This file 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/LLVMContext.h" -#include "llvm/Module.h" -#include "llvm/PassManager.h" -#include "llvm/Assembly/AssemblyAnnotationWriter.h" -#include "llvm/Analysis/ProfileInfo.h" -#include "llvm/Analysis/ProfileInfoLoader.h" -#include "llvm/Analysis/Passes.h" -#include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/FormattedStream.h" -#include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/PrettyStackTrace.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Support/Format.h" -#include "llvm/System/Signals.h" -#include <algorithm> -#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, double>, - std::pair<T, double>, bool> { - bool operator()(const std::pair<T, double> &LHS, - const std::pair<T, double> &RHS) const { - return LHS.second > RHS.second; - } -}; - -static double ignoreMissing(double w) { - if (w == ProfileInfo::MissingValue) return 0; - return w; -} - -namespace { - class ProfileAnnotator : public AssemblyAnnotationWriter { - ProfileInfo &PI; - public: - ProfileAnnotator(ProfileInfo &pi) : PI(pi) {} - - virtual void emitFunctionAnnot(const Function *F, - formatted_raw_ostream &OS) { - double w = PI.getExecutionCount(F); - if (w != ProfileInfo::MissingValue) { - OS << ";;; %" << F->getName() << " called "<<(unsigned)w - <<" times.\n;;;\n"; - } - } - virtual void emitBasicBlockStartAnnot(const BasicBlock *BB, - formatted_raw_ostream &OS) { - double w = PI.getExecutionCount(BB); - if (w != ProfileInfo::MissingValue) { - if (w != 0) { - OS << "\t;;; Basic block executed " << (unsigned)w << " times.\n"; - } else { - OS << "\t;;; Never executed!\n"; - } - } - } - - virtual void emitBasicBlockEndAnnot(const BasicBlock *BB, - formatted_raw_ostream &OS) { - // Figure out how many times each successor executed. - std::vector<std::pair<ProfileInfo::Edge, double> > SuccCounts; - - const TerminatorInst *TI = BB->getTerminator(); - for (unsigned s = 0, e = TI->getNumSuccessors(); s != e; ++s) { - BasicBlock* Succ = TI->getSuccessor(s); - double w = ignoreMissing(PI.getEdgeWeight(std::make_pair(BB, Succ))); - if (w != 0) - SuccCounts.push_back(std::make_pair(std::make_pair(BB, Succ), w)); - } - 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.second->getName() << "]"; - OS << "\n"; - } - } - }; -} - -namespace { - /// ProfileInfoPrinterPass - Helper pass to dump the profile information for - /// a module. - // - // FIXME: This should move elsewhere. - class ProfileInfoPrinterPass : public ModulePass { - ProfileInfoLoader &PIL; - public: - static char ID; // Class identification, replacement for typeinfo. - explicit ProfileInfoPrinterPass(ProfileInfoLoader &_PIL) - : ModulePass(ID), PIL(_PIL) {} - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - AU.addRequired<ProfileInfo>(); - } - - bool runOnModule(Module &M); - }; -} - -char ProfileInfoPrinterPass::ID = 0; - -bool ProfileInfoPrinterPass::runOnModule(Module &M) { - ProfileInfo &PI = getAnalysis<ProfileInfo>(); - std::map<const Function *, unsigned> FuncFreqs; - std::map<const BasicBlock*, unsigned> BlockFreqs; - std::map<ProfileInfo::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*, double> > FunctionCounts; - std::vector<std::pair<BasicBlock*, double> > Counts; - for (Module::iterator FI = M.begin(), FE = M.end(); FI != FE; ++FI) { - if (FI->isDeclaration()) continue; - double w = ignoreMissing(PI.getExecutionCount(FI)); - FunctionCounts.push_back(std::make_pair(FI, w)); - for (Function::iterator BB = FI->begin(), BBE = FI->end(); - BB != BBE; ++BB) { - double w = ignoreMissing(PI.getExecutionCount(BB)); - Counts.push_back(std::make_pair(BB, w)); - } - } - - // Sort by the frequency, backwards. - sort(FunctionCounts.begin(), FunctionCounts.end(), - PairSecondSortReverse<Function*>()); - - double TotalExecutions = 0; - for (unsigned i = 0, e = FunctionCounts.size(); i != e; ++i) - TotalExecutions += FunctionCounts[i].second; - - outs() << "===" << std::string(73, '-') << "===\n" - << "LLVM profiling output for execution"; - if (PIL.getNumExecutions() != 1) outs() << "s"; - outs() << ":\n"; - - for (unsigned i = 0, e = PIL.getNumExecutions(); i != e; ++i) { - outs() << " "; - if (e != 1) outs() << i+1 << ". "; - outs() << PIL.getExecution(i) << "\n"; - } - - outs() << "\n===" << std::string(73, '-') << "===\n"; - outs() << "Function execution frequencies:\n\n"; - - // Print out the function frequencies... - outs() << " ## Frequency\n"; - for (unsigned i = 0, e = FunctionCounts.size(); i != e; ++i) { - if (FunctionCounts[i].second == 0) { - outs() << "\n NOTE: " << e-i << " function" - << (e-i-1 ? "s were" : " was") << " never executed!\n"; - break; - } - - outs() << format("%3d", i+1) << ". " - << format("%5.2g", FunctionCounts[i].second) << "/" - << format("%g", TotalExecutions) << " " - << FunctionCounts[i].first->getNameStr() << "\n"; - } - - std::set<Function*> FunctionsToPrint; - - 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*>()); - - outs() << "\n===" << std::string(73, '-') << "===\n"; - outs() << "Top 20 most frequently executed basic blocks:\n\n"; - - // Print out the function frequencies... - outs() <<" ## %% \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(); - outs() << format("%3d", i+1) << ". " - << format("%5g", Counts[i].second/(double)TotalExecutions*100) << "% " - << format("%5.0f", Counts[i].second) << "/" - << format("%g", TotalExecutions) << "\t" - << F->getNameStr() << "() - " - << Counts[i].first->getNameStr() << "\n"; - FunctionsToPrint.insert(F); - } - - if (PrintAnnotatedLLVM || PrintAllCode) { - outs() << "\n===" << std::string(73, '-') << "===\n"; - outs() << "Annotated LLVM code for the module:\n\n"; - - ProfileAnnotator PA(PI); - - if (FunctionsToPrint.empty() || PrintAllCode) - M.print(outs(), &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(outs(), &PA); - } - - return false; -} - -int main(int argc, char **argv) { - // Print a stack trace if we signal out. - sys::PrintStackTraceOnErrorSignal(); - PrettyStackTraceProgram X(argc, argv); - - LLVMContext &Context = getGlobalContext(); - llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. - - cl::ParseCommandLineOptions(argc, argv, "llvm profile dump decoder\n"); - - // Read in the bitcode file... - std::string ErrorMessage; - Module *M = 0; - if (MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(BitcodeFile, - &ErrorMessage)) { - M = ParseBitcodeFile(Buffer, Context, &ErrorMessage); - delete Buffer; - } - if (M == 0) { - errs() << argv[0] << ": " << BitcodeFile << ": " - << ErrorMessage << "\n"; - return 1; - } - - // Read the profiling information. This is redundant since we load it again - // using the standard profile info provider pass, but for now this gives us - // access to additional information not exposed via the ProfileInfo - // interface. - ProfileInfoLoader PIL(argv[0], ProfileDataFile, *M); - - // Run the printer pass. - PassManager PassMgr; - PassMgr.add(createProfileLoaderPass(ProfileDataFile)); - PassMgr.add(new ProfileInfoPrinterPass(PIL)); - PassMgr.run(*M); - - return 0; -} diff --git a/contrib/llvm/tools/llvm-ranlib/CMakeLists.txt b/contrib/llvm/tools/llvm-ranlib/CMakeLists.txt deleted file mode 100644 index 3116d2e..0000000 --- a/contrib/llvm/tools/llvm-ranlib/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -set(LLVM_LINK_COMPONENTS archive) -set(LLVM_REQUIRES_EH 1) - -add_llvm_tool(llvm-ranlib - llvm-ranlib.cpp - ) diff --git a/contrib/llvm/tools/llvm-ranlib/Makefile b/contrib/llvm/tools/llvm-ranlib/Makefile deleted file mode 100644 index 46a10e6..0000000 --- a/contrib/llvm/tools/llvm-ranlib/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -##===- tools/llvm-ranlib/Makefile --------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL = ../.. -TOOLNAME = llvm-ranlib -LINK_COMPONENTS = archive -REQUIRES_EH := 1 - -# This tool has no plugins, optimize startup time. -TOOL_NO_EXPORTS = 1 - -include $(LEVEL)/Makefile.common diff --git a/contrib/llvm/tools/llvm-ranlib/llvm-ranlib.cpp b/contrib/llvm/tools/llvm-ranlib/llvm-ranlib.cpp deleted file mode 100644 index dffe3ad..0000000 --- a/contrib/llvm/tools/llvm-ranlib/llvm-ranlib.cpp +++ /dev/null @@ -1,101 +0,0 @@ -//===-- llvm-ranlib.cpp - LLVM archive index generator --------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file 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/LLVMContext.h" -#include "llvm/Module.h" -#include "llvm/Bitcode/Archive.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/PrettyStackTrace.h" -#include "llvm/Support/raw_ostream.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) { - // Print a stack trace if we signal out. - llvm::sys::PrintStackTraceOnErrorSignal(); - llvm::PrettyStackTraceProgram X(argc, argv); - - LLVMContext &Context = getGlobalContext(); - llvm_shutdown_obj Y; // 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." - ); - - 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, Context, &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) { - errs() << argv[0] << ": " << msg << "\n\n"; - exitCode = 1; - } catch (const std::string& msg) { - errs() << argv[0] << ": " << msg << "\n"; - exitCode = 2; - } catch (...) { - errs() << argv[0] << ": An unexpected unknown exception occurred.\n"; - exitCode = 3; - } - return exitCode; -} diff --git a/contrib/llvm/tools/llvm-shlib/Makefile b/contrib/llvm/tools/llvm-shlib/Makefile deleted file mode 100644 index 5238130..0000000 --- a/contrib/llvm/tools/llvm-shlib/Makefile +++ /dev/null @@ -1,111 +0,0 @@ -##===- tools/shlib/Makefile --------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL = ../.. - -LIBRARYNAME = LLVM-$(LLVMVersion) - -NO_BUILD_ARCHIVE = 1 -LINK_LIBS_IN_SHARED = 1 -SHARED_LIBRARY = 1 - -include $(LEVEL)/Makefile.config - -ifeq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW)) - EXPORTED_SYMBOL_FILE = $(ObjDir)/$(LIBRARYNAME).exports - - # It is needed to force static-stdc++.a linked. - # FIXME: It should be omitted when configure detects system's stdc++.dll. - SHLIB_FRAG_NAMES += stdc++.a.o - -endif - -include $(LEVEL)/Makefile.common - -# Include all archives in libLLVM.(so|dylib) except the ones that have -# their own dynamic libraries. -Archives := $(wildcard $(LibDir)/libLLVM*.a) -SharedLibraries := $(wildcard $(LibDir)/libLLVM*$(SHLIBEXT)) -IncludeInLibLlvm := $(filter-out $(basename $(SharedLibraries)).a, $(Archives)) -LLVMLibsOptions := $(IncludeInLibLlvm:$(LibDir)/lib%.a=-l%) -LLVMLibsPaths := $(IncludeInLibLlvm) - -$(LibName.SO): $(LLVMLibsPaths) - -ifeq ($(HOST_OS),Darwin) - # set dylib internal version number to llvmCore submission number - ifdef LLVM_SUBMIT_VERSION - LLVMLibsOptions := $(LLVMLibsOptions) -Wl,-current_version \ - -Wl,$(LLVM_SUBMIT_VERSION).$(LLVM_SUBMIT_SUBVERSION) \ - -Wl,-compatibility_version -Wl,1 - endif - # Include everything from the .a's into the shared library. - LLVMLibsOptions := $(LLVMLibsOptions) -all_load - # extra options to override libtool defaults - LLVMLibsOptions := $(LLVMLibsOptions) \ - -Wl,-dead_strip \ - -Wl,-seg1addr -Wl,0xE0000000 - - # Mac OS X 10.4 and earlier tools do not allow a second -install_name on command line - DARWIN_VERS := $(shell echo $(TARGET_TRIPLE) | sed 's/.*darwin\([0-9]*\).*/\1/') - ifneq ($(DARWIN_VERS),8) - LLVMLibsOptions := $(LLVMLibsOptions) \ - -Wl,-install_name \ - -Wl,"@executable_path/../lib/lib$(LIBRARYNAME)$(SHLIBEXT)" - endif -endif - -ifeq ($(HOST_OS), Linux) - # Include everything from the .a's into the shared library. - LLVMLibsOptions := -Wl,--whole-archive $(LLVMLibsOptions) \ - -Wl,--no-whole-archive - # Don't allow unresolved symbols. - LLVMLibsOptions += -Wl,--no-undefined -endif - -ifeq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW)) - -SHLIB_STUBS := $(addprefix $(ObjDir)/, $(SHLIB_FRAG_NAMES)) -SHLIB_FRAGS := $(patsubst %.a.o, $(ObjDir)/%.syms.txt, $(LIBRARYNAME).a.o $(SHLIB_FRAG_NAMES)) -LLVMLibsOptions := $(SHLIB_STUBS) $(LLVMLibsOptions) - -$(LibName.SO): $(SHLIB_STUBS) - -%.syms.txt: %.a.o - $(Echo) Collecting global symbols of $(notdir $*) - $(Verb) $(NM_PATH) -g $< > $@ - -$(ObjDir)/$(LIBRARYNAME).exports: $(SHLIB_FRAGS) $(ObjDir)/.dir - $(Echo) Generating exports for $(LIBRARYNAME) - $(Verb) ($(SED) -n \ - -e "s/^.* T _\([^.][^.]*\)$$/\1/p" \ - -e "s/^.* [BDR] _\([^.][^.]*\)$$/\1 DATA/p" \ - $(SHLIB_FRAGS) \ - | sort -u) > $@ - -$(ObjDir)/$(LIBRARYNAME).a.o: $(LLVMLibsPaths) $(ObjDir)/.dir - $(Echo) Linking all LLVMLibs together for $(LIBRARYNAME) - $(Verb) $(Link) -nostartfiles -Wl,-r -nodefaultlibs -o $@ \ - -Wl,--whole-archive $(LLVMLibsPaths) \ - -Wl,--no-whole-archive - -$(ObjDir)/stdc++.a.o: $(ObjDir)/.dir - $(Echo) Linking all libs together for static libstdc++.a - $(Verb) $(Link) -nostartfiles -Wl,-r -nodefaultlibs -o $@ \ - -Wl,--whole-archive -lstdc++ \ - -Wl,--no-whole-archive -# FIXME: workaround to invalidate -lstdc++ - $(Echo) Making dummy -lstdc++ to lib - $(Verb) $(AR) rc $(ToolDir)/libstdc++.dll.a -# FIXME: Is install-local needed? - -clean-local:: - $(Verb) $(RM) -f $(ToolDir)/libstdc++.dll.a - -endif diff --git a/contrib/llvm/tools/llvm-stub/CMakeLists.txt b/contrib/llvm/tools/llvm-stub/CMakeLists.txt deleted file mode 100644 index a98dc9e..0000000 --- a/contrib/llvm/tools/llvm-stub/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -add_llvm_tool(llvm-stub - llvm-stub.c - ) diff --git a/contrib/llvm/tools/llvm-stub/Makefile b/contrib/llvm/tools/llvm-stub/Makefile deleted file mode 100644 index 7ffe149..0000000 --- a/contrib/llvm/tools/llvm-stub/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -##===- tools/llvm-stub/Makefile ----------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL = ../.. -TOOLNAME = llvm-stub -include $(LEVEL)/Makefile.common - diff --git a/contrib/llvm/tools/llvm-stub/llvm-stub.c b/contrib/llvm/tools/llvm-stub/llvm-stub.c deleted file mode 100644 index f2e478e..0000000 --- a/contrib/llvm/tools/llvm-stub/llvm-stub.c +++ /dev/null @@ -1,73 +0,0 @@ -/*===- llvm-stub.c - Stub executable to run llvm bitcode files ------------===// -// -// The LLVM Compiler Infrastructure -// -// This file 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 LLVM_ON_WIN32 - { - int len = strlen(argv[0]); - if (len < 4 || strcmp(argv[0] + len - 4, ".exe") != 0) { - /* .exe suffix is stripped off of argv[0] if the executable was run on the - * command line without one. Put it back on. - */ - argv[0] = strcat(strcpy((char*)malloc(len + 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((char **)Args+2, argv+1, sizeof(char*)*argc); - - /* Run the JIT. */ - execvp(Interp, (char **)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/contrib/llvm/tools/llvmc/CMakeLists.txt b/contrib/llvm/tools/llvmc/CMakeLists.txt deleted file mode 100644 index 10ad5d8..0000000 --- a/contrib/llvm/tools/llvmc/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -# add_subdirectory(src) - -# TODO: support plugins and user-configured builds. -# See ./doc/LLVMC-Reference.rst "Customizing LLVMC: the compilation graph" diff --git a/contrib/llvm/tools/llvmc/Makefile b/contrib/llvm/tools/llvmc/Makefile deleted file mode 100644 index 7c03e2a..0000000 --- a/contrib/llvm/tools/llvmc/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -##===- tools/llvmc/Makefile --------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open -# Source License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL = ../.. - -DIRS = src - -ifeq ($(BUILD_EXAMPLES),1) - OPTIONAL_DIRS += examples -endif - -include $(LEVEL)/Makefile.common diff --git a/contrib/llvm/tools/llvmc/doc/LLVMC-Reference.rst b/contrib/llvm/tools/llvmc/doc/LLVMC-Reference.rst deleted file mode 100644 index d160e75..0000000 --- a/contrib/llvm/tools/llvmc/doc/LLVMC-Reference.rst +++ /dev/null @@ -1,839 +0,0 @@ -=================================== -Customizing LLVMC: Reference Manual -=================================== -.. - This file was automatically generated by rst2html. - Please do not edit directly! - The ReST source lives in the directory 'tools/llvmc/doc'. - -.. contents:: - -.. raw:: html - - <div class="doc_author"> - <p>Written by <a href="mailto:foldr@codedgers.com">Mikhail Glushenkov</a></p> - </div> - -Introduction -============ - -LLVMC is a generic compiler driver, designed to be customizable and -extensible. It plays the same role for LLVM as the ``gcc`` program -does for GCC - LLVMC's job is essentially to transform a set of input -files into a set of targets depending on configuration rules and user -options. What makes LLVMC different is that these transformation rules -are completely customizable - in fact, LLVMC knows nothing about the -specifics of transformation (even the command-line options are mostly -not hard-coded) and regards the transformation structure as an -abstract graph. The structure of this graph is completely determined -by plugins, which can be either statically or dynamically linked. This -makes it possible to easily adapt LLVMC for other purposes - for -example, as a build tool for game resources. - -Because LLVMC employs TableGen_ as its configuration language, you -need to be familiar with it to customize LLVMC. - -.. _TableGen: http://llvm.org/docs/TableGenFundamentals.html - - -Compiling with LLVMC -==================== - -LLVMC tries hard to be as compatible with ``gcc`` as possible, -although there are some small differences. Most of the time, however, -you shouldn't be able to notice them:: - - $ # This works as expected: - $ llvmc -O3 -Wall hello.cpp - $ ./a.out - hello - -One nice feature of LLVMC is that one doesn't have to distinguish between -different compilers for different languages (think ``g++`` vs. ``gcc``) - the -right toolchain is chosen automatically based on input language names (which -are, in turn, determined from file extensions). If you want to force files -ending with ".c" to compile as C++, use the ``-x`` option, just like you would -do it with ``gcc``:: - - $ # hello.c is really a C++ file - $ llvmc -x c++ hello.c - $ ./a.out - hello - -On the other hand, when using LLVMC as a linker to combine several C++ -object files you should provide the ``--linker`` option since it's -impossible for LLVMC to choose the right linker in that case:: - - $ llvmc -c hello.cpp - $ llvmc hello.o - [A lot of link-time errors skipped] - $ llvmc --linker=c++ hello.o - $ ./a.out - hello - -By default, LLVMC uses ``llvm-gcc`` to compile the source code. It is also -possible to choose the ``clang`` compiler with the ``-clang`` option. - - -Predefined options -================== - -LLVMC has some built-in options that can't be overridden in the -configuration libraries: - -* ``-o FILE`` - Output file name. - -* ``-x LANGUAGE`` - Specify the language of the following input files - until the next -x option. - -* ``-load PLUGIN_NAME`` - Load the specified plugin DLL. Example: - ``-load $LLVM_DIR/Release/lib/LLVMCSimple.so``. - -* ``-v`` - Enable verbose mode, i.e. print out all executed commands. - -* ``--save-temps`` - Write temporary files to the current directory and do not - delete them on exit. This option can also take an argument: the - ``--save-temps=obj`` switch will write files into the directory specified with - the ``-o`` option. The ``--save-temps=cwd`` and ``--save-temps`` switches are - both synonyms for the default behaviour. - -* ``--temp-dir DIRECTORY`` - Store temporary files in the given directory. This - directory is deleted on exit unless ``--save-temps`` is specified. If - ``--save-temps=obj`` is also specified, ``--temp-dir`` is given the - precedence. - -* ``--check-graph`` - Check the compilation for common errors like mismatched - output/input language names, multiple default edges and cycles. Because of - plugins, these checks can't be performed at compile-time. Exit with code zero - if no errors were found, and return the number of found errors - otherwise. Hidden option, useful for debugging LLVMC plugins. - -* ``--view-graph`` - Show a graphical representation of the compilation graph - and exit. Requires that you have ``dot`` and ``gv`` programs installed. Hidden - option, useful for debugging LLVMC plugins. - -* ``--write-graph`` - Write a ``compilation-graph.dot`` file in the current - directory with the compilation graph description in Graphviz format (identical - to the file used by the ``--view-graph`` option). The ``-o`` option can be - used to set the output file name. Hidden option, useful for debugging LLVMC - plugins. - -* ``--help``, ``--help-hidden``, ``--version`` - These options have - their standard meaning. - -Compiling LLVMC plugins -======================= - -It's easiest to start working on your own LLVMC plugin by copying the -skeleton project which lives under ``$LLVMC_DIR/plugins/Simple``:: - - $ cd $LLVMC_DIR/plugins - $ cp -r Simple MyPlugin - $ cd MyPlugin - $ ls - Makefile PluginMain.cpp Simple.td - -As you can see, our basic plugin consists of only two files (not -counting the build script). ``Simple.td`` contains TableGen -description of the compilation graph; its format is documented in the -following sections. ``PluginMain.cpp`` is just a helper file used to -compile the auto-generated C++ code produced from TableGen source. It -can also contain hook definitions (see `below`__). - -__ hooks_ - -The first thing that you should do is to change the ``LLVMC_PLUGIN`` -variable in the ``Makefile`` to avoid conflicts (since this variable -is used to name the resulting library):: - - LLVMC_PLUGIN=MyPlugin - -It is also a good idea to rename ``Simple.td`` to something less -generic:: - - $ mv Simple.td MyPlugin.td - -To build your plugin as a dynamic library, just ``cd`` to its source -directory and run ``make``. The resulting file will be called -``plugin_llvmc_$(LLVMC_PLUGIN).$(DLL_EXTENSION)`` (in our case, -``plugin_llvmc_MyPlugin.so``). This library can be then loaded in with the -``-load`` option. Example:: - - $ cd $LLVMC_DIR/plugins/Simple - $ make - $ llvmc -load $LLVM_DIR/Release/lib/plugin_llvmc_Simple.so - -Compiling standalone LLVMC-based drivers -======================================== - -By default, the ``llvmc`` executable consists of a driver core plus several -statically linked plugins (``Base`` and ``Clang`` at the moment). You can -produce a standalone LLVMC-based driver executable by linking the core with your -own plugins. The recommended way to do this is by starting with the provided -``Skeleton`` example (``$LLVMC_DIR/example/Skeleton``):: - - $ cd $LLVMC_DIR/example/ - $ cp -r Skeleton mydriver - $ cd mydriver - $ vim Makefile - [...] - $ make - -If you're compiling LLVM with different source and object directories, then you -must perform the following additional steps before running ``make``:: - - # LLVMC_SRC_DIR = $LLVM_SRC_DIR/tools/llvmc/ - # LLVMC_OBJ_DIR = $LLVM_OBJ_DIR/tools/llvmc/ - $ cp $LLVMC_SRC_DIR/example/mydriver/Makefile \ - $LLVMC_OBJ_DIR/example/mydriver/ - $ cd $LLVMC_OBJ_DIR/example/mydriver - $ make - -Another way to do the same thing is by using the following command:: - - $ cd $LLVMC_DIR - $ make LLVMC_BUILTIN_PLUGINS=MyPlugin LLVMC_BASED_DRIVER_NAME=mydriver - -This works with both srcdir == objdir and srcdir != objdir, but assumes that the -plugin source directory was placed under ``$LLVMC_DIR/plugins``. - -Sometimes, you will want a 'bare-bones' version of LLVMC that has no -built-in plugins. It can be compiled with the following command:: - - $ cd $LLVMC_DIR - $ make LLVMC_BUILTIN_PLUGINS="" - - -Customizing LLVMC: the compilation graph -======================================== - -Each TableGen configuration file should include the common -definitions:: - - include "llvm/CompilerDriver/Common.td" - -Internally, LLVMC stores information about possible source -transformations in form of a graph. Nodes in this graph represent -tools, and edges between two nodes represent a transformation path. A -special "root" node is used to mark entry points for the -transformations. LLVMC also assigns a weight to each edge (more on -this later) to choose between several alternative edges. - -The definition of the compilation graph (see file -``plugins/Base/Base.td`` for an example) is just a list of edges:: - - def CompilationGraph : CompilationGraph<[ - Edge<"root", "llvm_gcc_c">, - Edge<"root", "llvm_gcc_assembler">, - ... - - Edge<"llvm_gcc_c", "llc">, - Edge<"llvm_gcc_cpp", "llc">, - ... - - OptionalEdge<"llvm_gcc_c", "opt", (case (switch_on "opt"), - (inc_weight))>, - OptionalEdge<"llvm_gcc_cpp", "opt", (case (switch_on "opt"), - (inc_weight))>, - ... - - OptionalEdge<"llvm_gcc_assembler", "llvm_gcc_cpp_linker", - (case (input_languages_contain "c++"), (inc_weight), - (or (parameter_equals "linker", "g++"), - (parameter_equals "linker", "c++")), (inc_weight))>, - ... - - ]>; - -As you can see, the edges can be either default or optional, where -optional edges are differentiated by an additional ``case`` expression -used to calculate the weight of this edge. Notice also that we refer -to tools via their names (as strings). This makes it possible to add -edges to an existing compilation graph in plugins without having to -know about all tool definitions used in the graph. - -The default edges are assigned a weight of 1, and optional edges get a -weight of 0 + 2*N where N is the number of tests that evaluated to -true in the ``case`` expression. It is also possible to provide an -integer parameter to ``inc_weight`` and ``dec_weight`` - in this case, -the weight is increased (or decreased) by the provided value instead -of the default 2. It is also possible to change the default weight of -an optional edge by using the ``default`` clause of the ``case`` -construct. - -When passing an input file through the graph, LLVMC picks the edge -with the maximum weight. To avoid ambiguity, there should be only one -default edge between two nodes (with the exception of the root node, -which gets a special treatment - there you are allowed to specify one -default edge *per language*). - -When multiple plugins are loaded, their compilation graphs are merged -together. Since multiple edges that have the same end nodes are not -allowed (i.e. the graph is not a multigraph), an edge defined in -several plugins will be replaced by the definition from the plugin -that was loaded last. Plugin load order can be controlled by using the -plugin priority feature described above. - -To get a visual representation of the compilation graph (useful for -debugging), run ``llvmc --view-graph``. You will need ``dot`` and -``gsview`` installed for this to work properly. - -Describing options -================== - -Command-line options that the plugin supports are defined by using an -``OptionList``:: - - def Options : OptionList<[ - (switch_option "E", (help "Help string")), - (alias_option "quiet", "q") - ... - ]>; - -As you can see, the option list is just a list of DAGs, where each DAG -is an option description consisting of the option name and some -properties. A plugin can define more than one option list (they are -all merged together in the end), which can be handy if one wants to -separate option groups syntactically. - -* Possible option types: - - - ``switch_option`` - a simple boolean switch without arguments, for example - ``-O2`` or ``-time``. At most one occurrence is allowed by default. - - - ``parameter_option`` - option that takes one argument, for example - ``-std=c99``. It is also allowed to use spaces instead of the equality - sign: ``-std c99``. At most one occurrence is allowed. - - - ``parameter_list_option`` - same as the above, but more than one option - occurence is allowed. - - - ``prefix_option`` - same as the parameter_option, but the option name and - argument do not have to be separated. Example: ``-ofile``. This can be also - specified as ``-o file``; however, ``-o=file`` will be parsed incorrectly - (``=file`` will be interpreted as option value). At most one occurrence is - allowed. - - - ``prefix_list_option`` - same as the above, but more than one occurence of - the option is allowed; example: ``-lm -lpthread``. - - - ``alias_option`` - a special option type for creating aliases. Unlike other - option types, aliases are not allowed to have any properties besides the - aliased option name. Usage example: ``(alias_option "preprocess", "E")`` - - - ``switch_list_option`` - like ``switch_option`` with the ``zero_or_more`` - property, but remembers how many times the switch was turned on. Useful - mostly for forwarding. Example: when ``-foo`` is a switch option (with the - ``zero_or_more`` property), the command ``driver -foo -foo`` is forwarded - as ``some-tool -foo``, but when ``-foo`` is a switch list, the same command - is forwarded as ``some-tool -foo -foo``. - - -* Possible option properties: - - - ``help`` - help string associated with this option. Used for ``--help`` - output. - - - ``required`` - this option must be specified exactly once (or, in case of - the list options without the ``multi_val`` property, at least - once). Incompatible with ``optional`` and ``one_or_more``. - - - ``optional`` - the option can be specified either zero times or exactly - once. The default for switch options. Useful only for list options in - conjunction with ``multi_val``. Incompatible with ``required``, - ``zero_or_more`` and ``one_or_more``. - - - ``one_or_more`` - the option must be specified at least once. Can be useful - to allow switch options be both obligatory and be specified multiple - times. For list options is useful only in conjunction with ``multi_val``; - for ordinary it is synonymous with ``required``. Incompatible with - ``required``, ``optional`` and ``zero_or_more``. - - - ``zero_or_more`` - the option can be specified zero or more times. Useful - to allow a single switch option to be specified more than - once. Incompatible with ``required``, ``optional`` and ``one_or_more``. - - - ``hidden`` - the description of this option will not appear in - the ``--help`` output (but will appear in the ``--help-hidden`` - output). - - - ``really_hidden`` - the option will not be mentioned in any help - output. - - - ``comma_separated`` - Indicates that any commas specified for an option's - value should be used to split the value up into multiple values for the - option. This property is valid only for list options. In conjunction with - ``forward_value`` can be used to implement option forwarding in style of - gcc's ``-Wa,``. - - - ``multi_val n`` - this option takes *n* arguments (can be useful in some - special cases). Usage example: ``(parameter_list_option "foo", (multi_val - 3))``; the command-line syntax is '-foo a b c'. Only list options can have - this attribute; you can, however, use the ``one_or_more``, ``optional`` - and ``required`` properties. - - - ``init`` - this option has a default value, either a string (if it is a - parameter), or a boolean (if it is a switch; as in C++, boolean constants - are called ``true`` and ``false``). List options can't have ``init`` - attribute. - Usage examples: ``(switch_option "foo", (init true))``; ``(prefix_option - "bar", (init "baz"))``. - - - ``extern`` - this option is defined in some other plugin, see `below`__. - - __ extern_ - -.. _extern: - -External options ----------------- - -Sometimes, when linking several plugins together, one plugin needs to -access options defined in some other plugin. Because of the way -options are implemented, such options must be marked as -``extern``. This is what the ``extern`` option property is -for. Example:: - - ... - (switch_option "E", (extern)) - ... - -If an external option has additional attributes besides 'extern', they are -ignored. See also the section on plugin `priorities`__. - -__ priorities_ - -.. _case: - -Conditional evaluation -====================== - -The 'case' construct is the main means by which programmability is -achieved in LLVMC. It can be used to calculate edge weights, program -actions and modify the shell commands to be executed. The 'case' -expression is designed after the similarly-named construct in -functional languages and takes the form ``(case (test_1), statement_1, -(test_2), statement_2, ... (test_N), statement_N)``. The statements -are evaluated only if the corresponding tests evaluate to true. - -Examples:: - - // Edge weight calculation - - // Increases edge weight by 5 if "-A" is provided on the - // command-line, and by 5 more if "-B" is also provided. - (case - (switch_on "A"), (inc_weight 5), - (switch_on "B"), (inc_weight 5)) - - - // Tool command line specification - - // Evaluates to "cmdline1" if the option "-A" is provided on the - // command line; to "cmdline2" if "-B" is provided; - // otherwise to "cmdline3". - - (case - (switch_on "A"), "cmdline1", - (switch_on "B"), "cmdline2", - (default), "cmdline3") - -Note the slight difference in 'case' expression handling in contexts -of edge weights and command line specification - in the second example -the value of the ``"B"`` switch is never checked when switch ``"A"`` is -enabled, and the whole expression always evaluates to ``"cmdline1"`` in -that case. - -Case expressions can also be nested, i.e. the following is legal:: - - (case (switch_on "E"), (case (switch_on "o"), ..., (default), ...) - (default), ...) - -You should, however, try to avoid doing that because it hurts -readability. It is usually better to split tool descriptions and/or -use TableGen inheritance instead. - -* Possible tests are: - - - ``switch_on`` - Returns true if a given command-line switch is provided by - the user. Can be given a list as argument, in that case ``(switch_on ["foo", - "bar", "baz"])`` is equivalent to ``(and (switch_on "foo"), (switch_on - "bar"), (switch_on "baz"))``. - Example: ``(switch_on "opt")``. - - - ``any_switch_on`` - Given a list of switch options, returns true if any of - the switches is turned on. - Example: ``(any_switch_on ["foo", "bar", "baz"])`` is equivalent to ``(or - (switch_on "foo"), (switch_on "bar"), (switch_on "baz"))``. - - - ``parameter_equals`` - Returns true if a command-line parameter equals - a given value. - Example: ``(parameter_equals "W", "all")``. - - - ``element_in_list`` - Returns true if a command-line parameter - list contains a given value. - Example: ``(element_in_list "l", "pthread")``. - - - ``input_languages_contain`` - Returns true if a given language - belongs to the current input language set. - Example: ``(input_languages_contain "c++")``. - - - ``in_language`` - Evaluates to true if the input file language is equal to - the argument. At the moment works only with ``cmd_line`` and ``actions`` (on - non-join nodes). - Example: ``(in_language "c++")``. - - - ``not_empty`` - Returns true if a given option (which should be either a - parameter or a parameter list) is set by the user. Like ``switch_on``, can - be also given a list as argument. - Example: ``(not_empty "o")``. - - - ``any_not_empty`` - Returns true if ``not_empty`` returns true for any of - the options in the list. - Example: ``(any_not_empty ["foo", "bar", "baz"])`` is equivalent to ``(or - (not_empty "foo"), (not_empty "bar"), (not_empty "baz"))``. - - - ``empty`` - The opposite of ``not_empty``. Equivalent to ``(not (not_empty - X))``. Provided for convenience. Can be given a list as argument. - - - ``any_not_empty`` - Returns true if ``not_empty`` returns true for any of - the options in the list. - Example: ``(any_empty ["foo", "bar", "baz"])`` is equivalent to ``(not (and - (not_empty "foo"), (not_empty "bar"), (not_empty "baz")))``. - - - ``single_input_file`` - Returns true if there was only one input file - provided on the command-line. Used without arguments: - ``(single_input_file)``. - - - ``multiple_input_files`` - Equivalent to ``(not (single_input_file))`` (the - case of zero input files is considered an error). - - - ``default`` - Always evaluates to true. Should always be the last - test in the ``case`` expression. - - - ``and`` - A standard binary logical combinator that returns true iff all of - its arguments return true. Used like this: ``(and (test1), (test2), - ... (testN))``. Nesting of ``and`` and ``or`` is allowed, but not - encouraged. - - - ``or`` - A binary logical combinator that returns true iff any of its - arguments returns true. Example: ``(or (test1), (test2), ... (testN))``. - - - ``not`` - Standard unary logical combinator that negates its - argument. Example: ``(not (or (test1), (test2), ... (testN)))``. - - - -Writing a tool description -========================== - -As was said earlier, nodes in the compilation graph represent tools, -which are described separately. A tool definition looks like this -(taken from the ``include/llvm/CompilerDriver/Tools.td`` file):: - - def llvm_gcc_cpp : Tool<[ - (in_language "c++"), - (out_language "llvm-assembler"), - (output_suffix "bc"), - (cmd_line "llvm-g++ -c $INFILE -o $OUTFILE -emit-llvm"), - (sink) - ]>; - -This defines a new tool called ``llvm_gcc_cpp``, which is an alias for -``llvm-g++``. As you can see, a tool definition is just a list of -properties; most of them should be self-explanatory. The ``sink`` -property means that this tool should be passed all command-line -options that aren't mentioned in the option list. - -The complete list of all currently implemented tool properties follows. - -* Possible tool properties: - - - ``in_language`` - input language name. Can be either a string or a - list, in case the tool supports multiple input languages. - - - ``out_language`` - output language name. Multiple output languages are not - allowed. - - - ``output_suffix`` - output file suffix. Can also be changed - dynamically, see documentation on actions. - - - ``cmd_line`` - the actual command used to run the tool. You can - use ``$INFILE`` and ``$OUTFILE`` variables, output redirection - with ``>``, hook invocations (``$CALL``), environment variables - (via ``$ENV``) and the ``case`` construct. - - - ``join`` - this tool is a "join node" in the graph, i.e. it gets a - list of input files and joins them together. Used for linkers. - - - ``sink`` - all command-line options that are not handled by other - tools are passed to this tool. - - - ``actions`` - A single big ``case`` expression that specifies how - this tool reacts on command-line options (described in more detail - `below`__). - -__ actions_ - -.. _actions: - -Actions -------- - -A tool often needs to react to command-line options, and this is -precisely what the ``actions`` property is for. The next example -illustrates this feature:: - - def llvm_gcc_linker : Tool<[ - (in_language "object-code"), - (out_language "executable"), - (output_suffix "out"), - (cmd_line "llvm-gcc $INFILE -o $OUTFILE"), - (join), - (actions (case (not_empty "L"), (forward "L"), - (not_empty "l"), (forward "l"), - (not_empty "dummy"), - [(append_cmd "-dummy1"), (append_cmd "-dummy2")]) - ]>; - -The ``actions`` tool property is implemented on top of the omnipresent -``case`` expression. It associates one or more different *actions* -with given conditions - in the example, the actions are ``forward``, -which forwards a given option unchanged, and ``append_cmd``, which -appends a given string to the tool execution command. Multiple actions -can be associated with a single condition by using a list of actions -(used in the example to append some dummy options). The same ``case`` -construct can also be used in the ``cmd_line`` property to modify the -tool command line. - -The "join" property used in the example means that this tool behaves -like a linker. - -The list of all possible actions follows. - -* Possible actions: - - - ``append_cmd`` - Append a string to the tool invocation command. - Example: ``(case (switch_on "pthread"), (append_cmd "-lpthread"))``. - - - ``error`` - Exit with error. - Example: ``(error "Mixing -c and -S is not allowed!")``. - - - ``warning`` - Print a warning. - Example: ``(warning "Specifying both -O1 and -O2 is meaningless!")``. - - - ``forward`` - Forward the option unchanged. - Example: ``(forward "Wall")``. - - - ``forward_as`` - Change the option's name, but forward the argument - unchanged. - Example: ``(forward_as "O0", "--disable-optimization")``. - - - ``forward_value`` - Forward only option's value. Cannot be used with switch - options (since they don't have values), but works fine with lists. - Example: ``(forward_value "Wa,")``. - - - ``forward_transformed_value`` - As above, but applies a hook to the - option's value before forwarding (see `below`__). When - ``forward_transformed_value`` is applied to a list - option, the hook must have signature - ``std::string hooks::HookName (const std::vector<std::string>&)``. - Example: ``(forward_transformed_value "m", "ConvertToMAttr")``. - - __ hooks_ - - - ``output_suffix`` - Modify the output suffix of this tool. - Example: ``(output_suffix "i")``. - - - ``stop_compilation`` - Stop compilation after this tool processes its - input. Used without arguments. - Example: ``(stop_compilation)``. - - -Language map -============ - -If you are adding support for a new language to LLVMC, you'll need to -modify the language map, which defines mappings from file extensions -to language names. It is used to choose the proper toolchain(s) for a -given input file set. Language map definition looks like this:: - - def LanguageMap : LanguageMap< - [LangToSuffixes<"c++", ["cc", "cp", "cxx", "cpp", "CPP", "c++", "C"]>, - LangToSuffixes<"c", ["c"]>, - ... - ]>; - -For example, without those definitions the following command wouldn't work:: - - $ llvmc hello.cpp - llvmc: Unknown suffix: cpp - -The language map entries are needed only for the tools that are linked from the -root node. Since a tool can't have multiple output languages, for inner nodes of -the graph the input and output languages should match. This is enforced at -compile-time. - -Option preprocessor -=================== - -It is sometimes useful to run error-checking code before processing the -compilation graph. For example, if optimization options "-O1" and "-O2" are -implemented as switches, we might want to output a warning if the user invokes -the driver with both of these options enabled. - -The ``OptionPreprocessor`` feature is reserved specially for these -occasions. Example (adapted from the built-in Base plugin):: - - - def Preprocess : OptionPreprocessor< - (case (not (any_switch_on ["O0", "O1", "O2", "O3"])), - (set_option "O2"), - (and (switch_on "O3"), (any_switch_on ["O0", "O1", "O2"])), - (unset_option ["O0", "O1", "O2"]), - (and (switch_on "O2"), (any_switch_on ["O0", "O1"])), - (unset_option ["O0", "O1"]), - (and (switch_on "O1"), (switch_on "O0")), - (unset_option "O0")) - >; - -Here, ``OptionPreprocessor`` is used to unset all spurious ``-O`` options so -that they are not forwarded to the compiler. If no optimization options are -specified, ``-O2`` is enabled. - -``OptionPreprocessor`` is basically a single big ``case`` expression, which is -evaluated only once right after the plugin is loaded. The only allowed actions -in ``OptionPreprocessor`` are ``error``, ``warning``, and two special actions: -``unset_option`` and ``set_option``. As their names suggest, they can be used to -set or unset a given option. To set an option with ``set_option``, use the -two-argument form: ``(set_option "parameter", VALUE)``. Here, ``VALUE`` can be -either a string, a string list, or a boolean constant. - -For convenience, ``set_option`` and ``unset_option`` also work on lists. That -is, instead of ``[(unset_option "A"), (unset_option "B")]`` you can use -``(unset_option ["A", "B"])``. Obviously, ``(set_option ["A", "B"])`` is valid -only if both ``A`` and ``B`` are switches. - - -More advanced topics -==================== - -.. _hooks: - -Hooks and environment variables -------------------------------- - -Normally, LLVMC executes programs from the system ``PATH``. Sometimes, -this is not sufficient: for example, we may want to specify tool paths -or names in the configuration file. This can be easily achieved via -the hooks mechanism. To write your own hooks, just add their -definitions to the ``PluginMain.cpp`` or drop a ``.cpp`` file into the -your plugin directory. Hooks should live in the ``hooks`` namespace -and have the signature ``std::string hooks::MyHookName ([const char* -Arg0 [ const char* Arg2 [, ...]]])``. They can be used from the -``cmd_line`` tool property:: - - (cmd_line "$CALL(MyHook)/path/to/file -o $CALL(AnotherHook)") - -To pass arguments to hooks, use the following syntax:: - - (cmd_line "$CALL(MyHook, 'Arg1', 'Arg2', 'Arg # 3')/path/to/file -o1 -o2") - -It is also possible to use environment variables in the same manner:: - - (cmd_line "$ENV(VAR1)/path/to/file -o $ENV(VAR2)") - -To change the command line string based on user-provided options use -the ``case`` expression (documented `above`__):: - - (cmd_line - (case - (switch_on "E"), - "llvm-g++ -E -x c $INFILE -o $OUTFILE", - (default), - "llvm-g++ -c -x c $INFILE -o $OUTFILE -emit-llvm")) - -__ case_ - -.. _priorities: - -How plugins are loaded ----------------------- - -It is possible for LLVMC plugins to depend on each other. For example, -one can create edges between nodes defined in some other plugin. To -make this work, however, that plugin should be loaded first. To -achieve this, the concept of plugin priority was introduced. By -default, every plugin has priority zero; to specify the priority -explicitly, put the following line in your plugin's TableGen file:: - - def Priority : PluginPriority<$PRIORITY_VALUE>; - # Where PRIORITY_VALUE is some integer > 0 - -Plugins are loaded in order of their (increasing) priority, starting -with 0. Therefore, the plugin with the highest priority value will be -loaded last. - -Debugging ---------- - -When writing LLVMC plugins, it can be useful to get a visual view of -the resulting compilation graph. This can be achieved via the command -line option ``--view-graph``. This command assumes that Graphviz_ and -Ghostview_ are installed. There is also a ``--write-graph`` option that -creates a Graphviz source file (``compilation-graph.dot``) in the -current directory. - -Another useful ``llvmc`` option is ``--check-graph``. It checks the -compilation graph for common errors like mismatched output/input -language names, multiple default edges and cycles. These checks can't -be performed at compile-time because the plugins can load code -dynamically. When invoked with ``--check-graph``, ``llvmc`` doesn't -perform any compilation tasks and returns the number of encountered -errors as its status code. - -.. _Graphviz: http://www.graphviz.org/ -.. _Ghostview: http://pages.cs.wisc.edu/~ghost/ - -Conditioning on the executable name ------------------------------------ - -For now, the executable name (the value passed to the driver in ``argv[0]``) is -accessible only in the C++ code (i.e. hooks). Use the following code:: - - namespace llvmc { - extern const char* ProgramName; - } - - namespace hooks { - - std::string MyHook() { - //... - if (strcmp(ProgramName, "mydriver") == 0) { - //... - - } - - } // end namespace hooks - -In general, you're encouraged not to make the behaviour dependent on the -executable file name, and use command-line switches instead. See for example how -the ``Base`` plugin behaves when it needs to choose the correct linker options -(think ``g++`` vs. ``gcc``). - -.. raw:: html - - <hr /> - <address> - <a href="http://jigsaw.w3.org/css-validator/check/referer"> - <img src="http://jigsaw.w3.org/css-validator/images/vcss-blue" - alt="Valid CSS" /></a> - <a href="http://validator.w3.org/check?uri=referer"> - <img src="http://www.w3.org/Icons/valid-xhtml10-blue" - alt="Valid XHTML 1.0 Transitional"/></a> - - <a href="mailto:foldr@codedgers.com">Mikhail Glushenkov</a><br /> - <a href="http://llvm.org">LLVM Compiler Infrastructure</a><br /> - - Last modified: $Date: 2008-12-11 11:34:48 -0600 (Thu, 11 Dec 2008) $ - </address> diff --git a/contrib/llvm/tools/llvmc/doc/LLVMC-Tutorial.rst b/contrib/llvm/tools/llvmc/doc/LLVMC-Tutorial.rst deleted file mode 100644 index e7e8f08..0000000 --- a/contrib/llvm/tools/llvmc/doc/LLVMC-Tutorial.rst +++ /dev/null @@ -1,129 +0,0 @@ -====================== -Tutorial - Using LLVMC -====================== -.. - This file was automatically generated by rst2html. - Please do not edit directly! - The ReST source lives in the directory 'tools/llvmc/doc'. - -.. contents:: - -.. raw:: html - - <div class="doc_author"> - <p>Written by <a href="mailto:foldr@codedgers.com">Mikhail Glushenkov</a></p> - </div> - -Introduction -============ - -LLVMC is a generic compiler driver, which plays the same role for LLVM -as the ``gcc`` program does for GCC - the difference being that LLVMC -is designed to be more adaptable and easier to customize. Most of -LLVMC functionality is implemented via plugins, which can be loaded -dynamically or compiled in. This tutorial describes the basic usage -and configuration of LLVMC. - - -Compiling with LLVMC -==================== - -In general, LLVMC tries to be command-line compatible with ``gcc`` as -much as possible, so most of the familiar options work:: - - $ llvmc -O3 -Wall hello.cpp - $ ./a.out - hello - -This will invoke ``llvm-g++`` under the hood (you can see which -commands are executed by using the ``-v`` option). For further help on -command-line LLVMC usage, refer to the ``llvmc --help`` output. - - -Using LLVMC to generate toolchain drivers -========================================= - -LLVMC plugins are written mostly using TableGen_, so you need to -be familiar with it to get anything done. - -.. _TableGen: http://llvm.org/docs/TableGenFundamentals.html - -Start by compiling ``example/Simple``, which is a primitive wrapper for -``gcc``:: - - $ cd $LLVM_DIR/tools/llvmc - $ cp -r example/Simple plugins/Simple - - # NB: A less verbose way to compile standalone LLVMC-based drivers is - # described in the reference manual. - - $ make LLVMC_BASED_DRIVER_NAME=mygcc LLVMC_BUILTIN_PLUGINS=Simple - $ cat > hello.c - [...] - $ mygcc hello.c - $ ./hello.out - Hello - -Here we link our plugin with the LLVMC core statically to form an executable -file called ``mygcc``. It is also possible to build our plugin as a dynamic -library to be loaded by the ``llvmc`` executable (or any other LLVMC-based -standalone driver); this is described in the reference manual. - -Contents of the file ``Simple.td`` look like this:: - - // Include common definitions - include "llvm/CompilerDriver/Common.td" - - // Tool descriptions - def gcc : Tool< - [(in_language "c"), - (out_language "executable"), - (output_suffix "out"), - (cmd_line "gcc $INFILE -o $OUTFILE"), - (sink) - ]>; - - // Language map - def LanguageMap : LanguageMap<[LangToSuffixes<"c", ["c"]>]>; - - // Compilation graph - def CompilationGraph : CompilationGraph<[Edge<"root", "gcc">]>; - -As you can see, this file consists of three parts: tool descriptions, -language map, and the compilation graph definition. - -At the heart of LLVMC is the idea of a compilation graph: vertices in -this graph are tools, and edges represent a transformation path -between two tools (for example, assembly source produced by the -compiler can be transformed into executable code by an assembler). The -compilation graph is basically a list of edges; a special node named -``root`` is used to mark graph entry points. - -Tool descriptions are represented as property lists: most properties -in the example above should be self-explanatory; the ``sink`` property -means that all options lacking an explicit description should be -forwarded to this tool. - -The ``LanguageMap`` associates a language name with a list of suffixes -and is used for deciding which toolchain corresponds to a given input -file. - -To learn more about LLVMC customization, refer to the reference -manual and plugin source code in the ``plugins`` directory. - -.. raw:: html - - <hr /> - <address> - <a href="http://jigsaw.w3.org/css-validator/check/referer"> - <img src="http://jigsaw.w3.org/css-validator/images/vcss-blue" - alt="Valid CSS" /></a> - <a href="http://validator.w3.org/check?uri=referer"> - <img src="http://www.w3.org/Icons/valid-xhtml10-blue" - alt="Valid XHTML 1.0 Transitional"/></a> - - <a href="mailto:foldr@codedgers.com">Mikhail Glushenkov</a><br /> - <a href="http://llvm.org">LLVM Compiler Infrastructure</a><br /> - - Last modified: $Date: 2008-12-11 11:34:48 -0600 (Thu, 11 Dec 2008) $ - </address> diff --git a/contrib/llvm/tools/llvmc/doc/Makefile b/contrib/llvm/tools/llvmc/doc/Makefile deleted file mode 100644 index ef98767..0000000 --- a/contrib/llvm/tools/llvmc/doc/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -##===- tools/llvmc/doc/Makefile ----------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL=../../.. - -ifneq (,$(strip $(wildcard $(LEVEL)/Makefile.config))) -include $(LEVEL)/Makefile.config -else -CP=cp -RM=rm -endif - -DOC_DIR=../../../docs -RST2HTML=rst2html --stylesheet=llvm.css --link-stylesheet - -all : LLVMC-Reference.html LLVMC-Tutorial.html - $(CP) LLVMC-Reference.html $(DOC_DIR)/CompilerDriver.html - $(CP) LLVMC-Tutorial.html $(DOC_DIR)/CompilerDriverTutorial.html - -LLVMC-Tutorial.html : LLVMC-Tutorial.rst - $(RST2HTML) $< $@ - -LLVMC-Reference.html : LLVMC-Reference.rst - $(RST2HTML) $< $@ - -clean : - $(RM) LLVMC-Tutorial.html LLVMC-Reference.html diff --git a/contrib/llvm/tools/llvmc/doc/img/lines.gif b/contrib/llvm/tools/llvmc/doc/img/lines.gif Binary files differdeleted file mode 100644 index 88f491e..0000000 --- a/contrib/llvm/tools/llvmc/doc/img/lines.gif +++ /dev/null diff --git a/contrib/llvm/tools/llvmc/src/AutoGenerated.td b/contrib/llvm/tools/llvmc/src/AutoGenerated.td deleted file mode 100644 index 8507b1f..0000000 --- a/contrib/llvm/tools/llvmc/src/AutoGenerated.td +++ /dev/null @@ -1,17 +0,0 @@ -//===- AutoGenerated.td - LLVMC toolchain descriptions -----*- tablegen -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains compilation graph description used by llvmc. -// -//===----------------------------------------------------------------------===// - -include "llvm/CompilerDriver/Common.td" - -include "Base.td" -include "Clang.td" diff --git a/contrib/llvm/tools/llvmc/src/Base.td.in b/contrib/llvm/tools/llvmc/src/Base.td.in deleted file mode 100644 index 0c4de4c..0000000 --- a/contrib/llvm/tools/llvmc/src/Base.td.in +++ /dev/null @@ -1,382 +0,0 @@ -//===- Base.td - LLVMC toolchain descriptions --------------*- tablegen -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains compilation graph description used by llvmc. -// -//===----------------------------------------------------------------------===// - - -// Options - -def OptList : OptionList<[ - (switch_option "emit-llvm", - (help "Emit LLVM .ll files instead of native object files")), - (switch_option "E", - (help "Stop after the preprocessing stage, do not run the compiler")), - (switch_option "fsyntax-only", - (help "Stop after checking the input for syntax errors")), - (switch_option "opt", - (help "Enable opt")), - (switch_option "O0", - (help "Turn off optimization"), (zero_or_more)), - (switch_option "O1", - (help "Optimization level 1"), (zero_or_more)), - (switch_option "O2", - (help "Optimization level 2"), (zero_or_more)), - (switch_option "O3", - (help "Optimization level 3"), (zero_or_more)), - (switch_option "S", - (help "Stop after compilation, do not assemble")), - (switch_option "c", - (help "Compile and assemble, but do not link")), - (switch_option "pthread", - (help "Enable threads")), - (switch_option "m32", - (help "Generate code for a 32-bit environment"), (hidden)), - (switch_option "m64", - (help "Generate code for a 64-bit environment"), (hidden)), - (switch_option "fPIC", - (help "Relocation model: PIC"), (hidden)), - (switch_option "mdynamic-no-pic", - (help "Relocation model: dynamic-no-pic"), (hidden)), - (switch_option "shared", - (help "Create a DLL instead of the regular executable")), - (parameter_option "linker", - (help "Choose linker (possible values: gcc, g++)")), - (parameter_option "mtune", - (help "Target a specific CPU type"), (hidden), (forward_not_split)), - - // TODO: Add a conditional compilation mechanism to make Darwin-only options - // like '-arch' really Darwin-only. - - (parameter_option "arch", - (help "Compile for the specified target architecture"), (hidden)), - (parameter_option "march", - (help "A synonym for -mtune"), (hidden), (forward_not_split)), - (parameter_option "mcpu", - (help "A deprecated synonym for -mtune"), (hidden), (forward_not_split)), - (switch_option "mfix-and-continue", - (help "Needed by gdb to load .o files dynamically"), (hidden)), - (parameter_option "MF", - (help "Specify a file to write dependencies to"), (hidden)), - (parameter_list_option "MT", - (help "Change the name of the rule emitted by dependency generation"), - (hidden)), - (parameter_list_option "include", - (help "Include the named file prior to preprocessing")), - (parameter_list_option "iquote", - (help "Search dir only for files requested with #inlcude \"file\""), - (hidden)), - (parameter_list_option "framework", - (help "Specifies a framework to link against")), - (parameter_list_option "weak_framework", - (help "Specifies a framework to weakly link against"), (hidden)), - (parameter_option "filelist", (hidden), - (help "Link the files listed in file")), - (prefix_list_option "F", - (help "Add a directory to framework search path")), - (prefix_list_option "I", - (help "Add a directory to include path")), - (prefix_list_option "D", - (help "Define a macro")), - (parameter_list_option "Xpreprocessor", (hidden), - (help "Pass options to preprocessor")), - (prefix_list_option "Wa,", (comma_separated), - (help "Pass options to assembler")), - (parameter_list_option "Xassembler", (hidden), - (help "Pass options to assembler")), - (prefix_list_option "Wllc,", (comma_separated), - (help "Pass options to llc")), - (prefix_list_option "L", - (help "Add a directory to link path")), - (prefix_list_option "l", - (help "Search a library when linking")), - (prefix_list_option "Wl,", - (help "Pass options to linker")), - (parameter_list_option "Xlinker", (hidden), - (help "Pass options to linker")), - (prefix_list_option "Wo,", (comma_separated), - (help "Pass options to opt")), - (prefix_list_option "m", - (help "Enable or disable various extensions (-mmmx, -msse, etc.)"), - (hidden)), - (switch_option "dynamiclib", (hidden), - (help "Produce a dynamic library")), - (switch_option "prebind", (hidden), - (help "Prebind all undefined symbols")), - (switch_option "dead_strip", (hidden), - (help "Remove unreachable blocks of code")), - (switch_option "single_module", (hidden), - (help "Build the library so it contains only one module")), - (parameter_option "install_name", (hidden), - (help "File name the library will be installed in")), - (parameter_option "compatibility_version", (hidden), - (help "Compatibility version number")), - (parameter_option "current_version", (hidden), - (help "Current version number")) -]>; - -// Option preprocessor. - -def Preprocess : OptionPreprocessor< -(case (not (any_switch_on ["O0", "O1", "O2", "O3"])), - (set_option "O2"), - (and (switch_on "O3"), (any_switch_on ["O0", "O1", "O2"])), - (unset_option ["O0", "O1", "O2"]), - (and (switch_on "O2"), (any_switch_on ["O0", "O1"])), - (unset_option ["O0", "O1"]), - (switch_on ["O1", "O0"]), - (unset_option "O0")) ->; - -// Tools - -class llvm_gcc_based <string cmd_prefix, string in_lang, - string E_ext, string out_lang> : Tool< -[(in_language in_lang), - (out_language "llvm-bitcode"), - (output_suffix out_lang), - (command cmd_prefix), - (actions - (case - (and (not_empty "o"), - (multiple_input_files), (or (switch_on "S"), (switch_on "c"))), - (error "cannot specify -o with -c or -S with multiple files"), - (switch_on "E"), - [(forward "E"), (stop_compilation), (output_suffix E_ext)], - (and (switch_on "E"), (empty "o")), (no_out_file), - (switch_on ["emit-llvm", "S"]), - [(output_suffix "ll"), (stop_compilation)], - (switch_on ["emit-llvm", "c"]), (stop_compilation), - (switch_on "fsyntax-only"), [(forward "fsyntax-only"), - (no_out_file), (stop_compilation)], - (switch_on ["S", "emit-llvm"]), [(forward "S"), (forward "emit-llvm")], - (not (or (switch_on ["S", "emit-llvm"]), (switch_on "fsyntax-only"))), - [(append_cmd "-c"), (append_cmd "-emit-llvm")], - - // Forwards - (not_empty "Xpreprocessor"), (forward "Xpreprocessor"), - (not_empty "include"), (forward "include"), - (not_empty "iquote"), (forward "iquote"), - (not_empty "save-temps"), (append_cmd "-save-temps"), - (not_empty "I"), (forward "I"), - (not_empty "F"), (forward "F"), - (not_empty "D"), (forward "D"), - (not_empty "arch"), (forward "arch"), - (not_empty "march"), (forward "march"), - (not_empty "mtune"), (forward "mtune"), - (not_empty "mcpu"), (forward "mcpu"), - (not_empty "m"), (forward "m"), - (switch_on "mfix-and-continue"), (forward "mfix-and-continue"), - (switch_on "m32"), (forward "m32"), - (switch_on "m64"), (forward "m64"), - (switch_on "O0"), (forward "O0"), - (switch_on "O1"), (forward "O1"), - (switch_on "O2"), (forward "O2"), - (switch_on "O3"), (forward "O3"), - (switch_on "fPIC"), (forward "fPIC"), - (switch_on "mdynamic-no-pic"), (forward "mdynamic-no-pic"), - (not_empty "MF"), (forward "MF"), - (not_empty "MT"), (forward "MT"))), - (sink) -]>; - -def llvm_gcc_c : llvm_gcc_based<"@LLVMGCCCOMMAND@ -x c", "c", "i", "bc">; -def llvm_gcc_cpp : llvm_gcc_based<"@LLVMGXXCOMMAND@ -x c++", "c++", "i", "bc">; -def llvm_gcc_m : llvm_gcc_based<"@LLVMGCCCOMMAND@ -x objective-c", - "objective-c", "mi", "bc">; -def llvm_gcc_mxx : llvm_gcc_based<"@LLVMGCCCOMMAND@ -x objective-c++", - "objective-c++", "mi", "bc">; - -def llvm_gcc_c_pch : llvm_gcc_based<"@LLVMGCCCOMMAND@ -x c-header", - "c-header", "i", "gch">; -def llvm_gcc_cpp_pch : llvm_gcc_based<"@LLVMGXXCOMMAND@ -x c++-header", - "c++-header", - "i", "gch">; -def llvm_gcc_m_pch : llvm_gcc_based<"@LLVMGCCCOMMAND@ -x objective-c-header", - "objective-c-header", - "mi", "gch">; -def llvm_gcc_mxx_pch - : llvm_gcc_based<"@LLVMGCCCOMMAND@ -x objective-c++-header", - "objective-c++-header", "mi", "gch">; - -def opt : Tool< -[(in_language "llvm-bitcode"), - (out_language "llvm-bitcode"), - (output_suffix "bc"), - (actions (case (not_empty "Wo,"), (forward_value "Wo,"), - (switch_on "O1"), (forward "O1"), - (switch_on "O2"), (forward "O2"), - (switch_on "O3"), (forward "O3"))), - (command "opt -f") -]>; - -def llvm_as : Tool< -[(in_language "llvm-assembler"), - (out_language "llvm-bitcode"), - (output_suffix "bc"), - (command "llvm-as"), - (actions (case (switch_on "emit-llvm"), (stop_compilation))) -]>; - -def llvm_gcc_assembler : Tool< -[(in_language "assembler"), - (out_language "object-code"), - (output_suffix "o"), - (command "@LLVMGCCCOMMAND@ -c -x assembler"), - (actions (case - (switch_on "c"), (stop_compilation), - (not_empty "arch"), (forward "arch"), - (not_empty "Xassembler"), (forward "Xassembler"), - (switch_on "m32"), (forward "m32"), - (switch_on "m64"), (forward "m64"), - (not_empty "Wa,"), (forward "Wa,"))) -]>; - -def llc : Tool< -[(in_language ["llvm-bitcode", "llvm-assembler"]), - (out_language "assembler"), - (output_suffix "s"), - (command "llc"), - (actions (case - (switch_on "S"), (stop_compilation), - (switch_on "O0"), (forward "O0"), - (switch_on "O1"), (forward "O1"), - (switch_on "O2"), (forward "O2"), - (switch_on "O3"), (forward "O3"), - (switch_on "fPIC"), (append_cmd "-relocation-model=pic"), - (switch_on "mdynamic-no-pic"), - (append_cmd "-relocation-model=dynamic-no-pic"), - (not_empty "march"), (forward_as "mtune", "-mcpu"), - (not_empty "mtune"), (forward_as "mtune", "-mcpu"), - (not_empty "mcpu"), (forward "mcpu"), - (not_empty "m"), (forward_transformed_value "m", "ConvertToMAttr"), - (not_empty "Wllc,"), (forward_value "Wllc,"))) -]>; - -// Base class for linkers -class llvm_gcc_based_linker <string cmd_prefix, dag on_empty> : Tool< -[(in_language ["object-code", "static-library", "dynamic-library"]), - (out_language "executable"), - (output_suffix "out"), - (command cmd_prefix), - (works_on_empty (case (and (not_empty "filelist"), on_empty), true, - (default), false)), - (join), - (actions (case - (switch_on "pthread"), (append_cmd "-lpthread"), - (not_empty "L"), (forward "L"), - (not_empty "F"), (forward "F"), - (not_empty "arch"), (forward "arch"), - (not_empty "framework"), (forward "framework"), - (not_empty "weak_framework"), (forward "weak_framework"), - (not_empty "filelist"), (forward "filelist"), - (switch_on "m32"), (forward "m32"), - (switch_on "m64"), (forward "m64"), - (not_empty "l"), (forward "l"), - (not_empty "Xlinker"), (forward "Xlinker"), - (not_empty "Wl,"), (forward "Wl,"), - (switch_on "shared"), (forward "shared"), - (switch_on "dynamiclib"), (forward "dynamiclib"), - (switch_on "prebind"), (forward "prebind"), - (switch_on "dead_strip"), (forward "dead_strip"), - (switch_on "single_module"), (forward "single_module"), - (not_empty "compatibility_version"), - (forward "compatibility_version"), - (not_empty "current_version"), (forward "current_version"), - (not_empty "install_name"), (forward "install_name"))) -]>; - -// Default linker -def llvm_gcc_linker : llvm_gcc_based_linker<"@LLVMGCCCOMMAND@", - (not (or (parameter_equals "linker", "g++"), - (parameter_equals "linker", "c++")))>; -// Alternative linker for C++ -def llvm_gcc_cpp_linker : llvm_gcc_based_linker<"@LLVMGXXCOMMAND@", - (or (parameter_equals "linker", "g++"), - (parameter_equals "linker", "c++"))>; - -// Language map - -def LanguageMap : LanguageMap<[ - (lang_to_suffixes "c++", ["cc", "cp", "cxx", "cpp", "CPP", "c++", "C"]), - (lang_to_suffixes "c++-header", "hpp"), - (lang_to_suffixes "c", "c"), - (lang_to_suffixes "c-header", "h"), - (lang_to_suffixes "c-cpp-output", "i"), - (lang_to_suffixes "objective-c-cpp-output", "mi"), - (lang_to_suffixes "objective-c++", "mm"), - (lang_to_suffixes "objective-c++-header", "hmm"), - (lang_to_suffixes "objective-c", "m"), - (lang_to_suffixes "objective-c-header", "hm"), - (lang_to_suffixes "assembler", "s"), - (lang_to_suffixes "assembler-with-cpp", "S"), - (lang_to_suffixes "llvm-assembler", "ll"), - (lang_to_suffixes "llvm-bitcode", "bc"), - (lang_to_suffixes "object-code", ["o", "*empty*"]), - (lang_to_suffixes "static-library", ["a", "lib"]), - (lang_to_suffixes "dynamic-library", ["so", "dylib", "dll"]), - (lang_to_suffixes "executable", ["out"]) -]>; - -// Compilation graph - -def CompilationGraph : CompilationGraph<[ - (edge "root", "llvm_gcc_c"), - (edge "root", "llvm_gcc_assembler"), - (edge "root", "llvm_gcc_cpp"), - (edge "root", "llvm_gcc_m"), - (edge "root", "llvm_gcc_mxx"), - (edge "root", "llc"), - - (edge "root", "llvm_gcc_c_pch"), - (edge "root", "llvm_gcc_cpp_pch"), - (edge "root", "llvm_gcc_m_pch"), - (edge "root", "llvm_gcc_mxx_pch"), - - (edge "llvm_gcc_c", "llc"), - (edge "llvm_gcc_cpp", "llc"), - (edge "llvm_gcc_m", "llc"), - (edge "llvm_gcc_mxx", "llc"), - (edge "llvm_as", "llc"), - - (optional_edge "root", "llvm_as", - (case (switch_on "emit-llvm"), (inc_weight))), - (optional_edge "llvm_gcc_c", "opt", - (case (switch_on "opt"), (inc_weight))), - (optional_edge "llvm_gcc_cpp", "opt", - (case (switch_on "opt"), (inc_weight))), - (optional_edge "llvm_gcc_m", "opt", - (case (switch_on "opt"), (inc_weight))), - (optional_edge "llvm_gcc_mxx", "opt", - (case (switch_on "opt"), (inc_weight))), - (optional_edge "llvm_as", "opt", - (case (switch_on "opt"), (inc_weight))), - (edge "opt", "llc"), - - (edge "llc", "llvm_gcc_assembler"), - (edge "llvm_gcc_assembler", "llvm_gcc_linker"), - (optional_edge "llvm_gcc_assembler", "llvm_gcc_cpp_linker", - (case - (or (input_languages_contain "c++"), - (input_languages_contain "objective-c++")), - (inc_weight), - (or (parameter_equals "linker", "g++"), - (parameter_equals "linker", "c++")), (inc_weight))), - - - (edge "root", "llvm_gcc_linker"), - (optional_edge "root", "llvm_gcc_cpp_linker", - (case - (or (input_languages_contain "c++"), - (input_languages_contain "objective-c++")), - (inc_weight), - (or (parameter_equals "linker", "g++"), - (parameter_equals "linker", "c++")), (inc_weight))) -]>; diff --git a/contrib/llvm/tools/llvmc/src/Clang.td b/contrib/llvm/tools/llvmc/src/Clang.td deleted file mode 100644 index 1d75743..0000000 --- a/contrib/llvm/tools/llvmc/src/Clang.td +++ /dev/null @@ -1,87 +0,0 @@ -//===- Clang.td - LLVMC toolchain descriptions -------------*- tablegen -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains compilation graph description used by llvmc. -// -//===----------------------------------------------------------------------===// - - -def Options : OptionList<[ -(switch_option "clang", (help "Use Clang instead of llvm-gcc")) -]>; - -class clang_based<string language, string cmd, string ext_E> : Tool< -[(in_language language), - (out_language "llvm-bitcode"), - (output_suffix "bc"), - (command cmd), - (actions (case (switch_on "E"), - [(forward "E"), (stop_compilation), (output_suffix ext_E)], - (and (switch_on "E"), (empty "o")), (no_out_file), - (switch_on "fsyntax-only"), (stop_compilation), - (switch_on ["S", "emit-llvm"]), - [(append_cmd "-emit-llvm"), - (stop_compilation), (output_suffix "ll")], - (not (switch_on ["S", "emit-llvm"])), - (append_cmd "-emit-llvm-bc"), - (switch_on ["c", "emit-llvm"]), - (stop_compilation), - (not_empty "include"), (forward "include"), - (not_empty "I"), (forward "I"))), - (sink) -]>; - -def clang_c : clang_based<"c", "clang -x c", "i">; -def clang_cpp : clang_based<"c++", "clang -x c++", "i">; -def clang_objective_c : clang_based<"objective-c", - "clang -x objective-c", "mi">; -def clang_objective_cpp : clang_based<"objective-c++", - "clang -x objective-c++", "mi">; - -def as : Tool< -[(in_language "assembler"), - (out_language "object-code"), - (output_suffix "o"), - (command "as"), - (actions (case (not_empty "Wa,"), (forward_value "Wa,"), - (switch_on "c"), (stop_compilation))) -]>; - -// Default linker -def llvm_ld : Tool< -[(in_language "object-code"), - (out_language "executable"), - (output_suffix "out"), - (command "llvm-ld -native -disable-internalize"), - (actions (case - (switch_on "pthread"), (append_cmd "-lpthread"), - (not_empty "L"), (forward "L"), - (not_empty "l"), (forward "l"), - (not_empty "Wl,"), (forward_value "Wl,"))), - (join) -]>; - -// Compilation graph - -def ClangCompilationGraph : CompilationGraph<[ - (optional_edge "root", "clang_c", - (case (switch_on "clang"), (inc_weight))), - (optional_edge "root", "clang_cpp", - (case (switch_on "clang"), (inc_weight))), - (optional_edge "root", "clang_objective_c", - (case (switch_on "clang"), (inc_weight))), - (optional_edge "root", "clang_objective_cpp", - (case (switch_on "clang"), (inc_weight))), - (edge "clang_c", "llc"), - (edge "clang_cpp", "llc"), - (edge "clang_objective_c", "llc"), - (edge "clang_objective_cpp", "llc"), - (optional_edge "llc", "as", (case (switch_on "clang"), (inc_weight))), - (edge "as", "llvm_ld") -]>; diff --git a/contrib/llvm/tools/llvmc/src/Hooks.cpp b/contrib/llvm/tools/llvmc/src/Hooks.cpp deleted file mode 100644 index 661a914..0000000 --- a/contrib/llvm/tools/llvmc/src/Hooks.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include <string> -#include <vector> - -namespace hooks { -typedef std::vector<std::string> StrVec; - -/// ConvertToMAttr - Convert -m* and -mno-* to -mattr=+*,-* -std::string ConvertToMAttr(const StrVec& Opts) { - std::string out("-mattr="); - - bool firstIter = true; - for (StrVec::const_iterator B = Opts.begin(), E = Opts.end(); B!=E; ++B) { - const std::string& Arg = *B; - - if (firstIter) - firstIter = false; - else - out += ","; - - if (Arg.find("no-") == 0 && Arg[3] != 0) { - out += '-'; - out += Arg.c_str() + 3; - } - else { - out += '+'; - out += Arg; - } - } - - return out; -} - -} diff --git a/contrib/llvm/tools/llvmc/src/Main.cpp b/contrib/llvm/tools/llvmc/src/Main.cpp deleted file mode 100644 index 9f9c71a..0000000 --- a/contrib/llvm/tools/llvmc/src/Main.cpp +++ /dev/null @@ -1,16 +0,0 @@ -//===--- Main.cpp - The LLVM Compiler Driver -------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open -// Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Just include AutoGenerated.inc and CompilerDriver/Main.inc. -// -//===----------------------------------------------------------------------===// - -#include "AutoGenerated.inc" - -#include "llvm/CompilerDriver/Main.inc" diff --git a/contrib/llvm/tools/llvmc/src/Makefile b/contrib/llvm/tools/llvmc/src/Makefile deleted file mode 100644 index f3f3091..0000000 --- a/contrib/llvm/tools/llvmc/src/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -##===- tools/llvmc/src/Makefile ----------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open -# Source License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL = ../../.. -LLVMC_BASED_DRIVER = llvmc -BUILT_SOURCES = AutoGenerated.inc - -include $(LEVEL)/Makefile.common diff --git a/contrib/llvm/tools/lto/LTOCodeGenerator.cpp b/contrib/llvm/tools/lto/LTOCodeGenerator.cpp deleted file mode 100644 index 671348c..0000000 --- a/contrib/llvm/tools/lto/LTOCodeGenerator.cpp +++ /dev/null @@ -1,442 +0,0 @@ -//===-LTOCodeGenerator.cpp - LLVM Link Time Optimizer ---------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the Link Time Optimization library. This library is -// intended to be used by linker to optimize code at link time. -// -//===----------------------------------------------------------------------===// - -#include "LTOModule.h" -#include "LTOCodeGenerator.h" - -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Linker.h" -#include "llvm/LLVMContext.h" -#include "llvm/Module.h" -#include "llvm/PassManager.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/ADT/Triple.h" -#include "llvm/Analysis/Passes.h" -#include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/MC/MCAsmInfo.h" -#include "llvm/MC/MCContext.h" -#include "llvm/Target/Mangler.h" -#include "llvm/Target/SubtargetFeature.h" -#include "llvm/Target/TargetOptions.h" -#include "llvm/Target/TargetData.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetRegistry.h" -#include "llvm/Target/TargetSelect.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/FormattedStream.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/StandardPasses.h" -#include "llvm/Support/SystemUtils.h" -#include "llvm/System/Host.h" -#include "llvm/System/Program.h" -#include "llvm/System/Signals.h" -#include "llvm/Config/config.h" -#include <cstdlib> -#include <unistd.h> -#include <fcntl.h> - - -using namespace llvm; - -static cl::opt<bool> DisableInline("disable-inlining", - cl::desc("Do not run the inliner pass")); - - -const char* LTOCodeGenerator::getVersionString() -{ -#ifdef LLVM_VERSION_INFO - return PACKAGE_NAME " version " PACKAGE_VERSION ", " LLVM_VERSION_INFO; -#else - return PACKAGE_NAME " version " PACKAGE_VERSION; -#endif -} - - -LTOCodeGenerator::LTOCodeGenerator() - : _context(getGlobalContext()), - _linker("LinkTimeOptimizer", "ld-temp.o", _context), _target(NULL), - _emitDwarfDebugInfo(false), _scopeRestrictionsDone(false), - _codeModel(LTO_CODEGEN_PIC_MODEL_DYNAMIC), - _nativeObjectFile(NULL), _assemblerPath(NULL) -{ - InitializeAllTargets(); - InitializeAllAsmPrinters(); -} - -LTOCodeGenerator::~LTOCodeGenerator() -{ - delete _target; - delete _nativeObjectFile; -} - - - -bool LTOCodeGenerator::addModule(LTOModule* mod, std::string& errMsg) -{ - return _linker.LinkInModule(mod->getLLVVMModule(), &errMsg); -} - - -bool LTOCodeGenerator::setDebugInfo(lto_debug_model debug, std::string& errMsg) -{ - switch (debug) { - case LTO_DEBUG_MODEL_NONE: - _emitDwarfDebugInfo = false; - return false; - - case LTO_DEBUG_MODEL_DWARF: - _emitDwarfDebugInfo = true; - return false; - } - errMsg = "unknown debug format"; - return true; -} - - -bool LTOCodeGenerator::setCodePICModel(lto_codegen_model model, - std::string& errMsg) -{ - switch (model) { - case LTO_CODEGEN_PIC_MODEL_STATIC: - case LTO_CODEGEN_PIC_MODEL_DYNAMIC: - case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC: - _codeModel = model; - return false; - } - errMsg = "unknown pic model"; - return true; -} - -void LTOCodeGenerator::setCpu(const char* mCpu) -{ - _mCpu = mCpu; -} - -void LTOCodeGenerator::setAssemblerPath(const char* path) -{ - if ( _assemblerPath ) - delete _assemblerPath; - _assemblerPath = new sys::Path(path); -} - -void LTOCodeGenerator::setAssemblerArgs(const char** args, int nargs) -{ - for (int i = 0; i < nargs; ++i) { - const char *arg = args[i]; - _assemblerArgs.push_back(arg); - } -} - -void LTOCodeGenerator::addMustPreserveSymbol(const char* sym) -{ - _mustPreserveSymbols[sym] = 1; -} - - -bool LTOCodeGenerator::writeMergedModules(const char *path, - std::string &errMsg) { - if (determineTarget(errMsg)) - return true; - - // mark which symbols can not be internalized - applyScopeRestrictions(); - - // create output file - std::string ErrInfo; - tool_output_file Out(path, ErrInfo, - raw_fd_ostream::F_Binary); - if (!ErrInfo.empty()) { - errMsg = "could not open bitcode file for writing: "; - errMsg += path; - return true; - } - - // write bitcode to it - WriteBitcodeToFile(_linker.getModule(), Out.os()); - Out.os().close(); - - if (Out.os().has_error()) { - errMsg = "could not write bitcode file: "; - errMsg += path; - Out.os().clear_error(); - return true; - } - - Out.keep(); - return false; -} - - -const void* LTOCodeGenerator::compile(size_t* length, std::string& errMsg) -{ - // make unique temp .s file to put generated assembly code - sys::Path uniqueAsmPath("lto-llvm.s"); - if ( uniqueAsmPath.createTemporaryFileOnDisk(true, &errMsg) ) - return NULL; - sys::RemoveFileOnSignal(uniqueAsmPath); - - // generate assembly code - bool genResult = false; - { - tool_output_file asmFile(uniqueAsmPath.c_str(), errMsg); - if (!errMsg.empty()) - return NULL; - genResult = this->generateAssemblyCode(asmFile.os(), errMsg); - asmFile.os().close(); - if (asmFile.os().has_error()) { - asmFile.os().clear_error(); - return NULL; - } - asmFile.keep(); - } - if ( genResult ) { - uniqueAsmPath.eraseFromDisk(); - return NULL; - } - - // make unique temp .o file to put generated object file - sys::PathWithStatus uniqueObjPath("lto-llvm.o"); - if ( uniqueObjPath.createTemporaryFileOnDisk(true, &errMsg) ) { - uniqueAsmPath.eraseFromDisk(); - return NULL; - } - sys::RemoveFileOnSignal(uniqueObjPath); - - // assemble the assembly code - const std::string& uniqueObjStr = uniqueObjPath.str(); - bool asmResult = this->assemble(uniqueAsmPath.str(), uniqueObjStr, errMsg); - if ( !asmResult ) { - // remove old buffer if compile() called twice - delete _nativeObjectFile; - - // read .o file into memory buffer - _nativeObjectFile = MemoryBuffer::getFile(uniqueObjStr.c_str(),&errMsg); - } - - // remove temp files - uniqueAsmPath.eraseFromDisk(); - uniqueObjPath.eraseFromDisk(); - - // return buffer, unless error - if ( _nativeObjectFile == NULL ) - return NULL; - *length = _nativeObjectFile->getBufferSize(); - return _nativeObjectFile->getBufferStart(); -} - - -bool LTOCodeGenerator::assemble(const std::string& asmPath, - const std::string& objPath, std::string& errMsg) -{ - sys::Path tool; - bool needsCompilerOptions = true; - if ( _assemblerPath ) { - tool = *_assemblerPath; - needsCompilerOptions = false; - } else { - // find compiler driver - tool = sys::Program::FindProgramByName("gcc"); - if ( tool.isEmpty() ) { - errMsg = "can't locate gcc"; - return true; - } - } - - // build argument list - std::vector<const char*> args; - llvm::Triple targetTriple(_linker.getModule()->getTargetTriple()); - const char *arch = targetTriple.getArchNameForAssembler(); - - args.push_back(tool.c_str()); - - if (targetTriple.getOS() == Triple::Darwin) { - // darwin specific command line options - if (arch != NULL) { - args.push_back("-arch"); - args.push_back(arch); - } - // add -static to assembler command line when code model requires - if ( (_assemblerPath != NULL) && - (_codeModel == LTO_CODEGEN_PIC_MODEL_STATIC) ) - args.push_back("-static"); - } - if ( needsCompilerOptions ) { - args.push_back("-c"); - args.push_back("-x"); - args.push_back("assembler"); - } else { - for (std::vector<std::string>::iterator I = _assemblerArgs.begin(), - E = _assemblerArgs.end(); I != E; ++I) { - args.push_back(I->c_str()); - } - } - args.push_back("-o"); - args.push_back(objPath.c_str()); - args.push_back(asmPath.c_str()); - args.push_back(0); - - // invoke assembler - if ( sys::Program::ExecuteAndWait(tool, &args[0], 0, 0, 0, 0, &errMsg) ) { - errMsg = "error in assembly"; - return true; - } - return false; // success -} - - - -bool LTOCodeGenerator::determineTarget(std::string& errMsg) -{ - if ( _target == NULL ) { - std::string Triple = _linker.getModule()->getTargetTriple(); - if (Triple.empty()) - Triple = sys::getHostTriple(); - - // create target machine from info for merged modules - const Target *march = TargetRegistry::lookupTarget(Triple, errMsg); - if ( march == NULL ) - return true; - - // The relocation model is actually a static member of TargetMachine - // and needs to be set before the TargetMachine is instantiated. - switch( _codeModel ) { - case LTO_CODEGEN_PIC_MODEL_STATIC: - TargetMachine::setRelocationModel(Reloc::Static); - break; - case LTO_CODEGEN_PIC_MODEL_DYNAMIC: - TargetMachine::setRelocationModel(Reloc::PIC_); - break; - case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC: - TargetMachine::setRelocationModel(Reloc::DynamicNoPIC); - break; - } - - // construct LTModule, hand over ownership of module and target - SubtargetFeatures Features; - Features.getDefaultSubtargetFeatures(_mCpu, llvm::Triple(Triple)); - std::string FeatureStr = Features.getString(); - _target = march->createTargetMachine(Triple, FeatureStr); - } - return false; -} - -void LTOCodeGenerator::applyScopeRestrictions() { - if (_scopeRestrictionsDone) return; - Module *mergedModule = _linker.getModule(); - - // Start off with a verification pass. - PassManager passes; - passes.add(createVerifierPass()); - - // mark which symbols can not be internalized - if (!_mustPreserveSymbols.empty()) { - MCContext Context(*_target->getMCAsmInfo()); - Mangler mangler(Context, *_target->getTargetData()); - std::vector<const char*> mustPreserveList; - for (Module::iterator f = mergedModule->begin(), - e = mergedModule->end(); f != e; ++f) { - if (!f->isDeclaration() && - _mustPreserveSymbols.count(mangler.getNameWithPrefix(f))) - mustPreserveList.push_back(::strdup(f->getNameStr().c_str())); - } - for (Module::global_iterator v = mergedModule->global_begin(), - e = mergedModule->global_end(); v != e; ++v) { - if (!v->isDeclaration() && - _mustPreserveSymbols.count(mangler.getNameWithPrefix(v))) - mustPreserveList.push_back(::strdup(v->getNameStr().c_str())); - } - passes.add(createInternalizePass(mustPreserveList)); - } - - // apply scope restrictions - passes.run(*mergedModule); - - _scopeRestrictionsDone = true; -} - -/// Optimize merged modules using various IPO passes -bool LTOCodeGenerator::generateAssemblyCode(raw_ostream& out, - std::string& errMsg) -{ - if ( this->determineTarget(errMsg) ) - return true; - - // mark which symbols can not be internalized - this->applyScopeRestrictions(); - - Module* mergedModule = _linker.getModule(); - - // if options were requested, set them - if ( !_codegenOptions.empty() ) - cl::ParseCommandLineOptions(_codegenOptions.size(), - const_cast<char **>(&_codegenOptions[0])); - - // Instantiate the pass manager to organize the passes. - PassManager passes; - - // Start off with a verification pass. - passes.add(createVerifierPass()); - - // Add an appropriate TargetData instance for this module... - passes.add(new TargetData(*_target->getTargetData())); - - createStandardLTOPasses(&passes, /*Internalize=*/ false, !DisableInline, - /*VerifyEach=*/ false); - - // Make sure everything is still good. - passes.add(createVerifierPass()); - - FunctionPassManager* codeGenPasses = new FunctionPassManager(mergedModule); - - codeGenPasses->add(new TargetData(*_target->getTargetData())); - - formatted_raw_ostream Out(out); - - if (_target->addPassesToEmitFile(*codeGenPasses, Out, - TargetMachine::CGFT_AssemblyFile, - CodeGenOpt::Aggressive)) { - errMsg = "target file type not supported"; - return true; - } - - // Run our queue of passes all at once now, efficiently. - passes.run(*mergedModule); - - // Run the code generator, and write assembly file - codeGenPasses->doInitialization(); - - for (Module::iterator - it = mergedModule->begin(), e = mergedModule->end(); it != e; ++it) - if (!it->isDeclaration()) - codeGenPasses->run(*it); - - codeGenPasses->doFinalization(); - - return false; // success -} - - -/// Optimize merged modules using various IPO passes -void LTOCodeGenerator::setCodeGenDebugOptions(const char* options) -{ - for (std::pair<StringRef, StringRef> o = getToken(options); - !o.first.empty(); o = getToken(o.second)) { - // ParseCommandLineOptions() expects argv[0] to be program name. - // Lazily add that. - if ( _codegenOptions.empty() ) - _codegenOptions.push_back("libLTO"); - _codegenOptions.push_back(strdup(o.first.str().c_str())); - } -} diff --git a/contrib/llvm/tools/lto/LTOCodeGenerator.h b/contrib/llvm/tools/lto/LTOCodeGenerator.h deleted file mode 100644 index f5b78a6..0000000 --- a/contrib/llvm/tools/lto/LTOCodeGenerator.h +++ /dev/null @@ -1,72 +0,0 @@ -//===-LTOCodeGenerator.h - LLVM Link Time Optimizer -----------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file declares the LTOCodeGenerator class. -// -//===----------------------------------------------------------------------===// - - -#ifndef LTO_CODE_GENERATOR_H -#define LTO_CODE_GENERATOR_H - -#include "llvm/Linker.h" -#include "llvm/LLVMContext.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/ADT/SmallVector.h" - -#include <string> - - -// -// C++ class which implements the opaque lto_code_gen_t -// - -struct LTOCodeGenerator { - static const char* getVersionString(); - - LTOCodeGenerator(); - ~LTOCodeGenerator(); - - bool addModule(struct LTOModule*, std::string& errMsg); - bool setDebugInfo(lto_debug_model, std::string& errMsg); - bool setCodePICModel(lto_codegen_model, std::string& errMsg); - void setCpu(const char *cpu); - void setAssemblerPath(const char* path); - void setAssemblerArgs(const char** args, int nargs); - void addMustPreserveSymbol(const char* sym); - bool writeMergedModules(const char* path, - std::string& errMsg); - const void* compile(size_t* length, std::string& errMsg); - void setCodeGenDebugOptions(const char *opts); -private: - bool generateAssemblyCode(llvm::raw_ostream& out, - std::string& errMsg); - bool assemble(const std::string& asmPath, - const std::string& objPath, std::string& errMsg); - void applyScopeRestrictions(); - bool determineTarget(std::string& errMsg); - - typedef llvm::StringMap<uint8_t> StringSet; - - llvm::LLVMContext& _context; - llvm::Linker _linker; - llvm::TargetMachine* _target; - bool _emitDwarfDebugInfo; - bool _scopeRestrictionsDone; - lto_codegen_model _codeModel; - StringSet _mustPreserveSymbols; - llvm::MemoryBuffer* _nativeObjectFile; - std::vector<const char*> _codegenOptions; - llvm::sys::Path* _assemblerPath; - std::string _mCpu; - std::vector<std::string> _assemblerArgs; -}; - -#endif // LTO_CODE_GENERATOR_H - diff --git a/contrib/llvm/tools/lto/LTOModule.cpp b/contrib/llvm/tools/lto/LTOModule.cpp deleted file mode 100644 index c7cd585..0000000 --- a/contrib/llvm/tools/lto/LTOModule.cpp +++ /dev/null @@ -1,508 +0,0 @@ -//===-- LTOModule.cpp - LLVM Link Time Optimizer --------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the Link Time Optimization library. This library is -// intended to be used by linker to optimize code at link time. -// -//===----------------------------------------------------------------------===// - -#include "LTOModule.h" - -#include "llvm/Constants.h" -#include "llvm/LLVMContext.h" -#include "llvm/Module.h" -#include "llvm/ADT/OwningPtr.h" -#include "llvm/ADT/Triple.h" -#include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/Support/SystemUtils.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/MathExtras.h" -#include "llvm/System/Host.h" -#include "llvm/System/Path.h" -#include "llvm/System/Process.h" -#include "llvm/Target/Mangler.h" -#include "llvm/Target/SubtargetFeature.h" -#include "llvm/MC/MCAsmInfo.h" -#include "llvm/MC/MCContext.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetRegistry.h" -#include "llvm/Target/TargetSelect.h" - -using namespace llvm; - -bool LTOModule::isBitcodeFile(const void *mem, size_t length) { - return llvm::sys::IdentifyFileType((char*)mem, length) - == llvm::sys::Bitcode_FileType; -} - -bool LTOModule::isBitcodeFile(const char *path) { - return llvm::sys::Path(path).isBitcodeFile(); -} - -bool LTOModule::isBitcodeFileForTarget(const void *mem, size_t length, - const char *triplePrefix) { - MemoryBuffer *buffer = makeBuffer(mem, length); - if (!buffer) - return false; - return isTargetMatch(buffer, triplePrefix); -} - - -bool LTOModule::isBitcodeFileForTarget(const char *path, - const char *triplePrefix) { - MemoryBuffer *buffer = MemoryBuffer::getFile(path); - if (buffer == NULL) - return false; - return isTargetMatch(buffer, triplePrefix); -} - -// Takes ownership of buffer. -bool LTOModule::isTargetMatch(MemoryBuffer *buffer, const char *triplePrefix) { - OwningPtr<Module> m(getLazyBitcodeModule(buffer, getGlobalContext())); - // On success, m owns buffer and both are deleted at end of this method. - if (!m) { - delete buffer; - return false; - } - std::string actualTarget = m->getTargetTriple(); - return (strncmp(actualTarget.c_str(), triplePrefix, - strlen(triplePrefix)) == 0); -} - - -LTOModule::LTOModule(Module *m, TargetMachine *t) - : _module(m), _target(t), _symbolsParsed(false) -{ -} - -LTOModule *LTOModule::makeLTOModule(const char *path, - std::string &errMsg) { - OwningPtr<MemoryBuffer> buffer(MemoryBuffer::getFile(path, &errMsg)); - if (!buffer) - return NULL; - return makeLTOModule(buffer.get(), errMsg); -} - -/// makeBuffer - Create a MemoryBuffer from a memory range. MemoryBuffer -/// requires the byte past end of the buffer to be a zero. We might get lucky -/// and already be that way, otherwise make a copy. Also if next byte is on a -/// different page, don't assume it is readable. -MemoryBuffer *LTOModule::makeBuffer(const void *mem, size_t length) { - const char *startPtr = (char*)mem; - const char *endPtr = startPtr+length; - if (((uintptr_t)endPtr & (sys::Process::GetPageSize()-1)) == 0 || - *endPtr != 0) - return MemoryBuffer::getMemBufferCopy(StringRef(startPtr, length)); - - return MemoryBuffer::getMemBuffer(StringRef(startPtr, length)); -} - - -LTOModule *LTOModule::makeLTOModule(const void *mem, size_t length, - std::string &errMsg) { - OwningPtr<MemoryBuffer> buffer(makeBuffer(mem, length)); - if (!buffer) - return NULL; - return makeLTOModule(buffer.get(), errMsg); -} - -LTOModule *LTOModule::makeLTOModule(MemoryBuffer *buffer, - std::string &errMsg) { - InitializeAllTargets(); - - // parse bitcode buffer - OwningPtr<Module> m(ParseBitcodeFile(buffer, getGlobalContext(), &errMsg)); - if (!m) - return NULL; - - std::string Triple = m->getTargetTriple(); - if (Triple.empty()) - Triple = sys::getHostTriple(); - - // find machine architecture for this module - const Target *march = TargetRegistry::lookupTarget(Triple, errMsg); - if (!march) - return NULL; - - // construct LTModule, hand over ownership of module and target - SubtargetFeatures Features; - Features.getDefaultSubtargetFeatures("" /* cpu */, llvm::Triple(Triple)); - std::string FeatureStr = Features.getString(); - TargetMachine *target = march->createTargetMachine(Triple, FeatureStr); - return new LTOModule(m.take(), target); -} - - -const char *LTOModule::getTargetTriple() { - return _module->getTargetTriple().c_str(); -} - -void LTOModule::setTargetTriple(const char *triple) { - _module->setTargetTriple(triple); -} - -void LTOModule::addDefinedFunctionSymbol(Function *f, Mangler &mangler) { - // add to list of defined symbols - addDefinedSymbol(f, mangler, true); - - // add external symbols referenced by this function. - for (Function::iterator b = f->begin(); b != f->end(); ++b) { - for (BasicBlock::iterator i = b->begin(); i != b->end(); ++i) { - for (unsigned count = 0, total = i->getNumOperands(); - count != total; ++count) { - findExternalRefs(i->getOperand(count), mangler); - } - } - } -} - -// Get string that data pointer points to. -bool LTOModule::objcClassNameFromExpression(Constant *c, std::string &name) { - if (ConstantExpr *ce = dyn_cast<ConstantExpr>(c)) { - Constant *op = ce->getOperand(0); - if (GlobalVariable *gvn = dyn_cast<GlobalVariable>(op)) { - Constant *cn = gvn->getInitializer(); - if (ConstantArray *ca = dyn_cast<ConstantArray>(cn)) { - if (ca->isCString()) { - name = ".objc_class_name_" + ca->getAsString(); - return true; - } - } - } - } - return false; -} - -// Parse i386/ppc ObjC class data structure. -void LTOModule::addObjCClass(GlobalVariable *clgv) { - if (ConstantStruct *c = dyn_cast<ConstantStruct>(clgv->getInitializer())) { - // second slot in __OBJC,__class is pointer to superclass name - std::string superclassName; - if (objcClassNameFromExpression(c->getOperand(1), superclassName)) { - NameAndAttributes info; - if (_undefines.find(superclassName.c_str()) == _undefines.end()) { - const char *symbolName = ::strdup(superclassName.c_str()); - info.name = symbolName; - info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED; - // string is owned by _undefines - _undefines[info.name] = info; - } - } - // third slot in __OBJC,__class is pointer to class name - std::string className; - if (objcClassNameFromExpression(c->getOperand(2), className)) { - const char *symbolName = ::strdup(className.c_str()); - NameAndAttributes info; - info.name = symbolName; - info.attributes = (lto_symbol_attributes) - (LTO_SYMBOL_PERMISSIONS_DATA | - LTO_SYMBOL_DEFINITION_REGULAR | - LTO_SYMBOL_SCOPE_DEFAULT); - _symbols.push_back(info); - _defines[info.name] = 1; - } - } -} - - -// Parse i386/ppc ObjC category data structure. -void LTOModule::addObjCCategory(GlobalVariable *clgv) { - if (ConstantStruct *c = dyn_cast<ConstantStruct>(clgv->getInitializer())) { - // second slot in __OBJC,__category is pointer to target class name - std::string targetclassName; - if (objcClassNameFromExpression(c->getOperand(1), targetclassName)) { - NameAndAttributes info; - if (_undefines.find(targetclassName.c_str()) == _undefines.end()) { - const char *symbolName = ::strdup(targetclassName.c_str()); - info.name = symbolName; - info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED; - // string is owned by _undefines - _undefines[info.name] = info; - } - } - } -} - - -// Parse i386/ppc ObjC class list data structure. -void LTOModule::addObjCClassRef(GlobalVariable *clgv) { - std::string targetclassName; - if (objcClassNameFromExpression(clgv->getInitializer(), targetclassName)) { - NameAndAttributes info; - if (_undefines.find(targetclassName.c_str()) == _undefines.end()) { - const char *symbolName = ::strdup(targetclassName.c_str()); - info.name = symbolName; - info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED; - // string is owned by _undefines - _undefines[info.name] = info; - } - } -} - - -void LTOModule::addDefinedDataSymbol(GlobalValue *v, Mangler &mangler) { - // Add to list of defined symbols. - addDefinedSymbol(v, mangler, false); - - // Special case i386/ppc ObjC data structures in magic sections: - // The issue is that the old ObjC object format did some strange - // contortions to avoid real linker symbols. For instance, the - // ObjC class data structure is allocated statically in the executable - // that defines that class. That data structures contains a pointer to - // its superclass. But instead of just initializing that part of the - // struct to the address of its superclass, and letting the static and - // dynamic linkers do the rest, the runtime works by having that field - // instead point to a C-string that is the name of the superclass. - // At runtime the objc initialization updates that pointer and sets - // it to point to the actual super class. As far as the linker - // knows it is just a pointer to a string. But then someone wanted the - // linker to issue errors at build time if the superclass was not found. - // So they figured out a way in mach-o object format to use an absolute - // symbols (.objc_class_name_Foo = 0) and a floating reference - // (.reference .objc_class_name_Bar) to cause the linker into erroring when - // a class was missing. - // The following synthesizes the implicit .objc_* symbols for the linker - // from the ObjC data structures generated by the front end. - if (v->hasSection() /* && isTargetDarwin */) { - // special case if this data blob is an ObjC class definition - if (v->getSection().compare(0, 15, "__OBJC,__class,") == 0) { - if (GlobalVariable *gv = dyn_cast<GlobalVariable>(v)) { - addObjCClass(gv); - } - } - - // special case if this data blob is an ObjC category definition - else if (v->getSection().compare(0, 18, "__OBJC,__category,") == 0) { - if (GlobalVariable *gv = dyn_cast<GlobalVariable>(v)) { - addObjCCategory(gv); - } - } - - // special case if this data blob is the list of referenced classes - else if (v->getSection().compare(0, 18, "__OBJC,__cls_refs,") == 0) { - if (GlobalVariable *gv = dyn_cast<GlobalVariable>(v)) { - addObjCClassRef(gv); - } - } - } - - // add external symbols referenced by this data. - for (unsigned count = 0, total = v->getNumOperands(); - count != total; ++count) { - findExternalRefs(v->getOperand(count), mangler); - } -} - - -void LTOModule::addDefinedSymbol(GlobalValue *def, Mangler &mangler, - bool isFunction) { - // ignore all llvm.* symbols - if (def->getName().startswith("llvm.")) - return; - - // string is owned by _defines - const char *symbolName = ::strdup(mangler.getNameWithPrefix(def).c_str()); - - // set alignment part log2() can have rounding errors - uint32_t align = def->getAlignment(); - uint32_t attr = align ? CountTrailingZeros_32(def->getAlignment()) : 0; - - // set permissions part - if (isFunction) - attr |= LTO_SYMBOL_PERMISSIONS_CODE; - else { - GlobalVariable *gv = dyn_cast<GlobalVariable>(def); - if (gv && gv->isConstant()) - attr |= LTO_SYMBOL_PERMISSIONS_RODATA; - else - attr |= LTO_SYMBOL_PERMISSIONS_DATA; - } - - // set definition part - if (def->hasWeakLinkage() || def->hasLinkOnceLinkage()) { - attr |= LTO_SYMBOL_DEFINITION_WEAK; - } - else if (def->hasCommonLinkage()) { - attr |= LTO_SYMBOL_DEFINITION_TENTATIVE; - } - else { - attr |= LTO_SYMBOL_DEFINITION_REGULAR; - } - - // set scope part - if (def->hasHiddenVisibility()) - attr |= LTO_SYMBOL_SCOPE_HIDDEN; - else if (def->hasProtectedVisibility()) - attr |= LTO_SYMBOL_SCOPE_PROTECTED; - else if (def->hasExternalLinkage() || def->hasWeakLinkage() - || def->hasLinkOnceLinkage() || def->hasCommonLinkage()) - attr |= LTO_SYMBOL_SCOPE_DEFAULT; - else - attr |= LTO_SYMBOL_SCOPE_INTERNAL; - - // add to table of symbols - NameAndAttributes info; - info.name = symbolName; - info.attributes = (lto_symbol_attributes)attr; - _symbols.push_back(info); - _defines[info.name] = 1; -} - -void LTOModule::addAsmGlobalSymbol(const char *name) { - // only add new define if not already defined - if (_defines.count(name)) - return; - - // string is owned by _defines - const char *symbolName = ::strdup(name); - uint32_t attr = LTO_SYMBOL_DEFINITION_REGULAR; - attr |= LTO_SYMBOL_SCOPE_DEFAULT; - NameAndAttributes info; - info.name = symbolName; - info.attributes = (lto_symbol_attributes)attr; - _symbols.push_back(info); - _defines[info.name] = 1; -} - -void LTOModule::addPotentialUndefinedSymbol(GlobalValue *decl, - Mangler &mangler) { - // ignore all llvm.* symbols - if (decl->getName().startswith("llvm.")) - return; - - // ignore all aliases - if (isa<GlobalAlias>(decl)) - return; - - std::string name = mangler.getNameWithPrefix(decl); - - // we already have the symbol - if (_undefines.find(name) != _undefines.end()) - return; - - NameAndAttributes info; - // string is owned by _undefines - info.name = ::strdup(name.c_str()); - if (decl->hasExternalWeakLinkage()) - info.attributes = LTO_SYMBOL_DEFINITION_WEAKUNDEF; - else - info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED; - _undefines[name] = info; -} - - - -// Find external symbols referenced by VALUE. This is a recursive function. -void LTOModule::findExternalRefs(Value *value, Mangler &mangler) { - if (GlobalValue *gv = dyn_cast<GlobalValue>(value)) { - if (!gv->hasExternalLinkage()) - addPotentialUndefinedSymbol(gv, mangler); - // If this is a variable definition, do not recursively process - // initializer. It might contain a reference to this variable - // and cause an infinite loop. The initializer will be - // processed in addDefinedDataSymbol(). - return; - } - - // 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), mangler); - } -} - -void LTOModule::lazyParseSymbols() { - if (_symbolsParsed) - return; - - _symbolsParsed = true; - - // Use mangler to add GlobalPrefix to names to match linker names. - MCContext Context(*_target->getMCAsmInfo()); - Mangler mangler(Context, *_target->getTargetData()); - - // add functions - for (Module::iterator f = _module->begin(); f != _module->end(); ++f) { - if (f->isDeclaration()) - addPotentialUndefinedSymbol(f, mangler); - else - addDefinedFunctionSymbol(f, mangler); - } - - // add data - for (Module::global_iterator v = _module->global_begin(), - e = _module->global_end(); v != e; ++v) { - if (v->isDeclaration()) - addPotentialUndefinedSymbol(v, mangler); - else - addDefinedDataSymbol(v, mangler); - } - - // add asm globals - const std::string &inlineAsm = _module->getModuleInlineAsm(); - const std::string glbl = ".globl"; - std::string asmSymbolName; - std::string::size_type pos = inlineAsm.find(glbl, 0); - while (pos != std::string::npos) { - // eat .globl - pos = pos + 6; - - // skip white space between .globl and symbol name - std::string::size_type pbegin = inlineAsm.find_first_not_of(' ', pos); - if (pbegin == std::string::npos) - break; - - // find end-of-line - std::string::size_type pend = inlineAsm.find_first_of('\n', pbegin); - if (pend == std::string::npos) - break; - - asmSymbolName.assign(inlineAsm, pbegin, pend - pbegin); - addAsmGlobalSymbol(asmSymbolName.c_str()); - - // search next .globl - pos = inlineAsm.find(glbl, pend); - } - - // make symbols for all undefines - for (StringMap<NameAndAttributes>::iterator it=_undefines.begin(); - it != _undefines.end(); ++it) { - // if this symbol also has a definition, then don't make an undefine - // because it is a tentative definition - if (_defines.count(it->getKey()) == 0) { - NameAndAttributes info = it->getValue(); - _symbols.push_back(info); - } - } -} - - -uint32_t LTOModule::getSymbolCount() { - lazyParseSymbols(); - return _symbols.size(); -} - - -lto_symbol_attributes LTOModule::getSymbolAttributes(uint32_t index) { - lazyParseSymbols(); - if (index < _symbols.size()) - return _symbols[index].attributes; - else - return lto_symbol_attributes(0); -} - -const char *LTOModule::getSymbolName(uint32_t index) { - lazyParseSymbols(); - if (index < _symbols.size()) - return _symbols[index].name; - else - return NULL; -} diff --git a/contrib/llvm/tools/lto/LTOModule.h b/contrib/llvm/tools/lto/LTOModule.h deleted file mode 100644 index a19acc0..0000000 --- a/contrib/llvm/tools/lto/LTOModule.h +++ /dev/null @@ -1,111 +0,0 @@ -//===-LTOModule.h - LLVM Link Time Optimizer ------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file declares the LTOModule class. -// -//===----------------------------------------------------------------------===// - -#ifndef LTO_MODULE_H -#define LTO_MODULE_H - -#include "llvm/Module.h" -#include "llvm/ADT/OwningPtr.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/ADT/StringMap.h" - -#include "llvm-c/lto.h" - -#include <vector> -#include <string> - - -// forward references to llvm classes -namespace llvm { - class Mangler; - class MemoryBuffer; - class GlobalValue; - class Value; - class Function; -} - - -// -// C++ class which implements the opaque lto_module_t -// -struct LTOModule { - - static bool isBitcodeFile(const void* mem, size_t length); - static bool isBitcodeFile(const char* path); - - static bool isBitcodeFileForTarget(const void* mem, - size_t length, const char* triplePrefix); - - static bool isBitcodeFileForTarget(const char* path, - const char* triplePrefix); - - static LTOModule* makeLTOModule(const char* path, - std::string& errMsg); - static LTOModule* makeLTOModule(const void* mem, size_t length, - std::string& errMsg); - - const char* getTargetTriple(); - void setTargetTriple(const char*); - uint32_t getSymbolCount(); - lto_symbol_attributes getSymbolAttributes(uint32_t index); - const char* getSymbolName(uint32_t index); - - llvm::Module * getLLVVMModule() { return _module.get(); } - -private: - LTOModule(llvm::Module* m, llvm::TargetMachine* t); - - void lazyParseSymbols(); - void addDefinedSymbol(llvm::GlobalValue* def, - llvm::Mangler& mangler, - bool isFunction); - void addPotentialUndefinedSymbol(llvm::GlobalValue* decl, - llvm::Mangler &mangler); - void findExternalRefs(llvm::Value* value, - llvm::Mangler& mangler); - void addDefinedFunctionSymbol(llvm::Function* f, - llvm::Mangler &mangler); - void addDefinedDataSymbol(llvm::GlobalValue* v, - llvm::Mangler &mangler); - void addAsmGlobalSymbol(const char *); - void addObjCClass(llvm::GlobalVariable* clgv); - void addObjCCategory(llvm::GlobalVariable* clgv); - void addObjCClassRef(llvm::GlobalVariable* clgv); - bool objcClassNameFromExpression(llvm::Constant* c, - std::string& name); - - static bool isTargetMatch(llvm::MemoryBuffer* memBuffer, - const char* triplePrefix); - - static LTOModule* makeLTOModule(llvm::MemoryBuffer* buffer, - std::string& errMsg); - static llvm::MemoryBuffer* makeBuffer(const void* mem, size_t length); - - typedef llvm::StringMap<uint8_t> StringSet; - - struct NameAndAttributes { - const char* name; - lto_symbol_attributes attributes; - }; - - llvm::OwningPtr<llvm::Module> _module; - llvm::OwningPtr<llvm::TargetMachine> _target; - bool _symbolsParsed; - std::vector<NameAndAttributes> _symbols; - // _defines and _undefines only needed to disambiguate tentative definitions - StringSet _defines; - llvm::StringMap<NameAndAttributes> _undefines; -}; - -#endif // LTO_MODULE_H - diff --git a/contrib/llvm/tools/lto/Makefile b/contrib/llvm/tools/lto/Makefile deleted file mode 100644 index e157a4c..0000000 --- a/contrib/llvm/tools/lto/Makefile +++ /dev/null @@ -1,54 +0,0 @@ -##===- tools/lto/Makefile ----------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL = ../.. -LIBRARYNAME = LTO - -EXPORTED_SYMBOL_FILE = $(PROJ_SRC_DIR)/lto.exports - -# 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_LIBS_IN_SHARED = 1 -SHARED_LIBRARY = 1 - -LINK_COMPONENTS := $(TARGETS_TO_BUILD) ipo scalaropts linker bitreader bitwriter - -include $(LEVEL)/Makefile.common - -ifeq ($(HOST_OS),Darwin) - # Special hack to allow libLTO to have an offset version number. - ifdef LLVM_LTO_VERSION_OFFSET - LTO_LIBRARY_VERSION := $(shell expr $(LLVM_SUBMIT_VERSION) + \ - $(LLVM_LTO_VERSION_OFFSET)) - else - LTO_LIBRARY_VERSION := $(LLVM_SUBMIT_VERSION) - endif - - # set dylib internal version number to llvmCore submission number - ifdef LLVM_SUBMIT_VERSION - LLVMLibsOptions := $(LLVMLibsOptions) -Wl,-current_version \ - -Wl,$(LTO_LIBRARY_VERSION).$(LLVM_SUBMIT_SUBVERSION) \ - -Wl,-compatibility_version -Wl,1 - endif - # extra options to override libtool defaults - LLVMLibsOptions := $(LLVMLibsOptions) \ - -Wl,-dead_strip \ - -Wl,-seg1addr -Wl,0xE0000000 - - # Mac OS X 10.4 and earlier tools do not allow a second -install_name on command line - DARWIN_VERS := $(shell echo $(TARGET_TRIPLE) | sed 's/.*darwin\([0-9]*\).*/\1/') - ifneq ($(DARWIN_VERS),8) - LLVMLibsOptions := $(LLVMLibsOptions) \ - -Wl,-install_name \ - -Wl,"@executable_path/../lib/lib$(LIBRARYNAME)$(SHLIBEXT)" - endif -endif diff --git a/contrib/llvm/tools/lto/lto.cpp b/contrib/llvm/tools/lto/lto.cpp deleted file mode 100644 index 3d7ef0a..0000000 --- a/contrib/llvm/tools/lto/lto.cpp +++ /dev/null @@ -1,283 +0,0 @@ -//===-lto.cpp - LLVM Link Time Optimizer ----------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the Link Time Optimization library. This library is -// intended to be used by linker to optimize code at link time. -// -//===----------------------------------------------------------------------===// - -#include "llvm-c/lto.h" -#include "llvm-c/Core.h" - -#include "LTOModule.h" -#include "LTOCodeGenerator.h" - - -// holds most recent error string -// *** not thread safe *** -static std::string sLastErrorString; - - - -// -// returns a printable string -// -extern const char* lto_get_version() -{ - return LTOCodeGenerator::getVersionString(); -} - -// -// returns the last error string or NULL if last operation was successful -// -const char* lto_get_error_message() -{ - return sLastErrorString.c_str(); -} - - - -// -// validates if a file is a loadable object file -// -bool lto_module_is_object_file(const char* path) -{ - return LTOModule::isBitcodeFile(path); -} - - -// -// validates if a file is a loadable object file compilable for requested target -// -bool lto_module_is_object_file_for_target(const char* path, - const char* target_triplet_prefix) -{ - return LTOModule::isBitcodeFileForTarget(path, target_triplet_prefix); -} - - -// -// validates if a buffer is a loadable object file -// -bool lto_module_is_object_file_in_memory(const void* mem, size_t length) -{ - return LTOModule::isBitcodeFile(mem, length); -} - - -// -// validates if a buffer is a loadable object file compilable for the target -// -bool lto_module_is_object_file_in_memory_for_target(const void* mem, - size_t length, const char* target_triplet_prefix) -{ - return LTOModule::isBitcodeFileForTarget(mem, length, target_triplet_prefix); -} - - - -// -// loads an object file from disk -// returns NULL on error (check lto_get_error_message() for details) -// -lto_module_t lto_module_create(const char* path) -{ - return LTOModule::makeLTOModule(path, sLastErrorString); -} - - -// -// loads an object file from memory -// returns NULL on error (check lto_get_error_message() for details) -// -lto_module_t lto_module_create_from_memory(const void* mem, size_t length) -{ - return LTOModule::makeLTOModule(mem, length, sLastErrorString); -} - - -// -// frees all memory for a module -// upon return the lto_module_t is no longer valid -// -void lto_module_dispose(lto_module_t mod) -{ - delete mod; -} - - -// -// returns triplet string which the object module was compiled under -// -const char* lto_module_get_target_triple(lto_module_t mod) -{ - return mod->getTargetTriple(); -} - -// -// sets triple string with which the object will be codegened. -// -void lto_module_set_target_triple(lto_module_t mod, const char *triple) -{ - return mod->setTargetTriple(triple); -} - - -// -// returns the number of symbols in the object module -// -uint32_t lto_module_get_num_symbols(lto_module_t mod) -{ - return mod->getSymbolCount(); -} - -// -// returns the name of the ith symbol in the object module -// -const char* lto_module_get_symbol_name(lto_module_t mod, uint32_t index) -{ - return mod->getSymbolName(index); -} - - -// -// returns the attributes of the ith symbol in the object module -// -lto_symbol_attributes lto_module_get_symbol_attribute(lto_module_t mod, - uint32_t index) -{ - return mod->getSymbolAttributes(index); -} - - - - - -// -// instantiates a code generator -// returns NULL if there is an error -// -lto_code_gen_t lto_codegen_create(void) -{ - return new LTOCodeGenerator(); -} - - - -// -// frees all memory for a code generator -// upon return the lto_code_gen_t is no longer valid -// -void lto_codegen_dispose(lto_code_gen_t cg) -{ - delete cg; -} - - - -// -// add an object module to the set of modules for which code will be generated -// returns true on error (check lto_get_error_message() for details) -// -bool lto_codegen_add_module(lto_code_gen_t cg, lto_module_t mod) -{ - return cg->addModule(mod, sLastErrorString); -} - - -// -// sets what if any format of debug info should be generated -// returns true on error (check lto_get_error_message() for details) -// -bool lto_codegen_set_debug_model(lto_code_gen_t cg, lto_debug_model debug) -{ - return cg->setDebugInfo(debug, sLastErrorString); -} - - -// -// sets what code model to generated -// returns true on error (check lto_get_error_message() for details) -// -bool lto_codegen_set_pic_model(lto_code_gen_t cg, lto_codegen_model model) -{ - return cg->setCodePICModel(model, sLastErrorString); -} - -// -// sets the cpu to generate code for -// -void lto_codegen_set_cpu(lto_code_gen_t cg, const char* cpu) -{ - return cg->setCpu(cpu); -} - -// -// sets the path to the assembler tool -// -void lto_codegen_set_assembler_path(lto_code_gen_t cg, const char* path) -{ - cg->setAssemblerPath(path); -} - - -// -// sets extra arguments that libLTO should pass to the assembler -// -void lto_codegen_set_assembler_args(lto_code_gen_t cg, const char** args, - int nargs) -{ - cg->setAssemblerArgs(args, nargs); -} - -// -// adds to a list of all global symbols that must exist in the final -// generated code. If a function is not listed there, it might be -// inlined into every usage and optimized away. -// -void lto_codegen_add_must_preserve_symbol(lto_code_gen_t cg, const char* symbol) -{ - cg->addMustPreserveSymbol(symbol); -} - - -// -// writes a new file at the specified path that contains the -// merged contents of all modules added so far. -// returns true on error (check lto_get_error_message() for details) -// -bool lto_codegen_write_merged_modules(lto_code_gen_t cg, const char* path) -{ - return cg->writeMergedModules(path, sLastErrorString); -} - - -// -// Generates code for all added modules into one native object file. -// On sucess returns a pointer to a generated mach-o/ELF buffer and -// length set to the buffer size. The buffer is owned by the -// lto_code_gen_t and will be freed when lto_codegen_dispose() -// is called, or lto_codegen_compile() is called again. -// On failure, returns NULL (check lto_get_error_message() for details). -// -extern const void* -lto_codegen_compile(lto_code_gen_t cg, size_t* length) -{ - return cg->compile(length, sLastErrorString); -} - - -// -// Used to pass extra options to the code generator -// -extern void -lto_codegen_debug_options(lto_code_gen_t cg, const char * opt) -{ - cg->setCodeGenDebugOptions(opt); -} diff --git a/contrib/llvm/tools/lto/lto.exports b/contrib/llvm/tools/lto/lto.exports deleted file mode 100644 index 4dbf760..0000000 --- a/contrib/llvm/tools/lto/lto.exports +++ /dev/null @@ -1,26 +0,0 @@ -lto_get_error_message -lto_get_version -lto_module_create -lto_module_create_from_memory -lto_module_get_num_symbols -lto_module_get_symbol_attribute -lto_module_get_symbol_name -lto_module_get_target_triple -lto_module_set_target_triple -lto_module_is_object_file -lto_module_is_object_file_for_target -lto_module_is_object_file_in_memory -lto_module_is_object_file_in_memory_for_target -lto_module_dispose -lto_codegen_add_module -lto_codegen_add_must_preserve_symbol -lto_codegen_compile -lto_codegen_create -lto_codegen_dispose -lto_codegen_set_debug_model -lto_codegen_set_pic_model -lto_codegen_write_merged_modules -lto_codegen_debug_options -lto_codegen_set_assembler_args -lto_codegen_set_assembler_path -lto_codegen_set_cpu diff --git a/contrib/llvm/tools/opt/AnalysisWrappers.cpp b/contrib/llvm/tools/opt/AnalysisWrappers.cpp deleted file mode 100644 index a2b57bb..0000000 --- a/contrib/llvm/tools/opt/AnalysisWrappers.cpp +++ /dev/null @@ -1,94 +0,0 @@ -//===- AnalysisWrappers.cpp - Wrappers around non-pass analyses -----------===// -// -// The LLVM Compiler Infrastructure -// -// This file 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 "llvm/Support/raw_ostream.h" -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(ID) {} - virtual bool runOnModule(Module &M) { - for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { - if (!I->isDeclaration()) continue; - - bool PrintedFn = false; - for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); - UI != E; ++UI) { - Instruction *User = dyn_cast<Instruction>(*UI); - if (!User) continue; - - CallSite CS(cast<Value>(User)); - if (!CS) continue; - - for (CallSite::arg_iterator AI = CS.arg_begin(), - E = CS.arg_end(); AI != E; ++AI) { - if (!isa<Constant>(*AI)) continue; - - if (!PrintedFn) { - errs() << "Function '" << I->getName() << "':\n"; - PrintedFn = true; - } - errs() << *User; - break; - } - } - } - - return false; - } - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - } - }; -} - -char ExternalFunctionsPassedConstants::ID = 0; -static RegisterPass<ExternalFunctionsPassedConstants> - P1("print-externalfnconstants", - "Print external fn callsites passed constants"); - -namespace { - struct CallGraphPrinter : public ModulePass { - static char ID; // Pass ID, replacement for typeid - CallGraphPrinter() : ModulePass(ID) {} - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - AU.addRequiredTransitive<CallGraph>(); - } - virtual bool runOnModule(Module &M) { - getAnalysis<CallGraph>().print(errs(), &M); - return false; - } - }; -} - -char CallGraphPrinter::ID = 0; -static RegisterPass<CallGraphPrinter> - P2("print-callgraph", "Print a call graph"); diff --git a/contrib/llvm/tools/opt/CMakeLists.txt b/contrib/llvm/tools/opt/CMakeLists.txt deleted file mode 100644 index 0570d0e..0000000 --- a/contrib/llvm/tools/opt/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -set(LLVM_LINK_COMPONENTS bitreader asmparser bitwriter instrumentation scalaropts ipo) - -add_llvm_tool(opt - AnalysisWrappers.cpp - GraphPrinters.cpp - PrintSCC.cpp - opt.cpp - ) diff --git a/contrib/llvm/tools/opt/GraphPrinters.cpp b/contrib/llvm/tools/opt/GraphPrinters.cpp deleted file mode 100644 index 9de7d6a..0000000 --- a/contrib/llvm/tools/opt/GraphPrinters.cpp +++ /dev/null @@ -1,123 +0,0 @@ -//===- GraphPrinters.cpp - DOT printers for various graph types -----------===// -// -// The LLVM Compiler Infrastructure -// -// This file 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 "llvm/Analysis/Dominators.h" -#include "llvm/Support/raw_ostream.h" -using namespace llvm; - -template<typename GraphType> -static void WriteGraphToFile(raw_ostream &O, const std::string &GraphName, - const GraphType >) { - std::string Filename = GraphName + ".dot"; - O << "Writing '" << Filename << "'..."; - std::string ErrInfo; - tool_output_file F(Filename.c_str(), ErrInfo); - - if (ErrInfo.empty()) { - WriteGraph(F.os(), GT); - F.os().close(); - if (!F.os().has_error()) { - O << "\n"; - F.keep(); - return; - } - } - O << " error opening file for writing!\n"; - F.os().clear_error(); -} - - -//===----------------------------------------------------------------------===// -// Call Graph Printer -//===----------------------------------------------------------------------===// - -namespace llvm { - template<> - struct DOTGraphTraits<CallGraph*> : public DefaultDOTGraphTraits { - - DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {} - - 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 "external node"; - } - }; -} - - -namespace { - struct CallGraphPrinter : public ModulePass { - static char ID; // Pass ID, replacement for typeid - CallGraphPrinter() : ModulePass(ID) {} - - virtual bool runOnModule(Module &M) { - WriteGraphToFile(llvm::errs(), "callgraph", &getAnalysis<CallGraph>()); - return false; - } - - void print(raw_ostream &OS, const llvm::Module*) const {} - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired<CallGraph>(); - AU.setPreservesAll(); - } - }; -} - -char CallGraphPrinter::ID = 0; -static RegisterPass<CallGraphPrinter> P2("dot-callgraph", - "Print Call Graph to 'dot' file"); - -//===----------------------------------------------------------------------===// -// DomInfoPrinter Pass -//===----------------------------------------------------------------------===// - -namespace { - class DomInfoPrinter : public FunctionPass { - public: - static char ID; // Pass identification, replacement for typeid - DomInfoPrinter() : FunctionPass(ID) {} - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - AU.addRequired<DominatorTree>(); - AU.addRequired<DominanceFrontier>(); - - } - - virtual bool runOnFunction(Function &F) { - DominatorTree &DT = getAnalysis<DominatorTree>(); - DT.dump(); - DominanceFrontier &DF = getAnalysis<DominanceFrontier>(); - DF.dump(); - return false; - } - }; -} - -char DomInfoPrinter::ID = 0; -static RegisterPass<DomInfoPrinter> -DIP("print-dom-info", "Dominator Info Printer", true, true); diff --git a/contrib/llvm/tools/opt/Makefile b/contrib/llvm/tools/opt/Makefile deleted file mode 100644 index 726cad8..0000000 --- a/contrib/llvm/tools/opt/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -##===- tools/opt/Makefile ----------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -LEVEL = ../.. -TOOLNAME = opt - -LINK_COMPONENTS := bitreader bitwriter asmparser instrumentation scalaropts ipo - -include $(LEVEL)/Makefile.common diff --git a/contrib/llvm/tools/opt/PrintSCC.cpp b/contrib/llvm/tools/opt/PrintSCC.cpp deleted file mode 100644 index 533f49e..0000000 --- a/contrib/llvm/tools/opt/PrintSCC.cpp +++ /dev/null @@ -1,112 +0,0 @@ -//===- PrintSCC.cpp - Enumerate SCCs in some key graphs -------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file 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 -print-cfg-sccs to print the SCCs in each CFG of a module. -// analyze -print-cfg-sccs -stats to print the #SCCs and the maximum SCC size. -// analyze -print-cfg-sccs -debug > /dev/null to watch the algorithm in action. -// -// and similarly: -// analyze -print-callgraph-sccs [-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/Support/raw_ostream.h" -#include "llvm/ADT/SCCIterator.h" -using namespace llvm; - -namespace { - struct CFGSCC : public FunctionPass { - static char ID; // Pass identification, replacement for typeid - CFGSCC() : FunctionPass(ID) {} - bool runOnFunction(Function& func); - - void print(raw_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(ID) {} - - // run - Print out SCCs in the call graph for the specified module. - bool runOnModule(Module &M); - - void print(raw_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; -static RegisterPass<CFGSCC> -Y("print-cfg-sccs", "Print SCCs of each function CFG"); - -char CallGraphSCC::ID = 0; -static RegisterPass<CallGraphSCC> -Z("print-callgraph-sccs", "Print SCCs of the Call Graph"); - -bool CFGSCC::runOnFunction(Function &F) { - unsigned sccNum = 0; - errs() << "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; - errs() << "\nSCC #" << ++sccNum << " : "; - for (std::vector<BasicBlock*>::const_iterator I = nextSCC.begin(), - E = nextSCC.end(); I != E; ++I) - errs() << (*I)->getName() << ", "; - if (nextSCC.size() == 1 && SCCI.hasLoop()) - errs() << " (Has self-loop)."; - } - errs() << "\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; - errs() << "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; - errs() << "\nSCC #" << ++sccNum << " : "; - for (std::vector<CallGraphNode*>::const_iterator I = nextSCC.begin(), - E = nextSCC.end(); I != E; ++I) - errs() << ((*I)->getFunction() ? (*I)->getFunction()->getNameStr() - : std::string("external node")) << ", "; - if (nextSCC.size() == 1 && SCCI.hasLoop()) - errs() << " (Has self-loop)."; - } - errs() << "\n"; - - return true; -} diff --git a/contrib/llvm/tools/opt/opt.cpp b/contrib/llvm/tools/opt/opt.cpp deleted file mode 100644 index d837185..0000000 --- a/contrib/llvm/tools/opt/opt.cpp +++ /dev/null @@ -1,557 +0,0 @@ -//===- opt.cpp - The LLVM Modular Optimizer -------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file 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/LLVMContext.h" -#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/Debug.h" -#include "llvm/Support/IRReader.h" -#include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/PluginLoader.h" -#include "llvm/Support/PrettyStackTrace.h" -#include "llvm/Support/StandardPasses.h" -#include "llvm/Support/SystemUtils.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/LinkAllPasses.h" -#include "llvm/LinkAllVMCore.h" -#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")); - -static cl::opt<bool> -Force("f", cl::desc("Enable binary output on terminals")); - -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> -OutputAssembly("S", cl::desc("Write output as LLVM assembly")); - -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> -DisableInternalize("disable-internalize", - cl::desc("Do not mark all symbols as internal")); - -static cl::opt<bool> -StandardCompileOpts("std-compile-opts", - cl::desc("Include the standard compile time optimizations")); - -static cl::opt<bool> -StandardLinkOpts("std-link-opts", - cl::desc("Include the standard link time optimizations")); - -static cl::opt<bool> -OptLevelO1("O1", - cl::desc("Optimization level 1. Similar to llvm-gcc -O1")); - -static cl::opt<bool> -OptLevelO2("O2", - cl::desc("Optimization level 2. Similar to llvm-gcc -O2")); - -static cl::opt<bool> -OptLevelO3("O3", - cl::desc("Optimization level 3. Similar to llvm-gcc -O3")); - -static cl::opt<bool> -UnitAtATime("funit-at-a-time", - cl::desc("Enable IPO. This is same as llvm-gcc's -funit-at-a-time"), - cl::init(true)); - -static cl::opt<bool> -DisableSimplifyLibCalls("disable-simplify-libcalls", - cl::desc("Disable simplify-libcalls")); - -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")); - -static cl::opt<std::string> -DefaultDataLayout("default-data-layout", - cl::desc("data layout string to use if not specified by module"), - cl::value_desc("layout-string"), cl::init("")); - -// ---------- Define Printers for module and function passes ------------ -namespace { - -struct CallGraphSCCPassPrinter : public CallGraphSCCPass { - static char ID; - const PassInfo *PassToPrint; - raw_ostream &Out; - CallGraphSCCPassPrinter(const PassInfo *PI, raw_ostream &out) : - CallGraphSCCPass(ID), PassToPrint(PI), Out(out) {} - - virtual bool runOnSCC(CallGraphSCC &SCC) { - if (!Quiet) { - Out << "Printing analysis '" << PassToPrint->getPassName() << "':\n"; - - for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) { - Function *F = (*I)->getFunction(); - if (F) - getAnalysisID<Pass>(PassToPrint->getTypeInfo()).print(Out, - 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->getTypeInfo()); - AU.setPreservesAll(); - } -}; - -char CallGraphSCCPassPrinter::ID = 0; - -struct ModulePassPrinter : public ModulePass { - static char ID; - const PassInfo *PassToPrint; - raw_ostream &Out; - ModulePassPrinter(const PassInfo *PI, raw_ostream &out) - : ModulePass(ID), PassToPrint(PI), Out(out) {} - - virtual bool runOnModule(Module &M) { - if (!Quiet) { - Out << "Printing analysis '" << PassToPrint->getPassName() << "':\n"; - getAnalysisID<Pass>(PassToPrint->getTypeInfo()).print(Out, &M); - } - - // Get and print pass... - return false; - } - - virtual const char *getPassName() const { return "'Pass' Printer"; } - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequiredID(PassToPrint->getTypeInfo()); - AU.setPreservesAll(); - } -}; - -char ModulePassPrinter::ID = 0; -struct FunctionPassPrinter : public FunctionPass { - const PassInfo *PassToPrint; - raw_ostream &Out; - static char ID; - FunctionPassPrinter(const PassInfo *PI, raw_ostream &out) - : FunctionPass(ID), PassToPrint(PI), Out(out) {} - - virtual bool runOnFunction(Function &F) { - if (!Quiet) { - Out << "Printing analysis '" << PassToPrint->getPassName() - << "' for function '" << F.getName() << "':\n"; - } - // Get and print pass... - getAnalysisID<Pass>(PassToPrint->getTypeInfo()).print(Out, - F.getParent()); - return false; - } - - virtual const char *getPassName() const { return "FunctionPass Printer"; } - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequiredID(PassToPrint->getTypeInfo()); - AU.setPreservesAll(); - } -}; - -char FunctionPassPrinter::ID = 0; - -struct LoopPassPrinter : public LoopPass { - static char ID; - const PassInfo *PassToPrint; - raw_ostream &Out; - LoopPassPrinter(const PassInfo *PI, raw_ostream &out) : - LoopPass(ID), PassToPrint(PI), Out(out) {} - - virtual bool runOnLoop(Loop *L, LPPassManager &LPM) { - if (!Quiet) { - Out << "Printing analysis '" << PassToPrint->getPassName() << "':\n"; - getAnalysisID<Pass>(PassToPrint->getTypeInfo()).print(Out, - 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->getTypeInfo()); - AU.setPreservesAll(); - } -}; - -char LoopPassPrinter::ID = 0; - -struct BasicBlockPassPrinter : public BasicBlockPass { - const PassInfo *PassToPrint; - raw_ostream &Out; - static char ID; - BasicBlockPassPrinter(const PassInfo *PI, raw_ostream &out) - : BasicBlockPass(ID), PassToPrint(PI), Out(out) {} - - virtual bool runOnBasicBlock(BasicBlock &BB) { - if (!Quiet) { - Out << "Printing Analysis info for BasicBlock '" << BB.getName() - << "': Pass " << PassToPrint->getPassName() << ":\n"; - } - - // Get and print pass... - getAnalysisID<Pass>(PassToPrint->getTypeInfo()).print(Out, - BB.getParent()->getParent()); - return false; - } - - virtual const char *getPassName() const { return "BasicBlockPass Printer"; } - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequiredID(PassToPrint->getTypeInfo()); - AU.setPreservesAll(); - } -}; - -char BasicBlockPassPrinter::ID = 0; -inline void addPass(PassManagerBase &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()); -} - -/// AddOptimizationPasses - This routine adds optimization passes -/// based on selected optimization level, OptLevel. This routine -/// duplicates llvm-gcc behaviour. -/// -/// OptLevel - Optimization Level -void AddOptimizationPasses(PassManagerBase &MPM, PassManagerBase &FPM, - unsigned OptLevel) { - createStandardFunctionPasses(&FPM, OptLevel); - - llvm::Pass *InliningPass = 0; - if (DisableInline) { - // No inlining pass - } else if (OptLevel) { - unsigned Threshold = 200; - if (OptLevel > 2) - Threshold = 250; - InliningPass = createFunctionInliningPass(Threshold); - } else { - InliningPass = createAlwaysInlinerPass(); - } - createStandardModulePasses(&MPM, OptLevel, - /*OptimizeSize=*/ false, - UnitAtATime, - /*UnrollLoops=*/ OptLevel > 1, - !DisableSimplifyLibCalls, - /*HaveExceptions=*/ true, - InliningPass); -} - -void AddStandardCompilePasses(PassManagerBase &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; - - llvm::Pass *InliningPass = !DisableInline ? createFunctionInliningPass() : 0; - - // -std-compile-opts adds the same module passes as -O3. - createStandardModulePasses(&PM, 3, - /*OptimizeSize=*/ false, - /*UnitAtATime=*/ true, - /*UnrollLoops=*/ true, - /*SimplifyLibCalls=*/ true, - /*HaveExceptions=*/ true, - InliningPass); -} - -void AddStandardLinkPasses(PassManagerBase &PM) { - PM.add(createVerifierPass()); // Verify that input is correct - - // If the -strip-debug command line option was specified, do it. - if (StripDebug) - addPass(PM, createStripSymbolsPass(true)); - - if (DisableOptimizations) return; - - createStandardLTOPasses(&PM, /*Internalize=*/ !DisableInternalize, - /*RunInliner=*/ !DisableInline, - /*VerifyEach=*/ VerifyEach); -} - -} // anonymous namespace - - -//===----------------------------------------------------------------------===// -// main for opt -// -int main(int argc, char **argv) { - sys::PrintStackTraceOnErrorSignal(); - llvm::PrettyStackTraceProgram X(argc, argv); - - if (AnalyzeOnly && NoOutput) { - errs() << argv[0] << ": analyze mode conflicts with no-output mode.\n"; - return 1; - } - - // Enable debug stream buffering. - EnableDebugBuffering = true; - - llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. - LLVMContext &Context = getGlobalContext(); - - cl::ParseCommandLineOptions(argc, argv, - "llvm .bc -> .bc modular optimizer and analysis printer\n"); - - // 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; - - SMDiagnostic Err; - - // Load the input module... - std::auto_ptr<Module> M; - M.reset(ParseIRFile(InputFilename, Err, Context)); - - if (M.get() == 0) { - Err.Print(argv[0], errs()); - return 1; - } - - // Figure out what stream we are supposed to write to... - OwningPtr<tool_output_file> Out; - if (NoOutput) { - if (!OutputFilename.empty()) - errs() << "WARNING: The -o (output filename) option is ignored when\n" - "the --disable-output option is used.\n"; - } else { - // Default to standard output. - if (OutputFilename.empty()) - OutputFilename = "-"; - - std::string ErrorInfo; - Out.reset(new tool_output_file(OutputFilename.c_str(), ErrorInfo, - raw_fd_ostream::F_Binary)); - if (!ErrorInfo.empty()) { - errs() << ErrorInfo << '\n'; - return 1; - } - } - - // 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 && !AnalyzeOnly && !OutputAssembly) - if (CheckBitcodeOutputToConsole(Out->os(), !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... - TargetData *TD = 0; - const std::string &ModuleDataLayout = M.get()->getDataLayout(); - if (!ModuleDataLayout.empty()) - TD = new TargetData(ModuleDataLayout); - else if (!DefaultDataLayout.empty()) - TD = new TargetData(DefaultDataLayout); - - if (TD) - Passes.add(TD); - - OwningPtr<PassManager> FPasses; - if (OptLevelO1 || OptLevelO2 || OptLevelO3) { - FPasses.reset(new PassManager()); - if (TD) - FPasses->add(new TargetData(*TD)); - } - - // If the -strip-debug command line option was specified, add it. If - // -std-compile-opts was also specified, it will handle StripDebug. - if (StripDebug && !StandardCompileOpts) - 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) { - // Check to see if -std-compile-opts was specified before this option. If - // so, handle it. - if (StandardCompileOpts && - StandardCompileOpts.getPosition() < PassList.getPosition(i)) { - AddStandardCompilePasses(Passes); - StandardCompileOpts = false; - } - - if (StandardLinkOpts && - StandardLinkOpts.getPosition() < PassList.getPosition(i)) { - AddStandardLinkPasses(Passes); - StandardLinkOpts = false; - } - - if (OptLevelO1 && OptLevelO1.getPosition() < PassList.getPosition(i)) { - AddOptimizationPasses(Passes, *FPasses, 1); - OptLevelO1 = false; - } - - if (OptLevelO2 && OptLevelO2.getPosition() < PassList.getPosition(i)) { - AddOptimizationPasses(Passes, *FPasses, 2); - OptLevelO2 = false; - } - - if (OptLevelO3 && OptLevelO3.getPosition() < PassList.getPosition(i)) { - AddOptimizationPasses(Passes, *FPasses, 3); - OptLevelO3 = false; - } - - const PassInfo *PassInf = PassList[i]; - Pass *P = 0; - if (PassInf->getNormalCtor()) - P = PassInf->getNormalCtor()(); - else - errs() << argv[0] << ": cannot create pass: " - << PassInf->getPassName() << "\n"; - if (P) { - PassKind Kind = P->getPassKind(); - addPass(Passes, P); - - if (AnalyzeOnly) { - switch (Kind) { - case PT_BasicBlock: - Passes.add(new BasicBlockPassPrinter(PassInf, Out->os())); - break; - case PT_Loop: - Passes.add(new LoopPassPrinter(PassInf, Out->os())); - break; - case PT_Function: - Passes.add(new FunctionPassPrinter(PassInf, Out->os())); - break; - case PT_CallGraphSCC: - Passes.add(new CallGraphSCCPassPrinter(PassInf, Out->os())); - break; - default: - Passes.add(new ModulePassPrinter(PassInf, Out->os())); - break; - } - } - } - - if (PrintEachXForm) - Passes.add(createPrintModulePass(&errs())); - } - - // If -std-compile-opts was specified at the end of the pass list, add them. - if (StandardCompileOpts) { - AddStandardCompilePasses(Passes); - StandardCompileOpts = false; - } - - if (StandardLinkOpts) { - AddStandardLinkPasses(Passes); - StandardLinkOpts = false; - } - - if (OptLevelO1) - AddOptimizationPasses(Passes, *FPasses, 1); - - if (OptLevelO2) - AddOptimizationPasses(Passes, *FPasses, 2); - - if (OptLevelO3) - AddOptimizationPasses(Passes, *FPasses, 3); - - if (OptLevelO1 || OptLevelO2 || OptLevelO3) - FPasses->run(*M.get()); - - // Check that the module is well formed on completion of optimization - if (!NoVerify && !VerifyEach) - Passes.add(createVerifierPass()); - - // Write bitcode or assembly to the output as the last step... - if (!NoOutput && !AnalyzeOnly) { - if (OutputAssembly) - Passes.add(createPrintModulePass(&Out->os())); - else - Passes.add(createBitcodeWriterPass(Out->os())); - } - - // Now that we have all of the passes ready, run them. - Passes.run(*M.get()); - - // Declare success. - if (!NoOutput) - Out->keep(); - - return 0; -} |