include_directories( ${LLVM_BINARY_DIR}/include ${LLVM_MAIN_INCLUDE_DIR})
if( ${CMAKE_SYSTEM_NAME} MATCHES SunOS )
- SET(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} "-include llvm/System/Solaris.h")
+ SET(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} "-include llvm/Support/Solaris.h")
endif( ${CMAKE_SYSTEM_NAME} MATCHES SunOS )
include(AddLLVM)
endif()
add_subdirectory(lib/Support)
-add_subdirectory(lib/System)
-# Everything else depends on Support and System:
+# Everything else depends on Support:
set(LLVM_COMMON_DEPENDS ${LLVM_COMMON_DEPENDS} ${LLVM_LIBS} )
set(LLVM_TABLEGEN "tblgen" CACHE
set( td ${LLVM_MAIN_SRC_DIR}/lib/Target/${t} )
file(GLOB asmp_file "${td}/*AsmPrinter.cpp")
if( asmp_file )
- set(LLVM_ENUM_ASM_PRINTERS
+ set(LLVM_ENUM_ASM_PRINTERS
"${LLVM_ENUM_ASM_PRINTERS}LLVM_ASM_PRINTER(${t})\n")
endif()
if( EXISTS ${td}/InstPrinter/CMakeLists.txt )
endif()
if( EXISTS ${td}/AsmParser/CMakeLists.txt )
add_subdirectory(lib/Target/${t}/AsmParser)
- set(LLVM_ENUM_ASM_PARSERS
+ set(LLVM_ENUM_ASM_PARSERS
"${LLVM_ENUM_ASM_PARSERS}LLVM_ASM_PARSER(${t})\n")
endif()
if( EXISTS ${td}/Disassembler/CMakeLists.txt )
LEVEL := .
# Top-Level LLVM Build Stages:
-# 1. Build lib/System and lib/Support, which are used by utils (tblgen).
+# 1. Build lib/Support, which is used by utils (tblgen).
# 2. Build utils, which is used by VMCore.
# 3. Build VMCore, which builds the Intrinsics.inc file used by libs.
# 4. Build libs, which are needed by llvm-config.
ifneq ($(findstring llvmCore, $(RC_ProjectName)),llvmCore) # Normal build (not "Apple-style").
ifeq ($(BUILD_DIRS_ONLY),1)
- DIRS := lib/System lib/Support utils
+ DIRS := lib/Support utils
OPTIONAL_DIRS :=
else
- DIRS := lib/System lib/Support utils lib/VMCore lib tools/llvm-shlib \
+ DIRS := lib/Support utils lib/VMCore lib tools/llvm-shlib \
tools/llvm-config tools runtime docs unittests
OPTIONAL_DIRS := projects bindings
endif
$(Echo) Eliminating files constructed by configure
$(Verb) $(RM) -f \
$(TopDistDir)/include/llvm/Config/config.h \
- $(TopDistDir)/include/llvm/System/DataTypes.h
+ $(TopDistDir)/include/llvm/Support/DataTypes.h
clang-only: all
tools-only: all
include/llvm/Config/AsmPrinters.def \
include/llvm/Config/AsmParsers.def \
include/llvm/Config/Disassemblers.def \
- include/llvm/System/DataTypes.h \
+ include/llvm/Support/DataTypes.h \
tools/llvmc/src/Base.td
FilesToConfigPATH := $(addprefix $(LLVM_OBJ_ROOT)/,$(FilesToConfig))
endif
ifeq ($(HOST_OS),SunOS)
-CPP.BaseFlags += -include llvm/System/Solaris.h
+CPP.BaseFlags += -include llvm/Support/Solaris.h
endif
ifeq ($(HOST_OS),AuroraUX)
-CPP.BaseFlags += -include llvm/System/Solaris.h
+CPP.BaseFlags += -include llvm/Support/Solaris.h
endif # !HOST_OS - AuroraUX.
LD.Flags += -L$(LibDir) -L$(LLVMLibDir)
AC_SUBST(NOLINKALL,$llvm_cv_no_link_all_option)
dnl Set the "LLVM_ON_*" variables based on llvm_cv_platform_type
-dnl This is used by lib/System to determine the basic kind of implementation
+dnl This is used by lib/Support to determine the basic kind of implementation
dnl to use.
case $llvm_cv_platform_type in
Unix)
AC_CONFIG_FILES([include/llvm/Config/AsmPrinters.def])
AC_CONFIG_FILES([include/llvm/Config/AsmParsers.def])
AC_CONFIG_FILES([include/llvm/Config/Disassemblers.def])
-AC_CONFIG_HEADERS([include/llvm/System/DataTypes.h])
+AC_CONFIG_HEADERS([include/llvm/Support/DataTypes.h])
dnl Configure the makefile's configuration data
AC_CONFIG_FILES([Makefile.config])
)
configure_file(
- ${LLVM_MAIN_INCLUDE_DIR}/llvm/System/DataTypes.h.cmake
- ${LLVM_BINARY_DIR}/include/llvm/System/DataTypes.h
+ ${LLVM_MAIN_INCLUDE_DIR}/llvm/Support/DataTypes.h.cmake
+ ${LLVM_BINARY_DIR}/include/llvm/Support/DataTypes.h
)
ac_config_files="$ac_config_files include/llvm/Config/Disassemblers.def"
-ac_config_headers="$ac_config_headers include/llvm/System/DataTypes.h"
+ac_config_headers="$ac_config_headers include/llvm/Support/DataTypes.h"
ac_config_files="$ac_config_files Makefile.config"
"include/llvm/Config/AsmPrinters.def") CONFIG_FILES="$CONFIG_FILES include/llvm/Config/AsmPrinters.def" ;;
"include/llvm/Config/AsmParsers.def") CONFIG_FILES="$CONFIG_FILES include/llvm/Config/AsmParsers.def" ;;
"include/llvm/Config/Disassemblers.def") CONFIG_FILES="$CONFIG_FILES include/llvm/Config/Disassemblers.def" ;;
- "include/llvm/System/DataTypes.h") CONFIG_HEADERS="$CONFIG_HEADERS include/llvm/System/DataTypes.h" ;;
+ "include/llvm/Support/DataTypes.h") CONFIG_HEADERS="$CONFIG_HEADERS include/llvm/Support/DataTypes.h" ;;
"Makefile.config") CONFIG_FILES="$CONFIG_FILES Makefile.config" ;;
"llvm.spec") CONFIG_FILES="$CONFIG_FILES llvm.spec" ;;
"tools/llvmc/src/Base.td") CONFIG_FILES="$CONFIG_FILES tools/llvmc/src/Base.td" ;;
#ifndef LLVM_C_ENHANCEDDISASSEMBLY_H
#define LLVM_C_ENHANCEDDISASSEMBLY_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#ifdef __cplusplus
extern "C" {
#ifndef LLVM_ADT_EQUIVALENCECLASSES_H
#define LLVM_ADT_EQUIVALENCECLASSES_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <cassert>
#include <set>
#ifndef LLVM_ADT_FOLDINGSET_H
#define LLVM_ADT_FOLDINGSET_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
#include "llvm/ADT/FoldingSet.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <cassert>
namespace llvm {
#include "llvm/Support/Allocator.h"
#include "llvm/ADT/FoldingSet.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <cassert>
#include <functional>
#include <cassert>
#include <cstring>
#include <iterator>
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
namespace llvm {
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#ifndef LLVM_ADT_STATISTIC_H
#define LLVM_ADT_STATISTIC_H
-#include "llvm/System/Atomic.h"
+#include "llvm/Support/Atomic.h"
namespace llvm {
class raw_ostream;
#ifndef LLVM_ADT_STRINGEXTRAS_H
#define LLVM_ADT_STRINGEXTRAS_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/StringRef.h"
#include <cctype>
#define LLVM_ADT_TWINE_H
#include "llvm/ADT/StringRef.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <cassert>
#include <string>
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/ValueHandle.h"
#include "llvm/Support/type_traits.h"
-#include "llvm/System/Mutex.h"
+#include "llvm/Support/Mutex.h"
#include <iterator>
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Support/ValueHandle.h"
-#include "llvm/System/IncludeFile.h"
+#include "llvm/Support/IncludeFile.h"
#include <map>
namespace llvm {
#ifndef LLVM_ANALYSIS_DIBUILDER_H
#define LLVM_ANALYSIS_DIBUILDER_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/ADT/StringRef.h"
namespace llvm {
#include "llvm/Pass.h"
#include "llvm/Instructions.h"
#include "llvm/Function.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ValueHandle.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/ConstantRange.h"
#ifndef LLVM_ANALYSIS_VALUETRACKING_H
#define LLVM_ANALYSIS_VALUETRACKING_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <string>
namespace llvm {
#include "llvm/SymbolTableListTraits.h"
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/Twine.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
/// tables. The type of a BasicBlock is "Type::LabelTy" because the basic block
/// represents a label to which a branch can jump.
///
-/// A well formed basic block is formed of a list of non-terminating
-/// instructions followed by a single TerminatorInst instruction.
-/// TerminatorInst's may not occur in the middle of basic blocks, and must
+/// A well formed basic block is formed of a list of non-terminating
+/// instructions followed by a single TerminatorInst instruction.
+/// TerminatorInst's may not occur in the middle of basic blocks, and must
/// terminate the blocks. The BasicBlock class allows malformed basic blocks to
/// occur because it may be useful in the intermediate stage of constructing or
/// modifying a program. However, the verifier will ensure that basic blocks
public:
/// getContext - Get the context in which this basic block lives.
LLVMContext &getContext() const;
-
+
/// Instruction iterators...
typedef InstListType::iterator iterator;
typedef InstListType::const_iterator const_iterator;
/// Create - Creates a new BasicBlock. If the Parent parameter is specified,
/// the basic block is automatically inserted at either the end of the
/// function (if InsertBefore is 0), or before the specified basic block.
- static BasicBlock *Create(LLVMContext &Context, const Twine &Name = "",
+ static BasicBlock *Create(LLVMContext &Context, const Twine &Name = "",
Function *Parent = 0,BasicBlock *InsertBefore = 0) {
return new BasicBlock(Context, Name, Parent, InsertBefore);
}
/// and BlockAddress's).
User *use_back() { return cast<User>(*use_begin());}
const User *use_back() const { return cast<User>(*use_begin());}
-
+
/// getTerminator() - If this is a well formed basic block, then this returns
/// a pointer to the terminator instruction. If it is not, then you get a
/// null pointer back.
///
TerminatorInst *getTerminator();
const TerminatorInst *getTerminator() const;
-
- /// Returns a pointer to the first instructon in this block that is not a
+
+ /// Returns a pointer to the first instructon in this block that is not a
/// PHINode instruction. When adding instruction to the beginning of the
/// basic block, they should be added before the returned value, not before
/// the first instruction, which might be PHI.
const Instruction* getFirstNonPHIOrDbg() const {
return const_cast<BasicBlock*>(this)->getFirstNonPHIOrDbg();
}
-
+
/// removeFromParent - This method unlinks 'this' from the containing
/// function, but does not delete it.
///
/// and deletes it.
///
void eraseFromParent();
-
+
/// moveBefore - Unlink this basic block from its current function and
/// insert it into the function that MovePos lives in, right before MovePos.
void moveBefore(BasicBlock *MovePos);
-
+
/// moveAfter - Unlink this basic block from its current function and
/// insert it into the function that MovePos lives in, right after MovePos.
void moveAfter(BasicBlock *MovePos);
-
+
/// getSinglePredecessor - If this basic block has a single predecessor block,
/// return the block, otherwise return a null pointer.
/// getUniquePredecessor - If this basic block has a unique predecessor block,
/// return the block, otherwise return a null pointer.
- /// Note that unique predecessor doesn't mean single edge, there can be
- /// multiple edges from the unique predecessor to this block (for example
+ /// Note that unique predecessor doesn't mean single edge, there can be
+ /// multiple edges from the unique predecessor to this block (for example
/// a switch statement with multiple cases having the same destination).
BasicBlock *getUniquePredecessor();
const BasicBlock *getUniquePredecessor() const {
/// hasAddressTaken - returns true if there are any uses of this basic block
/// other than direct branches, switches, etc. to it.
bool hasAddressTaken() const { return getSubclassDataFromValue() != 0; }
-
+
private:
/// AdjustBlockAddressRefCount - BasicBlock stores the number of BlockAddress
/// objects using it. This is almost always 0, sometimes one, possibly but
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
-#include "llvm/System/Path.h"
+#include "llvm/Support/Path.h"
#include <map>
#include <set>
#define LLVM_BITCODE_BITCODES_H
#include "llvm/ADT/SmallVector.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <cassert>
namespace llvm {
#define LLVM_CODEGEN_ASMPRINTER_H
#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
class BlockAddress;
#define LLVM_CODEGEN_BINARYOBJECT_H
#include "llvm/CodeGen/MachineRelocation.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <string>
#include <vector>
#define LLVM_CODEGEN_JITCODEEMITTER_H
#include <string>
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/CodeGen/MachineCodeEmitter.h"
#include "llvm/ADT/DenseMap.h"
#ifndef LLVM_CODEGEN_MACHO_RELOCATION_H
#define LLVM_CODEGEN_MACHO_RELOCATION_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
#ifndef LLVM_CODEGEN_MACHINECODEEMITTER_H
#define LLVM_CODEGEN_MACHINECODEEMITTER_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/Support/DebugLoc.h"
namespace llvm {
#ifndef EE_MACHINE_CODE_INFO_H
#define EE_MACHINE_CODE_INFO_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
#include "llvm/ADT/SmallVector.h"
//#include "llvm/ADT/IndexedMap.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <cassert>
#include <vector>
#ifndef LLVM_CODEGEN_MACHINEMEMOPERAND_H
#define LLVM_CODEGEN_MACHINEMEMOPERAND_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/DebugLoc.h"
#include "llvm/Support/ValueHandle.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallPtrSet.h"
#ifndef LLVM_CODEGEN_MACHINEOPERAND_H
#define LLVM_CODEGEN_MACHINEOPERAND_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <cassert>
namespace llvm {
#ifndef LLVM_CODEGEN_MACHINERELOCATION_H
#define LLVM_CODEGEN_MACHINERELOCATION_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <cassert>
namespace llvm {
#define LLVM_CODEGEN_EXACTHAZARDRECOGNIZER_H
#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <cassert>
#include <cstring>
//
//===----------------------------------------------------------------------===//
-#include "llvm/System/IncludeFile.h"
+#include "llvm/Support/IncludeFile.h"
#include "llvm/CodeGen/LiveInterval.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/Support/MathExtras.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/Support/DebugLoc.h"
#include <cassert>
#include <cassert>
#include <string>
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/Support/MathExtras.h"
namespace llvm {
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringSet.h"
-#include "llvm/System/Path.h"
+#include "llvm/Support/Path.h"
#include <cassert>
#include <string>
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/StringSet.h"
-#include "llvm/System/Path.h"
+#include "llvm/Support/Path.h"
#include <string>
#include <vector>
#define LLVM_DERIVED_TYPES_H
#include "llvm/Type.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/ValueMap.h"
#include "llvm/Support/ValueHandle.h"
-#include "llvm/System/Mutex.h"
+#include "llvm/Support/Mutex.h"
#include "llvm/Target/TargetMachine.h"
namespace llvm {
#define GENERIC_VALUE_H
#include "llvm/ADT/APInt.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
#ifndef LLVM_EXECUTION_ENGINE_JIT_EVENTLISTENER_H
#define LLVM_EXECUTION_ENGINE_JIT_EVENTLISTENER_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/Support/DebugLoc.h"
#include <vector>
#ifndef LLVM_EXECUTION_ENGINE_JIT_MEMMANAGER_H
#define LLVM_EXECUTION_ENGINE_JIT_MEMMANAGER_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <string>
namespace llvm {
#include "llvm/IntrinsicInst.h"
#include "llvm/InlineAsm.h"
#include "llvm/Analysis/Verifier.h"
-#include "llvm/System/Alarm.h"
-#include "llvm/System/DynamicLibrary.h"
-#include "llvm/System/Memory.h"
-#include "llvm/System/Mutex.h"
-#include "llvm/System/Path.h"
-#include "llvm/System/Process.h"
-#include "llvm/System/Program.h"
-#include "llvm/System/Signals.h"
-#include "llvm/System/TimeValue.h"
+#include "llvm/Support/Alarm.h"
+#include "llvm/Support/DynamicLibrary.h"
+#include "llvm/Support/Memory.h"
+#include "llvm/Support/Mutex.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Process.h"
+#include "llvm/Support/Program.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/TimeValue.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/MathExtras.h"
#include <cstdlib>
#ifndef EDINSTINFO_H
#define EDINSTINFO_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
#include "llvm/Support/Casting.h"
#include "llvm/MC/MCFixup.h"
#include "llvm/MC/MCInst.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <vector> // FIXME: Shouldn't be needed.
namespace llvm {
#ifndef MCDISASSEMBLER_H
#define MCDISASSEMBLER_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
#define LLVM_MC_MCEXPR_H
#include "llvm/Support/Casting.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
class MCAsmInfo;
#ifndef LLVM_MC_MCFIXUP_H
#define LLVM_MC_MCFIXUP_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <cassert>
namespace llvm {
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
class raw_ostream;
#include "llvm/ADT/Triple.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <cassert>
namespace llvm {
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <string>
#include <cassert>
#define LLVM_MC_MCASMLEXER_H
#include "llvm/ADT/StringRef.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/Support/SMLoc.h"
namespace llvm {
#ifndef LLVM_MC_MCASMPARSER_H
#define LLVM_MC_MCASMPARSER_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
class AsmToken;
#ifndef LLVM_MC_MCSTREAMER_H
#define LLVM_MC_MCSTREAMER_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/MC/MCDirectives.h"
namespace llvm {
#ifndef LLVM_MC_MCVALUE_H
#define LLVM_MC_MCVALUE_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/MC/MCSymbol.h"
#include <cassert>
#include "llvm/GlobalAlias.h"
#include "llvm/Metadata.h"
#include "llvm/ADT/OwningPtr.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <vector>
namespace llvm {
#ifndef LLVM_OBJECT_MACHOFORMAT_H
#define LLVM_OBJECT_MACHOFORMAT_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
namespace object {
#define LLVM_OBJECT_OBJECT_FILE_H
#include "llvm/ADT/StringRef.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
#include "Pass.h"
#include "llvm/PassRegistry.h"
#include "llvm/InitializePasses.h"
-#include "llvm/System/Atomic.h"
+#include "llvm/Support/Atomic.h"
#include <vector>
namespace llvm {
--- /dev/null
+//===-- llvm/System/AIXDataTypesFix.h - Fix datatype defs ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file overrides default system-defined types and limits which cannot be
+// done in DataTypes.h.in because it is processed by autoheader first, which
+// comments out any #undef statement
+//
+//===----------------------------------------------------------------------===//
+
+// No include guards desired!
+
+#ifndef SUPPORT_DATATYPES_H
+#error "AIXDataTypesFix.h must only be included via DataTypes.h!"
+#endif
+
+// GCC is strict about defining large constants: they must have LL modifier.
+// These will be defined properly at the end of DataTypes.h
+#undef INT64_MAX
+#undef INT64_MIN
--- /dev/null
+//===- llvm/System/Alarm.h - Alarm Generation support ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides an operating system independent interface to alarm(2)
+// type functionality. The Alarm class allows a one-shot alarm to be set up
+// at some number of seconds in the future. When the alarm triggers, a method
+// is called to process the event
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_ALARM_H
+#define LLVM_SYSTEM_ALARM_H
+
+namespace llvm {
+namespace sys {
+
+ /// This function registers an alarm to trigger some number of \p seconds in
+ /// the future. When that time arrives, the AlarmStatus function will begin
+ /// to return 1 instead of 0. The user must poll the status of the alarm by
+ /// making occasional calls to AlarmStatus. If the user sends an interrupt
+ /// signal, AlarmStatus will begin returning -1, even if the alarm event
+ /// occurred.
+ /// @returns nothing
+ void SetupAlarm(
+ unsigned seconds ///< Number of seconds in future when alarm arrives
+ );
+
+ /// This function terminates the alarm previously set up
+ /// @returns nothing
+ void TerminateAlarm();
+
+ /// This function acquires the status of the alarm.
+ /// @returns -1=cancelled, 0=untriggered, 1=triggered
+ int AlarmStatus();
+
+ /// Sleep for n seconds. Warning: mixing calls to Sleep() and other *Alarm
+ /// calls may be a bad idea on some platforms (source: Linux man page).
+ /// @returns nothing.
+ void Sleep(unsigned n);
+
+
+} // End sys namespace
+} // End llvm namespace
+
+#endif
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/MathExtras.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <algorithm>
#include <cassert>
#include <cstdlib>
--- /dev/null
+//===- llvm/System/Atomic.h - Atomic Operations -----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the llvm::sys atomic operations.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_ATOMIC_H
+#define LLVM_SYSTEM_ATOMIC_H
+
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+ namespace sys {
+ void MemoryFence();
+
+#ifdef _MSC_VER
+ typedef long cas_flag;
+#else
+ typedef uint32_t cas_flag;
+#endif
+ cas_flag CompareAndSwap(volatile cas_flag* ptr,
+ cas_flag new_value,
+ cas_flag old_value);
+ cas_flag AtomicIncrement(volatile cas_flag* ptr);
+ cas_flag AtomicDecrement(volatile cas_flag* ptr);
+ cas_flag AtomicAdd(volatile cas_flag* ptr, cas_flag val);
+ cas_flag AtomicMul(volatile cas_flag* ptr, cas_flag val);
+ cas_flag AtomicDiv(volatile cas_flag* ptr, cas_flag val);
+ }
+}
+
+#endif
#ifndef LLVM_SUPPORT_WIN_COFF_H
#define LLVM_SUPPORT_WIN_COFF_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <cstring>
namespace llvm {
#define LLVM_SUPPORT_CONSTANT_RANGE_H
#include "llvm/ADT/APInt.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
--- /dev/null
+/*===-- include/Support/DataTypes.h - Define fixed size types -----*- C -*-===*\
+|* *|
+|* The LLVM Compiler Infrastructure *|
+|* *|
+|* This file is distributed under the University of Illinois Open Source *|
+|* License. See LICENSE.TXT for details. *|
+|* *|
+|*===----------------------------------------------------------------------===*|
+|* *|
+|* This file contains definitions to figure out the size of _HOST_ data types.*|
+|* This file is important because different host OS's define different macros,*|
+|* which makes portability tough. This file exports the following *|
+|* definitions: *|
+|* *|
+|* [u]int(32|64)_t : typedefs for signed and unsigned 32/64 bit system types*|
+|* [U]INT(8|16|32|64)_(MIN|MAX) : Constants for the min and max values. *|
+|* *|
+|* No library is required when using these functinons. *|
+|* *|
+|*===----------------------------------------------------------------------===*/
+
+/* Please leave this file C-compatible. */
+
+#ifndef SUPPORT_DATATYPES_H
+#define SUPPORT_DATATYPES_H
+
+#cmakedefine HAVE_SYS_TYPES_H ${HAVE_SYS_TYPES_H}
+#cmakedefine HAVE_INTTYPES_H ${HAVE_INTTYPES_H}
+#cmakedefine HAVE_STDINT_H ${HAVE_STDINT_H}
+#cmakedefine HAVE_UINT64_T ${HAVE_UINT64_T}
+#cmakedefine HAVE_U_INT64_T ${HAVE_U_INT64_T}
+
+#ifdef __cplusplus
+#include <cmath>
+#else
+#include <math.h>
+#endif
+
+#ifndef _MSC_VER
+
+/* Note that this header's correct operation depends on __STDC_LIMIT_MACROS
+ being defined. We would define it here, but in order to prevent Bad Things
+ happening when system headers or C++ STL headers include stdint.h before we
+ define it here, we define it on the g++ command line (in Makefile.rules). */
+#if !defined(__STDC_LIMIT_MACROS)
+# error "Must #define __STDC_LIMIT_MACROS before #including Support/DataTypes.h"
+#endif
+
+#if !defined(__STDC_CONSTANT_MACROS)
+# error "Must #define __STDC_CONSTANT_MACROS before " \
+ "#including Support/DataTypes.h"
+#endif
+
+/* Note that <inttypes.h> includes <stdint.h>, if this is a C99 system. */
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#ifdef _AIX
+#include "llvm/Support/AIXDataTypesFix.h"
+#endif
+
+/* Handle incorrect definition of uint64_t as u_int64_t */
+#ifndef HAVE_UINT64_T
+#ifdef HAVE_U_INT64_T
+typedef u_int64_t uint64_t;
+#else
+# error "Don't have a definition for uint64_t on this platform"
+#endif
+#endif
+
+#ifdef _OpenBSD_
+#define INT8_MAX 127
+#define INT8_MIN -128
+#define UINT8_MAX 255
+#define INT16_MAX 32767
+#define INT16_MIN -32768
+#define UINT16_MAX 65535
+#define INT32_MAX 2147483647
+#define INT32_MIN -2147483648
+#define UINT32_MAX 4294967295U
+#endif
+
+#else /* _MSC_VER */
+/* Visual C++ doesn't provide standard integer headers, but it does provide
+ built-in data types. */
+#include <stdlib.h>
+#include <stddef.h>
+#include <sys/types.h>
+#ifdef __cplusplus
+#include <cmath>
+#else
+#include <math.h>
+#endif
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+typedef signed int int32_t;
+typedef unsigned int uint32_t;
+typedef short int16_t;
+typedef unsigned short uint16_t;
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+typedef signed int ssize_t;
+#ifndef INT8_MAX
+# define INT8_MAX 127
+#endif
+#ifndef INT8_MIN
+# define INT8_MIN -128
+#endif
+#ifndef UINT8_MAX
+# define UINT8_MAX 255
+#endif
+#ifndef INT16_MAX
+# define INT16_MAX 32767
+#endif
+#ifndef INT16_MIN
+# define INT16_MIN -32768
+#endif
+#ifndef UINT16_MAX
+# define UINT16_MAX 65535
+#endif
+#ifndef INT32_MAX
+# define INT32_MAX 2147483647
+#endif
+#ifndef INT32_MIN
+# define INT32_MIN -2147483648
+#endif
+#ifndef UINT32_MAX
+# define UINT32_MAX 4294967295U
+#endif
+/* Certain compatibility updates to VC++ introduce the `cstdint'
+ * header, which defines the INT*_C macros. On default installs they
+ * are absent. */
+#ifndef INT8_C
+# define INT8_C(C) C##i8
+#endif
+#ifndef UINT8_C
+# define UINT8_C(C) C##ui8
+#endif
+#ifndef INT16_C
+# define INT16_C(C) C##i16
+#endif
+#ifndef UINT16_C
+# define UINT16_C(C) C##ui16
+#endif
+#ifndef INT32_C
+# define INT32_C(C) C##i32
+#endif
+#ifndef UINT32_C
+# define UINT32_C(C) C##ui32
+#endif
+#ifndef INT64_C
+# define INT64_C(C) C##i64
+#endif
+#ifndef UINT64_C
+# define UINT64_C(C) C##ui64
+#endif
+#endif /* _MSC_VER */
+
+/* Set defaults for constants which we cannot find. */
+#if !defined(INT64_MAX)
+# define INT64_MAX 9223372036854775807LL
+#endif
+#if !defined(INT64_MIN)
+# define INT64_MIN ((-INT64_MAX)-1)
+#endif
+#if !defined(UINT64_MAX)
+# define UINT64_MAX 0xffffffffffffffffULL
+#endif
+
+#if __GNUC__ > 3
+#define END_WITH_NULL __attribute__((sentinel))
+#else
+#define END_WITH_NULL
+#endif
+
+#ifndef HUGE_VALF
+#define HUGE_VALF (float)HUGE_VAL
+#endif
+
+#endif /* SUPPORT_DATATYPES_H */
--- /dev/null
+/*===-- include/System/DataTypes.h - Define fixed size types -----*- C -*-===*\
+|* *|
+|* The LLVM Compiler Infrastructure *|
+|* *|
+|* This file is distributed under the University of Illinois Open Source *|
+|* License. See LICENSE.TXT for details. *|
+|* *|
+|*===----------------------------------------------------------------------===*|
+|* *|
+|* This file contains definitions to figure out the size of _HOST_ data types.*|
+|* This file is important because different host OS's define different macros,*|
+|* which makes portability tough. This file exports the following *|
+|* definitions: *|
+|* *|
+|* [u]int(32|64)_t : typedefs for signed and unsigned 32/64 bit system types*|
+|* [U]INT(8|16|32|64)_(MIN|MAX) : Constants for the min and max values. *|
+|* *|
+|* No library is required when using these functions. *|
+|* *|
+|*===----------------------------------------------------------------------===*/
+
+/* Please leave this file C-compatible. */
+
+#ifndef SUPPORT_DATATYPES_H
+#define SUPPORT_DATATYPES_H
+
+#undef HAVE_SYS_TYPES_H
+#undef HAVE_INTTYPES_H
+#undef HAVE_STDINT_H
+#undef HAVE_UINT64_T
+#undef HAVE_U_INT64_T
+
+#ifdef __cplusplus
+#include <cmath>
+#else
+#include <math.h>
+#endif
+
+/* Note that this header's correct operation depends on __STDC_LIMIT_MACROS
+ being defined. We would define it here, but in order to prevent Bad Things
+ happening when system headers or C++ STL headers include stdint.h before we
+ define it here, we define it on the g++ command line (in Makefile.rules). */
+#if !defined(__STDC_LIMIT_MACROS)
+# error "Must #define __STDC_LIMIT_MACROS before #including System/DataTypes.h"
+#endif
+
+#if !defined(__STDC_CONSTANT_MACROS)
+# error "Must #define __STDC_CONSTANT_MACROS before " \
+ "#including System/DataTypes.h"
+#endif
+
+/* Note that <inttypes.h> includes <stdint.h>, if this is a C99 system. */
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#ifdef _AIX
+#include "llvm/System/AIXDataTypesFix.h"
+#endif
+
+/* Handle incorrect definition of uint64_t as u_int64_t */
+#ifndef HAVE_UINT64_T
+#ifdef HAVE_U_INT64_T
+typedef u_int64_t uint64_t;
+#else
+# error "Don't have a definition for uint64_t on this platform"
+#endif
+#endif
+
+#ifdef _OpenBSD_
+#define INT8_MAX 127
+#define INT8_MIN -128
+#define UINT8_MAX 255
+#define INT16_MAX 32767
+#define INT16_MIN -32768
+#define UINT16_MAX 65535
+#define INT32_MAX 2147483647
+#define INT32_MIN -2147483648
+#define UINT32_MAX 4294967295U
+#endif
+
+/* Set defaults for constants which we cannot find. */
+#if !defined(INT64_MAX)
+# define INT64_MAX 9223372036854775807LL
+#endif
+#if !defined(INT64_MIN)
+# define INT64_MIN ((-INT64_MAX)-1)
+#endif
+#if !defined(UINT64_MAX)
+# define UINT64_MAX 0xffffffffffffffffULL
+#endif
+
+#if __GNUC__ > 3
+#define END_WITH_NULL __attribute__((sentinel))
+#else
+#define END_WITH_NULL
+#endif
+
+#ifndef HUGE_VALF
+#define HUGE_VALF (float)HUGE_VAL
+#endif
+
+#endif /* SUPPORT_DATATYPES_H */
--- /dev/null
+//===- llvm/Support/Disassembler.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 implements the necessary glue to call external disassembler
+// libraries.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_DISASSEMBLER_H
+#define LLVM_SYSTEM_DISASSEMBLER_H
+
+#include "llvm/Support/DataTypes.h"
+#include <string>
+
+namespace llvm {
+namespace sys {
+
+/// This function returns true, if there is possible to use some external
+/// disassembler library. False otherwise.
+bool hasDisassembler();
+
+/// This function provides some "glue" code to call external disassembler
+/// libraries.
+std::string disassembleBuffer(uint8_t* start, size_t length, uint64_t pc = 0);
+
+}
+}
+
+#endif // LLVM_SYSTEM_DISASSEMBLER_H
--- /dev/null
+//===-- llvm/System/DynamicLibrary.h - Portable Dynamic Library -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the sys::DynamicLibrary class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_DYNAMIC_LIBRARY_H
+#define LLVM_SYSTEM_DYNAMIC_LIBRARY_H
+
+#include <string>
+
+namespace llvm {
+namespace sys {
+
+ /// This class provides a portable interface to dynamic libraries which also
+ /// might be known as shared libraries, shared objects, dynamic shared
+ /// objects, or dynamic link libraries. Regardless of the terminology or the
+ /// operating system interface, this class provides a portable interface that
+ /// allows dynamic libraries to be loaded and searched for externally
+ /// defined symbols. This is typically used to provide "plug-in" support.
+ /// It also allows for symbols to be defined which don't live in any library,
+ /// but rather the main program itself, useful on Windows where the main
+ /// executable cannot be searched.
+ class DynamicLibrary {
+ DynamicLibrary(); // DO NOT IMPLEMENT
+ public:
+ /// This function allows a library to be loaded without instantiating a
+ /// DynamicLibrary object. Consequently, it is marked as being permanent
+ /// and will only be unloaded when the program terminates. This returns
+ /// false on success or returns true and fills in *ErrMsg on failure.
+ /// @brief Open a dynamic library permanently.
+ ///
+ /// NOTE: This function is not thread safe.
+ ///
+ static bool LoadLibraryPermanently(const char *filename,
+ std::string *ErrMsg = 0);
+
+ /// This function will search through all previously loaded dynamic
+ /// libraries for the symbol \p symbolName. If it is found, the addressof
+ /// that symbol is returned. If not, null is returned. Note that this will
+ /// search permanently loaded libraries (LoadLibraryPermanently) as well
+ /// as ephemerally loaded libraries (constructors).
+ /// @throws std::string on error.
+ /// @brief Search through libraries for address of a symbol
+ ///
+ /// NOTE: This function is not thread safe.
+ ///
+ static void *SearchForAddressOfSymbol(const char *symbolName);
+
+ /// @brief Convenience function for C++ophiles.
+ ///
+ /// NOTE: This function is not thread safe.
+ ///
+ static void *SearchForAddressOfSymbol(const std::string &symbolName) {
+ return SearchForAddressOfSymbol(symbolName.c_str());
+ }
+
+ /// This functions permanently adds the symbol \p symbolName with the
+ /// value \p symbolValue. These symbols are searched before any
+ /// libraries.
+ /// @brief Add searchable symbol/value pair.
+ ///
+ /// NOTE: This function is not thread safe.
+ ///
+ static void AddSymbol(const char *symbolName, void *symbolValue);
+
+ /// @brief Convenience function for C++ophiles.
+ ///
+ /// NOTE: This function is not thread safe.
+ ///
+ static void AddSymbol(const std::string &symbolName, void *symbolValue) {
+ AddSymbol(symbolName.c_str(), symbolValue);
+ }
+ };
+
+} // End sys namespace
+} // End llvm namespace
+
+#endif // LLVM_SYSTEM_DYNAMIC_LIBRARY_H
#ifndef LLVM_SUPPORT_ELF_H
#define LLVM_SUPPORT_ELF_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <cstring>
namespace llvm {
#define LLVM_SUPPORT_ENDIAN_H
#include "llvm/Config/config.h"
-#include "llvm/System/Host.h"
-#include "llvm/System/SwapByteOrder.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/SwapByteOrder.h"
#include "llvm/Support/type_traits.h"
namespace llvm {
--- /dev/null
+//===- llvm/System/Errno.h - Portable+convenient errno handling -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares some portable and convenient functions to deal with errno.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_ERRNO_H
+#define LLVM_SYSTEM_ERRNO_H
+
+#include <string>
+
+namespace llvm {
+namespace sys {
+
+/// Returns a string representation of the errno value, using whatever
+/// thread-safe variant of strerror() is available. Be sure to call this
+/// immediately after the function that set errno, or errno may have been
+/// overwritten by an intervening call.
+std::string StrError();
+
+/// Like the no-argument version above, but uses \p errnum instead of errno.
+std::string StrError(int errnum);
+
+} // namespace sys
+} // namespace llvm
+
+#endif // LLVM_SYSTEM_ERRNO_H
--- /dev/null
+//===- llvm/System/FEnv.h - Host floating-point exceptions ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides an operating system independent interface to
+// floating-point exception interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_FENV_H
+#define LLVM_SYSTEM_FENV_H
+
+#include "llvm/Config/config.h"
+#include <cerrno>
+#ifdef HAVE_FENV_H
+#include <fenv.h>
+#endif
+
+// FIXME: Clang's #include handling apparently doesn't work for libstdc++'s
+// fenv.h; see PR6907 for details.
+#if defined(__clang__) && defined(_GLIBCXX_FENV_H)
+#undef HAVE_FENV_H
+#endif
+
+namespace llvm {
+namespace sys {
+
+/// llvm_fenv_clearexcept - Clear the floating-point exception state.
+static inline void llvm_fenv_clearexcept() {
+#ifdef HAVE_FENV_H
+ feclearexcept(FE_ALL_EXCEPT);
+#endif
+ errno = 0;
+}
+
+/// llvm_fenv_testexcept - Test if a floating-point exception was raised.
+static inline bool llvm_fenv_testexcept() {
+ int errno_val = errno;
+ if (errno_val == ERANGE || errno_val == EDOM)
+ return true;
+#ifdef HAVE_FENV_H
+ if (fetestexcept(FE_ALL_EXCEPT & ~FE_INEXACT))
+ return true;
+#endif
+ return false;
+}
+
+} // End sys namespace
+} // End llvm namespace
+
+#endif
#ifndef LLVM_SUPPORT_FILEUTILITIES_H
#define LLVM_SUPPORT_FILEUTILITIES_H
-#include "llvm/System/Path.h"
+#include "llvm/Support/Path.h"
namespace llvm {
#include "llvm/Support/DOTGraphTraits.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/GraphTraits.h"
-#include "llvm/System/Path.h"
+#include "llvm/Support/Path.h"
#include <vector>
#include <cassert>
--- /dev/null
+//===- llvm/System/Host.h - Host machine characteristics --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Methods for querying the nature of the host machine.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_HOST_H
+#define LLVM_SYSTEM_HOST_H
+
+#include "llvm/ADT/StringMap.h"
+#include <string>
+
+namespace llvm {
+namespace sys {
+
+ inline bool isLittleEndianHost() {
+ union {
+ int i;
+ char c;
+ };
+ i = 1;
+ return c;
+ }
+
+ inline bool isBigEndianHost() {
+ return !isLittleEndianHost();
+ }
+
+ /// getHostTriple() - Return the target triple of the running
+ /// system.
+ ///
+ /// The target triple is a string in the format of:
+ /// CPU_TYPE-VENDOR-OPERATING_SYSTEM
+ /// or
+ /// CPU_TYPE-VENDOR-KERNEL-OPERATING_SYSTEM
+ std::string getHostTriple();
+
+ /// getHostCPUName - Get the LLVM name for the host CPU. The particular format
+ /// of the name is target dependent, and suitable for passing as -mcpu to the
+ /// target which matches the host.
+ ///
+ /// \return - The host CPU name, or empty if the CPU could not be determined.
+ std::string getHostCPUName();
+
+ /// getHostCPUFeatures - Get the LLVM names for the host CPU features.
+ /// The particular format of the names are target dependent, and suitable for
+ /// passing as -mattr to the target which matches the host.
+ ///
+ /// \param Features - A string mapping feature names to either
+ /// true (if enabled) or false (if disabled). This routine makes no guarantees
+ /// about exactly which features may appear in this map, except that they are
+ /// all valid LLVM feature names.
+ ///
+ /// \return - True on success.
+ bool getHostCPUFeatures(StringMap<bool> &Features);
+}
+}
+
+#endif
--- /dev/null
+//===- llvm/System/IncludeFile.h - Ensure Linking Of Library ---*- 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 FORCE_DEFINING_FILE_TO_BE_LINKED and DEFINE_FILE_FOR
+// macros.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_INCLUDEFILE_H
+#define LLVM_SYSTEM_INCLUDEFILE_H
+
+/// This macro is the public interface that IncludeFile.h exports. This gives
+/// us the option to implement the "link the definition" capability in any
+/// manner that we choose. All header files that depend on a specific .cpp
+/// file being linked at run time should use this macro instead of the
+/// IncludeFile class directly.
+///
+/// For example, foo.h would use:<br/>
+/// <tt>FORCE_DEFINING_FILE_TO_BE_LINKED(foo)</tt><br/>
+///
+/// And, foo.cp would use:<br/>
+/// <tt>DEFINING_FILE_FOR(foo)</tt><br/>
+#ifdef __GNUC__
+// If the `used' attribute is available, use it to create a variable
+// with an initializer that will force the linking of the defining file.
+#define FORCE_DEFINING_FILE_TO_BE_LINKED(name) \
+ namespace llvm { \
+ extern const char name ## LinkVar; \
+ __attribute__((used)) static const char *const name ## LinkObj = \
+ &name ## LinkVar; \
+ }
+#else
+// Otherwise use a constructor call.
+#define FORCE_DEFINING_FILE_TO_BE_LINKED(name) \
+ namespace llvm { \
+ extern const char name ## LinkVar; \
+ static const IncludeFile name ## LinkObj ( &name ## LinkVar ); \
+ }
+#endif
+
+/// This macro is the counterpart to FORCE_DEFINING_FILE_TO_BE_LINKED. It should
+/// be used in a .cpp file to define the name referenced in a header file that
+/// will cause linkage of the .cpp file. It should only be used at extern level.
+#define DEFINING_FILE_FOR(name) \
+ namespace llvm { const char name ## LinkVar = 0; }
+
+namespace llvm {
+
+/// This class is used in the implementation of FORCE_DEFINING_FILE_TO_BE_LINKED
+/// macro to make sure that the implementation of a header file is included
+/// into a tool that uses the header. This is solely
+/// to overcome problems linking .a files and not getting the implementation
+/// of compilation units we need. This is commonly an issue with the various
+/// Passes but also occurs elsewhere in LLVM. We like to use .a files because
+/// they link faster and provide the smallest executables. However, sometimes
+/// those executables are too small, if the program doesn't reference something
+/// that might be needed, especially by a loaded share object. This little class
+/// helps to resolve that problem. The basic strategy is to use this class in
+/// a header file and pass the address of a variable to the constructor. If the
+/// variable is defined in the header file's corresponding .cpp file then all
+/// tools/libraries that \#include the header file will require the .cpp as
+/// well.
+/// For example:<br/>
+/// <tt>extern int LinkMyCodeStub;</tt><br/>
+/// <tt>static IncludeFile LinkMyModule(&LinkMyCodeStub);</tt><br/>
+/// @brief Class to ensure linking of corresponding object file.
+struct IncludeFile {
+ explicit IncludeFile(const void *);
+};
+
+}
+
+#endif
--- /dev/null
+LLVM System Interface Library
+-------------------------------------------------------------------------------
+The LLVM System Interface Library is licensed under the Illinois Open Source
+License and has the following additional copyright:
+
+Copyright (C) 2004 eXtensible Systems, Inc.
#ifndef LLVM_SUPPORT_MACHO_H
#define LLVM_SUPPORT_MACHO_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
// NOTE: The enums in this file are intentially named to be different than those
// in the headers in /usr/include/mach (on darwin systems) to avoid conflicts
#ifndef LLVM_SUPPORT_MANAGED_STATIC_H
#define LLVM_SUPPORT_MANAGED_STATIC_H
-#include "llvm/System/Atomic.h"
-#include "llvm/System/Threading.h"
+#include "llvm/Support/Atomic.h"
+#include "llvm/Support/Threading.h"
namespace llvm {
#ifndef LLVM_SUPPORT_MATHEXTRAS_H
#define LLVM_SUPPORT_MATHEXTRAS_H
-#include "llvm/System/SwapByteOrder.h"
+#include "llvm/Support/SwapByteOrder.h"
namespace llvm {
--- /dev/null
+//===- llvm/System/Memory.h - Memory Support --------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the llvm::sys::Memory class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_MEMORY_H
+#define LLVM_SYSTEM_MEMORY_H
+
+#include "llvm/Support/DataTypes.h"
+#include <string>
+
+namespace llvm {
+namespace sys {
+
+ /// This class encapsulates the notion of a memory block which has an address
+ /// and a size. It is used by the Memory class (a friend) as the result of
+ /// various memory allocation operations.
+ /// @see Memory
+ /// @brief Memory block abstraction.
+ class MemoryBlock {
+ public:
+ MemoryBlock() : Address(0), Size(0) { }
+ MemoryBlock(void *addr, size_t size) : Address(addr), Size(size) { }
+ void *base() const { return Address; }
+ size_t size() const { return Size; }
+ private:
+ void *Address; ///< Address of first byte of memory area
+ size_t Size; ///< Size, in bytes of the memory area
+ friend class Memory;
+ };
+
+ /// This class provides various memory handling functions that manipulate
+ /// MemoryBlock instances.
+ /// @since 1.4
+ /// @brief An abstraction for memory operations.
+ class Memory {
+ public:
+ /// This method allocates a block of Read/Write/Execute memory that is
+ /// suitable for executing dynamically generated code (e.g. JIT). An
+ /// attempt to allocate \p NumBytes bytes of virtual memory is made.
+ /// \p NearBlock may point to an existing allocation in which case
+ /// an attempt is made to allocate more memory near the existing block.
+ ///
+ /// On success, this returns a non-null memory block, otherwise it returns
+ /// a null memory block and fills in *ErrMsg.
+ ///
+ /// @brief Allocate Read/Write/Execute memory.
+ static MemoryBlock AllocateRWX(size_t NumBytes,
+ const MemoryBlock *NearBlock,
+ std::string *ErrMsg = 0);
+
+ /// This method releases a block of Read/Write/Execute memory that was
+ /// allocated with the AllocateRWX method. It should not be used to
+ /// release any memory block allocated any other way.
+ ///
+ /// On success, this returns false, otherwise it returns true and fills
+ /// in *ErrMsg.
+ /// @brief Release Read/Write/Execute memory.
+ static bool ReleaseRWX(MemoryBlock &block, std::string *ErrMsg = 0);
+
+
+ /// InvalidateInstructionCache - Before the JIT can run a block of code
+ /// that has been emitted it must invalidate the instruction cache on some
+ /// platforms.
+ static void InvalidateInstructionCache(const void *Addr, size_t Len);
+
+ /// setExecutable - Before the JIT can run a block of code, it has to be
+ /// given read and executable privilege. Return true if it is already r-x
+ /// or the system is able to change its previlege.
+ static bool setExecutable (MemoryBlock &M, std::string *ErrMsg = 0);
+
+ /// setWritable - When adding to a block of code, the JIT may need
+ /// to mark a block of code as RW since the protections are on page
+ /// boundaries, and the JIT internal allocations are not page aligned.
+ static bool setWritable (MemoryBlock &M, std::string *ErrMsg = 0);
+
+ /// setRangeExecutable - Mark the page containing a range of addresses
+ /// as executable.
+ static bool setRangeExecutable(const void *Addr, size_t Size);
+
+ /// setRangeWritable - Mark the page containing a range of addresses
+ /// as writable.
+ static bool setRangeWritable(const void *Addr, size_t Size);
+ };
+}
+}
+
+#endif
#define LLVM_SUPPORT_MEMORYBUFFER_H
#include "llvm/ADT/StringRef.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <string>
namespace llvm {
#ifndef MEMORYOBJECT_H
#define MEMORYOBJECT_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
--- /dev/null
+//===- llvm/System/Mutex.h - Mutex Operating System Concept -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the llvm::sys::Mutex class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_MUTEX_H
+#define LLVM_SYSTEM_MUTEX_H
+
+#include "llvm/Support/Threading.h"
+#include <cassert>
+
+namespace llvm
+{
+ namespace sys
+ {
+ /// @brief Platform agnostic Mutex class.
+ class MutexImpl
+ {
+ /// @name Constructors
+ /// @{
+ public:
+
+ /// Initializes the lock but doesn't acquire it. if \p recursive is set
+ /// to false, the lock will not be recursive which makes it cheaper but
+ /// also more likely to deadlock (same thread can't acquire more than
+ /// once).
+ /// @brief Default Constructor.
+ explicit MutexImpl(bool recursive = true);
+
+ /// Releases and removes the lock
+ /// @brief Destructor
+ ~MutexImpl();
+
+ /// @}
+ /// @name Methods
+ /// @{
+ public:
+
+ /// Attempts to unconditionally acquire the lock. If the lock is held by
+ /// another thread, this method will wait until it can acquire the lock.
+ /// @returns false if any kind of error occurs, true otherwise.
+ /// @brief Unconditionally acquire the lock.
+ bool acquire();
+
+ /// Attempts to release the lock. If the lock is held by the current
+ /// thread, the lock is released allowing other threads to acquire the
+ /// lock.
+ /// @returns false if any kind of error occurs, true otherwise.
+ /// @brief Unconditionally release the lock.
+ bool release();
+
+ /// Attempts to acquire the lock without blocking. If the lock is not
+ /// available, this function returns false quickly (without blocking). If
+ /// the lock is available, it is acquired.
+ /// @returns false if any kind of error occurs or the lock is not
+ /// available, true otherwise.
+ /// @brief Try to acquire the lock.
+ bool tryacquire();
+
+ //@}
+ /// @name Platform Dependent Data
+ /// @{
+ private:
+ void* data_; ///< We don't know what the data will be
+
+ /// @}
+ /// @name Do Not Implement
+ /// @{
+ private:
+ MutexImpl(const MutexImpl & original);
+ void operator=(const MutexImpl &);
+ /// @}
+ };
+
+
+ /// SmartMutex - A mutex with a compile time constant parameter that
+ /// indicates whether this mutex should become a no-op when we're not
+ /// running in multithreaded mode.
+ template<bool mt_only>
+ class SmartMutex : public MutexImpl {
+ unsigned acquired;
+ bool recursive;
+ public:
+ explicit SmartMutex(bool rec = true) :
+ MutexImpl(rec), acquired(0), recursive(rec) { }
+
+ bool acquire() {
+ if (!mt_only || llvm_is_multithreaded()) {
+ return MutexImpl::acquire();
+ } else {
+ // Single-threaded debugging code. This would be racy in
+ // multithreaded mode, but provides not sanity checks in single
+ // threaded mode.
+ assert((recursive || acquired == 0) && "Lock already acquired!!");
+ ++acquired;
+ return true;
+ }
+ }
+
+ bool release() {
+ if (!mt_only || llvm_is_multithreaded()) {
+ return MutexImpl::release();
+ } else {
+ // Single-threaded debugging code. This would be racy in
+ // multithreaded mode, but provides not sanity checks in single
+ // threaded mode.
+ assert(((recursive && acquired) || (acquired == 1)) &&
+ "Lock not acquired before release!");
+ --acquired;
+ return true;
+ }
+ }
+
+ bool tryacquire() {
+ if (!mt_only || llvm_is_multithreaded())
+ return MutexImpl::tryacquire();
+ else return true;
+ }
+
+ private:
+ SmartMutex(const SmartMutex<mt_only> & original);
+ void operator=(const SmartMutex<mt_only> &);
+ };
+
+ /// Mutex - A standard, always enforced mutex.
+ typedef SmartMutex<false> Mutex;
+
+ template<bool mt_only>
+ class SmartScopedLock {
+ SmartMutex<mt_only>& mtx;
+
+ public:
+ SmartScopedLock(SmartMutex<mt_only>& m) : mtx(m) {
+ mtx.acquire();
+ }
+
+ ~SmartScopedLock() {
+ mtx.release();
+ }
+ };
+
+ typedef SmartScopedLock<false> ScopedLock;
+ }
+}
+
+#endif
#ifndef LLVM_SUPPORT_MUTEXGUARD_H
#define LLVM_SUPPORT_MUTEXGUARD_H
-#include "llvm/System/Mutex.h"
+#include "llvm/Support/Mutex.h"
namespace llvm {
/// Instances of this class acquire a given Mutex Lock when constructed and
--- /dev/null
+//===- llvm/System/Path.h - Path Operating System Concept -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the llvm::sys::Path class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_PATH_H
+#define LLVM_SYSTEM_PATH_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/TimeValue.h"
+#include <set>
+#include <string>
+#include <vector>
+
+namespace llvm {
+namespace sys {
+
+ /// This structure provides basic file system information about a file. It
+ /// is patterned after the stat(2) Unix operating system call but made
+ /// platform independent and eliminates many of the unix-specific fields.
+ /// However, to support llvm-ar, the mode, user, and group fields are
+ /// retained. These pertain to unix security and may not have a meaningful
+ /// value on non-Unix platforms. However, the other fields should
+ /// always be applicable on all platforms. The structure is filled in by
+ /// the PathWithStatus class.
+ /// @brief File status structure
+ class FileStatus {
+ public:
+ uint64_t fileSize; ///< Size of the file in bytes
+ TimeValue modTime; ///< Time of file's modification
+ uint32_t mode; ///< Mode of the file, if applicable
+ uint32_t user; ///< User ID of owner, if applicable
+ uint32_t group; ///< Group ID of owner, if applicable
+ uint64_t uniqueID; ///< A number to uniquely ID this file
+ bool isDir : 1; ///< True if this is a directory.
+ bool isFile : 1; ///< True if this is a file.
+
+ FileStatus() : fileSize(0), modTime(0,0), mode(0777), user(999),
+ group(999), uniqueID(0), isDir(false), isFile(false) { }
+
+ TimeValue getTimestamp() const { return modTime; }
+ uint64_t getSize() const { return fileSize; }
+ uint32_t getMode() const { return mode; }
+ uint32_t getUser() const { return user; }
+ uint32_t getGroup() const { return group; }
+ uint64_t getUniqueID() const { return uniqueID; }
+ };
+
+ /// This class provides an abstraction for the path to a file or directory
+ /// in the operating system's filesystem and provides various basic operations
+ /// on it. Note that this class only represents the name of a path to a file
+ /// or directory which may or may not be valid for a given machine's file
+ /// system. The class is patterned after the java.io.File class with various
+ /// extensions and several omissions (not relevant to LLVM). A Path object
+ /// ensures that the path it encapsulates is syntactically valid for the
+ /// operating system it is running on but does not ensure correctness for
+ /// any particular file system. That is, a syntactically valid path might
+ /// specify path components that do not exist in the file system and using
+ /// such a Path to act on the file system could produce errors. There is one
+ /// invalid Path value which is permitted: the empty path. The class should
+ /// never allow a syntactically invalid non-empty path name to be assigned.
+ /// Empty paths are required in order to indicate an error result in some
+ /// situations. If the path is empty, the isValid operation will return
+ /// false. All operations will fail if isValid is false. Operations that
+ /// change the path will either return false if it would cause a syntactically
+ /// invalid path name (in which case the Path object is left unchanged) or
+ /// throw an std::string exception indicating the error. The methods are
+ /// grouped into four basic categories: Path Accessors (provide information
+ /// about the path without accessing disk), Disk Accessors (provide
+ /// information about the underlying file or directory), Path Mutators
+ /// (change the path information, not the disk), and Disk Mutators (change
+ /// the disk file/directory referenced by the path). The Disk Mutator methods
+ /// all have the word "disk" embedded in their method name to reinforce the
+ /// notion that the operation modifies the file system.
+ /// @since 1.4
+ /// @brief An abstraction for operating system paths.
+ class Path {
+ /// @name Constructors
+ /// @{
+ public:
+ /// Construct a path to the root directory of the file system. The root
+ /// directory is a top level directory above which there are no more
+ /// directories. For example, on UNIX, the root directory is /. On Windows
+ /// it is file:///. Other operating systems may have different notions of
+ /// what the root directory is or none at all. In that case, a consistent
+ /// default root directory will be used.
+ static Path GetRootDirectory();
+
+ /// Construct a path to a unique temporary directory that is created in
+ /// a "standard" place for the operating system. The directory is
+ /// guaranteed to be created on exit from this function. If the directory
+ /// cannot be created, the function will throw an exception.
+ /// @returns an invalid path (empty) on error
+ /// @param ErrMsg Optional place for an error message if an error occurs
+ /// @brief Constrct a path to an new, unique, existing temporary
+ /// directory.
+ static Path GetTemporaryDirectory(std::string* ErrMsg = 0);
+
+ /// Construct a vector of sys::Path that contains the "standard" system
+ /// library paths suitable for linking into programs.
+ /// @brief Construct a path to the system library directory
+ static void GetSystemLibraryPaths(std::vector<sys::Path>& Paths);
+
+ /// Construct a vector of sys::Path that contains the "standard" bitcode
+ /// library paths suitable for linking into an llvm program. This function
+ /// *must* return the value of LLVM_LIB_SEARCH_PATH as well as the value
+ /// of LLVM_LIBDIR. It also must provide the System library paths as
+ /// returned by GetSystemLibraryPaths.
+ /// @see GetSystemLibraryPaths
+ /// @brief Construct a list of directories in which bitcode could be
+ /// found.
+ static void GetBitcodeLibraryPaths(std::vector<sys::Path>& Paths);
+
+ /// Find the path to a library using its short name. Use the system
+ /// dependent library paths to locate the library.
+ /// @brief Find a library.
+ static Path FindLibrary(std::string& short_name);
+
+ /// Construct a path to the default LLVM configuration directory. The
+ /// implementation must ensure that this is a well-known (same on many
+ /// systems) directory in which llvm configuration files exist. For
+ /// example, on Unix, the /etc/llvm directory has been selected.
+ /// @brief Construct a path to the default LLVM configuration directory
+ static Path GetLLVMDefaultConfigDir();
+
+ /// Construct a path to the LLVM installed configuration directory. The
+ /// implementation must ensure that this refers to the "etc" directory of
+ /// the LLVM installation. This is the location where configuration files
+ /// will be located for a particular installation of LLVM on a machine.
+ /// @brief Construct a path to the LLVM installed configuration directory
+ static Path GetLLVMConfigDir();
+
+ /// Construct a path to the current user's home directory. The
+ /// implementation must use an operating system specific mechanism for
+ /// determining the user's home directory. For example, the environment
+ /// variable "HOME" could be used on Unix. If a given operating system
+ /// does not have the concept of a user's home directory, this static
+ /// constructor must provide the same result as GetRootDirectory.
+ /// @brief Construct a path to the current user's "home" directory
+ static Path GetUserHomeDirectory();
+
+ /// Construct a path to the current directory for the current process.
+ /// @returns The current working directory.
+ /// @brief Returns the current working directory.
+ static Path GetCurrentDirectory();
+
+ /// Return the suffix commonly used on file names that contain an
+ /// executable.
+ /// @returns The executable file suffix for the current platform.
+ /// @brief Return the executable file suffix.
+ static StringRef GetEXESuffix();
+
+ /// Return the suffix commonly used on file names that contain a shared
+ /// object, shared archive, or dynamic link library. Such files are
+ /// linked at runtime into a process and their code images are shared
+ /// between processes.
+ /// @returns The dynamic link library suffix for the current platform.
+ /// @brief Return the dynamic link library suffix.
+ static StringRef GetDLLSuffix();
+
+ /// GetMainExecutable - Return the path to the main executable, given the
+ /// value of argv[0] from program startup and the address of main itself.
+ /// In extremis, this function may fail and return an empty path.
+ static Path GetMainExecutable(const char *argv0, void *MainAddr);
+
+ /// This is one of the very few ways in which a path can be constructed
+ /// with a syntactically invalid name. The only *legal* invalid name is an
+ /// empty one. Other invalid names are not permitted. Empty paths are
+ /// provided so that they can be used to indicate null or error results in
+ /// other lib/System functionality.
+ /// @brief Construct an empty (and invalid) path.
+ Path() : path() {}
+ Path(const Path &that) : path(that.path) {}
+
+ /// This constructor will accept a char* or std::string as a path. No
+ /// checking is done on this path to determine if it is valid. To
+ /// determine validity of the path, use the isValid method.
+ /// @param p The path to assign.
+ /// @brief Construct a Path from a string.
+ explicit Path(StringRef p);
+
+ /// This constructor will accept a character range as a path. No checking
+ /// is done on this path to determine if it is valid. To determine
+ /// validity of the path, use the isValid method.
+ /// @param StrStart A pointer to the first character of the path name
+ /// @param StrLen The length of the path name at StrStart
+ /// @brief Construct a Path from a string.
+ Path(const char *StrStart, unsigned StrLen);
+
+ /// @}
+ /// @name Operators
+ /// @{
+ public:
+ /// Makes a copy of \p that to \p this.
+ /// @returns \p this
+ /// @brief Assignment Operator
+ Path &operator=(const Path &that) {
+ path = that.path;
+ return *this;
+ }
+
+ /// Makes a copy of \p that to \p this.
+ /// @param that A StringRef denoting the path
+ /// @returns \p this
+ /// @brief Assignment Operator
+ Path &operator=(StringRef that);
+
+ /// Compares \p this Path with \p that Path for equality.
+ /// @returns true if \p this and \p that refer to the same thing.
+ /// @brief Equality Operator
+ bool operator==(const Path &that) const;
+
+ /// Compares \p this Path with \p that Path for inequality.
+ /// @returns true if \p this and \p that refer to different things.
+ /// @brief Inequality Operator
+ bool operator!=(const Path &that) const { return !(*this == that); }
+
+ /// Determines if \p this Path is less than \p that Path. This is required
+ /// so that Path objects can be placed into ordered collections (e.g.
+ /// std::map). The comparison is done lexicographically as defined by
+ /// the std::string::compare method.
+ /// @returns true if \p this path is lexicographically less than \p that.
+ /// @brief Less Than Operator
+ bool operator<(const Path& that) const;
+
+ /// @}
+ /// @name Path Accessors
+ /// @{
+ public:
+ /// This function will use an operating system specific algorithm to
+ /// determine if the current value of \p this is a syntactically valid
+ /// path name for the operating system. The path name does not need to
+ /// exist, validity is simply syntactical. Empty paths are always invalid.
+ /// @returns true iff the path name is syntactically legal for the
+ /// host operating system.
+ /// @brief Determine if a path is syntactically valid or not.
+ bool isValid() const;
+
+ /// This function determines if the contents of the path name are empty.
+ /// That is, the path name has a zero length. This does NOT determine if
+ /// if the file is empty. To get the length of the file itself, Use the
+ /// PathWithStatus::getFileStatus() method and then the getSize() method
+ /// on the returned FileStatus object.
+ /// @returns true iff the path is empty.
+ /// @brief Determines if the path name is empty (invalid).
+ bool isEmpty() const { return path.empty(); }
+
+ /// This function returns the last component of the path name. The last
+ /// component is the file or directory name occuring after the last
+ /// directory separator. If no directory separator is present, the entire
+ /// path name is returned (i.e. same as toString).
+ /// @returns StringRef containing the last component of the path name.
+ /// @brief Returns the last component of the path name.
+ StringRef getLast() const;
+
+ /// This function strips off the path and suffix of the file or directory
+ /// name and returns just the basename. For example /a/foo.bar would cause
+ /// this function to return "foo".
+ /// @returns StringRef containing the basename of the path
+ /// @brief Get the base name of the path
+ StringRef getBasename() const;
+
+ /// This function strips off the suffix of the path beginning with the
+ /// path separator ('/' on Unix, '\' on Windows) and returns the result.
+ StringRef getDirname() const;
+
+ /// This function strips off the path and basename(up to and
+ /// including the last dot) of the file or directory name and
+ /// returns just the suffix. For example /a/foo.bar would cause
+ /// this function to return "bar".
+ /// @returns StringRef containing the suffix of the path
+ /// @brief Get the suffix of the path
+ StringRef getSuffix() const;
+
+ /// Obtain a 'C' string for the path name.
+ /// @returns a 'C' string containing the path name.
+ /// @brief Returns the path as a C string.
+ const char *c_str() const { return path.c_str(); }
+ const std::string &str() const { return path; }
+
+
+ /// size - Return the length in bytes of this path name.
+ size_t size() const { return path.size(); }
+
+ /// empty - Returns true if the path is empty.
+ unsigned empty() const { return path.empty(); }
+
+ /// @}
+ /// @name Disk Accessors
+ /// @{
+ public:
+ /// This function determines if the path name is absolute, as opposed to
+ /// relative.
+ /// @brief Determine if the path is absolute.
+ bool isAbsolute() const;
+
+ /// This function determines if the path name is absolute, as opposed to
+ /// relative.
+ /// @brief Determine if the path is absolute.
+ static bool isAbsolute(const char *NameStart, unsigned NameLen);
+
+ /// This function opens the file associated with the path name provided by
+ /// the Path object and reads its magic number. If the magic number at the
+ /// start of the file matches \p magic, true is returned. In all other
+ /// cases (file not found, file not accessible, etc.) it returns false.
+ /// @returns true if the magic number of the file matches \p magic.
+ /// @brief Determine if file has a specific magic number
+ bool hasMagicNumber(StringRef magic) const;
+
+ /// This function retrieves the first \p len bytes of the file associated
+ /// with \p this. These bytes are returned as the "magic number" in the
+ /// \p Magic parameter.
+ /// @returns true if the Path is a file and the magic number is retrieved,
+ /// false otherwise.
+ /// @brief Get the file's magic number.
+ bool getMagicNumber(std::string& Magic, unsigned len) const;
+
+ /// This function determines if the path name in the object references an
+ /// archive file by looking at its magic number.
+ /// @returns true if the file starts with the magic number for an archive
+ /// file.
+ /// @brief Determine if the path references an archive file.
+ bool isArchive() const;
+
+ /// This function determines if the path name in the object references an
+ /// LLVM Bitcode file by looking at its magic number.
+ /// @returns true if the file starts with the magic number for LLVM
+ /// bitcode files.
+ /// @brief Determine if the path references a bitcode file.
+ bool isBitcodeFile() const;
+
+ /// This function determines if the path name in the object references a
+ /// native Dynamic Library (shared library, shared object) by looking at
+ /// the file's magic number. The Path object must reference a file, not a
+ /// directory.
+ /// @returns true if the file starts with the magic number for a native
+ /// shared library.
+ /// @brief Determine if the path references a dynamic library.
+ bool isDynamicLibrary() const;
+
+ /// This function determines if the path name in the object references a
+ /// native object file by looking at it's magic number. The term object
+ /// file is defined as "an organized collection of separate, named
+ /// sequences of binary data." This covers the obvious file formats such
+ /// as COFF and ELF, but it also includes llvm ir bitcode, archives,
+ /// libraries, etc...
+ /// @returns true if the file starts with the magic number for an object
+ /// file.
+ /// @brief Determine if the path references an object file.
+ bool isObjectFile() const;
+
+ /// This function determines if the path name references an existing file
+ /// or directory in the file system.
+ /// @returns true if the pathname references an existing file or
+ /// directory.
+ /// @brief Determines if the path is a file or directory in
+ /// the file system.
+ bool exists() const;
+
+ /// This function determines if the path name references an
+ /// existing directory.
+ /// @returns true if the pathname references an existing directory.
+ /// @brief Determines if the path is a directory in the file system.
+ bool isDirectory() const;
+
+ /// This function determines if the path name references an
+ /// existing symbolic link.
+ /// @returns true if the pathname references an existing symlink.
+ /// @brief Determines if the path is a symlink in the file system.
+ bool isSymLink() const;
+
+ /// This function determines if the path name references a readable file
+ /// or directory in the file system. This function checks for
+ /// the existence and readability (by the current program) of the file
+ /// or directory.
+ /// @returns true if the pathname references a readable file.
+ /// @brief Determines if the path is a readable file or directory
+ /// in the file system.
+ bool canRead() const;
+
+ /// This function determines if the path name references a writable file
+ /// or directory in the file system. This function checks for the
+ /// existence and writability (by the current program) of the file or
+ /// directory.
+ /// @returns true if the pathname references a writable file.
+ /// @brief Determines if the path is a writable file or directory
+ /// in the file system.
+ bool canWrite() const;
+
+ /// This function checks that what we're trying to work only on a regular
+ /// file. Check for things like /dev/null, any block special file, or
+ /// other things that aren't "regular" regular files.
+ /// @returns true if the file is S_ISREG.
+ /// @brief Determines if the file is a regular file
+ bool isRegularFile() const;
+
+ /// This function determines if the path name references an executable
+ /// file in the file system. This function checks for the existence and
+ /// executability (by the current program) of the file.
+ /// @returns true if the pathname references an executable file.
+ /// @brief Determines if the path is an executable file in the file
+ /// system.
+ bool canExecute() const;
+
+ /// This function builds a list of paths that are the names of the
+ /// files and directories in a directory.
+ /// @returns true if an error occurs, true otherwise
+ /// @brief Build a list of directory's contents.
+ bool getDirectoryContents(
+ std::set<Path> &paths, ///< The resulting list of file & directory names
+ std::string* ErrMsg ///< Optional place to return an error message.
+ ) const;
+
+ /// @}
+ /// @name Path Mutators
+ /// @{
+ public:
+ /// The path name is cleared and becomes empty. This is an invalid
+ /// path name but is the *only* invalid path name. This is provided
+ /// so that path objects can be used to indicate the lack of a
+ /// valid path being found.
+ /// @brief Make the path empty.
+ void clear() { path.clear(); }
+
+ /// This method sets the Path object to \p unverified_path. This can fail
+ /// if the \p unverified_path does not pass the syntactic checks of the
+ /// isValid() method. If verification fails, the Path object remains
+ /// unchanged and false is returned. Otherwise true is returned and the
+ /// Path object takes on the path value of \p unverified_path
+ /// @returns true if the path was set, false otherwise.
+ /// @param unverified_path The path to be set in Path object.
+ /// @brief Set a full path from a StringRef
+ bool set(StringRef unverified_path);
+
+ /// One path component is removed from the Path. If only one component is
+ /// present in the path, the Path object becomes empty. If the Path object
+ /// is empty, no change is made.
+ /// @returns false if the path component could not be removed.
+ /// @brief Removes the last directory component of the Path.
+ bool eraseComponent();
+
+ /// The \p component is added to the end of the Path if it is a legal
+ /// name for the operating system. A directory separator will be added if
+ /// needed.
+ /// @returns false if the path component could not be added.
+ /// @brief Appends one path component to the Path.
+ bool appendComponent(StringRef component);
+
+ /// A period and the \p suffix are appended to the end of the pathname.
+ /// The precondition for this function is that the Path reference a file
+ /// name (i.e. isFile() returns true). If the Path is not a file, no
+ /// action is taken and the function returns false. If the path would
+ /// become invalid for the host operating system, false is returned. When
+ /// the \p suffix is empty, no action is performed.
+ /// @returns false if the suffix could not be added, true if it was.
+ /// @brief Adds a period and the \p suffix to the end of the pathname.
+ bool appendSuffix(StringRef suffix);
+
+ /// The suffix of the filename is erased. The suffix begins with and
+ /// includes the last . character in the filename after the last directory
+ /// separator and extends until the end of the name. If no . character is
+ /// after the last directory separator, then the file name is left
+ /// unchanged (i.e. it was already without a suffix) but the function
+ /// returns false.
+ /// @returns false if there was no suffix to remove, true otherwise.
+ /// @brief Remove the suffix from a path name.
+ bool eraseSuffix();
+
+ /// The current Path name is made unique in the file system. Upon return,
+ /// the Path will have been changed to make a unique file in the file
+ /// system or it will not have been changed if the current path name is
+ /// already unique.
+ /// @throws std::string if an unrecoverable error occurs.
+ /// @brief Make the current path name unique in the file system.
+ bool makeUnique( bool reuse_current /*= true*/, std::string* ErrMsg );
+
+ /// The current Path name is made absolute by prepending the
+ /// current working directory if necessary.
+ void makeAbsolute();
+
+ /// @}
+ /// @name Disk Mutators
+ /// @{
+ public:
+ /// This method attempts to make the file referenced by the Path object
+ /// available for reading so that the canRead() method will return true.
+ /// @brief Make the file readable;
+ bool makeReadableOnDisk(std::string* ErrMsg = 0);
+
+ /// This method attempts to make the file referenced by the Path object
+ /// available for writing so that the canWrite() method will return true.
+ /// @brief Make the file writable;
+ bool makeWriteableOnDisk(std::string* ErrMsg = 0);
+
+ /// This method attempts to make the file referenced by the Path object
+ /// available for execution so that the canExecute() method will return
+ /// true.
+ /// @brief Make the file readable;
+ bool makeExecutableOnDisk(std::string* ErrMsg = 0);
+
+ /// This method allows the last modified time stamp and permission bits
+ /// to be set on the disk object referenced by the Path.
+ /// @throws std::string if an error occurs.
+ /// @returns true on error.
+ /// @brief Set the status information.
+ bool setStatusInfoOnDisk(const FileStatus &SI,
+ std::string *ErrStr = 0) const;
+
+ /// This method attempts to create a directory in the file system with the
+ /// same name as the Path object. The \p create_parents parameter controls
+ /// whether intermediate directories are created or not. if \p
+ /// create_parents is true, then an attempt will be made to create all
+ /// intermediate directories, as needed. If \p create_parents is false,
+ /// then only the final directory component of the Path name will be
+ /// created. The created directory will have no entries.
+ /// @returns true if the directory could not be created, false otherwise
+ /// @brief Create the directory this Path refers to.
+ bool createDirectoryOnDisk(
+ bool create_parents = false, ///< Determines whether non-existent
+ ///< directory components other than the last one (the "parents")
+ ///< are created or not.
+ std::string* ErrMsg = 0 ///< Optional place to put error messages.
+ );
+
+ /// This method attempts to create a file in the file system with the same
+ /// name as the Path object. The intermediate directories must all exist
+ /// at the time this method is called. Use createDirectoriesOnDisk to
+ /// accomplish that. The created file will be empty upon return from this
+ /// function.
+ /// @returns true if the file could not be created, false otherwise.
+ /// @brief Create the file this Path refers to.
+ bool createFileOnDisk(
+ std::string* ErrMsg = 0 ///< Optional place to put error messages.
+ );
+
+ /// This is like createFile except that it creates a temporary file. A
+ /// unique temporary file name is generated based on the contents of
+ /// \p this before the call. The new name is assigned to \p this and the
+ /// file is created. Note that this will both change the Path object
+ /// *and* create the corresponding file. This function will ensure that
+ /// the newly generated temporary file name is unique in the file system.
+ /// @returns true if the file couldn't be created, false otherwise.
+ /// @brief Create a unique temporary file
+ bool createTemporaryFileOnDisk(
+ bool reuse_current = false, ///< When set to true, this parameter
+ ///< indicates that if the current file name does not exist then
+ ///< it will be used without modification.
+ std::string* ErrMsg = 0 ///< Optional place to put error messages
+ );
+
+ /// This method renames the file referenced by \p this as \p newName. The
+ /// file referenced by \p this must exist. The file referenced by
+ /// \p newName does not need to exist.
+ /// @returns true on error, false otherwise
+ /// @brief Rename one file as another.
+ bool renamePathOnDisk(const Path& newName, std::string* ErrMsg);
+
+ /// This method attempts to destroy the file or directory named by the
+ /// last component of the Path. If the Path refers to a directory and the
+ /// \p destroy_contents is false, an attempt will be made to remove just
+ /// the directory (the final Path component). If \p destroy_contents is
+ /// true, an attempt will be made to remove the entire contents of the
+ /// directory, recursively. If the Path refers to a file, the
+ /// \p destroy_contents parameter is ignored.
+ /// @param destroy_contents Indicates whether the contents of a destroyed
+ /// @param Err An optional string to receive an error message.
+ /// directory should also be destroyed (recursively).
+ /// @returns false if the file/directory was destroyed, true on error.
+ /// @brief Removes the file or directory from the filesystem.
+ bool eraseFromDisk(bool destroy_contents = false,
+ std::string *Err = 0) const;
+
+
+ /// MapInFilePages - This is a low level system API to map in the file
+ /// that is currently opened as FD into the current processes' address
+ /// space for read only access. This function may return null on failure
+ /// or if the system cannot provide the following constraints:
+ /// 1) The pages must be valid after the FD is closed, until
+ /// UnMapFilePages is called.
+ /// 2) Any padding after the end of the file must be zero filled, if
+ /// present.
+ /// 3) The pages must be contiguous.
+ ///
+ /// This API is not intended for general use, clients should use
+ /// MemoryBuffer::getFile instead.
+ static const char *MapInFilePages(int FD, uint64_t FileSize);
+
+ /// UnMapFilePages - Free pages mapped into the current process by
+ /// MapInFilePages.
+ ///
+ /// This API is not intended for general use, clients should use
+ /// MemoryBuffer::getFile instead.
+ static void UnMapFilePages(const char *Base, uint64_t FileSize);
+
+ /// @}
+ /// @name Data
+ /// @{
+ protected:
+ // Our win32 implementation relies on this string being mutable.
+ mutable std::string path; ///< Storage for the path name.
+
+
+ /// @}
+ };
+
+ /// This class is identical to Path class except it allows you to obtain the
+ /// file status of the Path as well. The reason for the distinction is one of
+ /// efficiency. First, the file status requires additional space and the space
+ /// is incorporated directly into PathWithStatus without an additional malloc.
+ /// Second, obtaining status information is an expensive operation on most
+ /// operating systems so we want to be careful and explicity about where we
+ /// allow this operation in LLVM.
+ /// @brief Path with file status class.
+ class PathWithStatus : public Path {
+ /// @name Constructors
+ /// @{
+ public:
+ /// @brief Default constructor
+ PathWithStatus() : Path(), status(), fsIsValid(false) {}
+
+ /// @brief Copy constructor
+ PathWithStatus(const PathWithStatus &that)
+ : Path(static_cast<const Path&>(that)), status(that.status),
+ fsIsValid(that.fsIsValid) {}
+
+ /// This constructor allows construction from a Path object
+ /// @brief Path constructor
+ PathWithStatus(const Path &other)
+ : Path(other), status(), fsIsValid(false) {}
+
+ /// This constructor will accept a char* or std::string as a path. No
+ /// checking is done on this path to determine if it is valid. To
+ /// determine validity of the path, use the isValid method.
+ /// @brief Construct a Path from a string.
+ explicit PathWithStatus(
+ StringRef p ///< The path to assign.
+ ) : Path(p), status(), fsIsValid(false) {}
+
+ /// This constructor will accept a character range as a path. No checking
+ /// is done on this path to determine if it is valid. To determine
+ /// validity of the path, use the isValid method.
+ /// @brief Construct a Path from a string.
+ explicit PathWithStatus(
+ const char *StrStart, ///< Pointer to the first character of the path
+ unsigned StrLen ///< Length of the path.
+ ) : Path(StrStart, StrLen), status(), fsIsValid(false) {}
+
+ /// Makes a copy of \p that to \p this.
+ /// @returns \p this
+ /// @brief Assignment Operator
+ PathWithStatus &operator=(const PathWithStatus &that) {
+ static_cast<Path&>(*this) = static_cast<const Path&>(that);
+ status = that.status;
+ fsIsValid = that.fsIsValid;
+ return *this;
+ }
+
+ /// Makes a copy of \p that to \p this.
+ /// @returns \p this
+ /// @brief Assignment Operator
+ PathWithStatus &operator=(const Path &that) {
+ static_cast<Path&>(*this) = static_cast<const Path&>(that);
+ fsIsValid = false;
+ return *this;
+ }
+
+ /// @}
+ /// @name Methods
+ /// @{
+ public:
+ /// This function returns status information about the file. The type of
+ /// path (file or directory) is updated to reflect the actual contents
+ /// of the file system.
+ /// @returns 0 on failure, with Error explaining why (if non-zero)
+ /// @returns a pointer to a FileStatus structure on success.
+ /// @brief Get file status.
+ const FileStatus *getFileStatus(
+ bool forceUpdate = false, ///< Force an update from the file system
+ std::string *Error = 0 ///< Optional place to return an error msg.
+ ) const;
+
+ /// @}
+ /// @name Data
+ /// @{
+ private:
+ mutable FileStatus status; ///< Status information.
+ mutable bool fsIsValid; ///< Whether we've obtained it or not
+
+ /// @}
+ };
+
+ /// This enumeration delineates the kinds of files that LLVM knows about.
+ enum LLVMFileType {
+ Unknown_FileType = 0, ///< Unrecognized file
+ Bitcode_FileType, ///< Bitcode file
+ Archive_FileType, ///< ar style archive file
+ ELF_Relocatable_FileType, ///< ELF Relocatable object file
+ ELF_Executable_FileType, ///< ELF Executable image
+ ELF_SharedObject_FileType, ///< ELF dynamically linked shared lib
+ ELF_Core_FileType, ///< ELF core image
+ Mach_O_Object_FileType, ///< Mach-O Object file
+ Mach_O_Executable_FileType, ///< Mach-O Executable
+ Mach_O_FixedVirtualMemorySharedLib_FileType, ///< Mach-O Shared Lib, FVM
+ Mach_O_Core_FileType, ///< Mach-O Core File
+ Mach_O_PreloadExecutable_FileType, ///< Mach-O Preloaded Executable
+ Mach_O_DynamicallyLinkedSharedLib_FileType, ///< Mach-O dynlinked shared lib
+ Mach_O_DynamicLinker_FileType, ///< The Mach-O dynamic linker
+ Mach_O_Bundle_FileType, ///< Mach-O Bundle file
+ Mach_O_DynamicallyLinkedSharedLibStub_FileType, ///< Mach-O Shared lib stub
+ COFF_FileType ///< COFF object file or lib
+ };
+
+ /// This utility function allows any memory block to be examined in order
+ /// to determine its file type.
+ LLVMFileType IdentifyFileType(const char*magic, unsigned length);
+
+ /// This function can be used to copy the file specified by Src to the
+ /// file specified by Dest. If an error occurs, Dest is removed.
+ /// @returns true if an error occurs, false otherwise
+ /// @brief Copy one file to another.
+ bool CopyFile(const Path& Dest, const Path& Src, std::string* ErrMsg);
+
+ /// This is the OS-specific path separator: a colon on Unix or a semicolon
+ /// on Windows.
+ extern const char PathSeparator;
+}
+
+}
+
+#endif
--- /dev/null
+//===- llvm/System/PathV2.h - Path Operating System Concept -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the llvm::sys::path namespace. It is designed after
+// TR2/boost filesystem (v3), but modified to remove exception handling and the
+// path class.
+//
+// All functions return an error_code and their actual work via the last out
+// argument. The out argument is defined if and only if errc::success is
+// returned. A function may return any error code in the generic or system
+// category. However, they shall be equivalent to any error conditions listed
+// in each functions respective documentation if the condition applies. [ note:
+// this does not guarantee that error_code will be in the set of explicitly
+// listed codes, but it does guarantee that if any of the explicitly listed
+// errors occur, the correct error_code will be used ]. All functions may
+// return errc::not_enough_memory if there is not enough memory to complete the
+// operation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/system_error.h"
+#include <ctime>
+#include <iterator>
+#include <string>
+
+namespace llvm {
+
+// Forward decls.
+class StringRef;
+class Twine;
+
+namespace sys {
+namespace path {
+
+/// @name Lexical Component Iterator
+/// @{
+
+/// @brief Path iterator.
+///
+/// This is a bidirectional iterator that iterates over the individual
+/// components in \a path. The forward traversal order is as follows:
+/// * The root-name element, if present.
+/// * The root-directory element, if present.
+/// * Each successive filename element, if present.
+/// * Dot, if one or more trailing non-root slash characters are present.
+/// The backwards traversal order is the reverse of forward traversal.
+///
+/// Iteration examples. Each component is separated by ',':
+/// / => /
+/// /foo => /,foo
+/// foo/ => foo,.
+/// /foo/bar => /,foo,bar
+/// ../ => ..,.
+/// C:\foo\bar => C:,/,foo,bar
+///
+class const_iterator {
+ StringRef Path; //< The entire path.
+ StringRef Component; //< The current component.
+
+public:
+ typedef const StringRef value_type;
+ typedef value_type &reference;
+ typedef value_type *pointer;
+ typedef std::bidirectional_iterator_tag iterator_category;
+ reference operator*() const;
+ pointer operator->() const;
+ const_iterator &operator++(); // preincrement
+ const_iterator &operator++(int); // postincrement
+ const_iterator &operator--(); // predecrement
+ const_iterator &operator--(int); // postdecrement
+ bool operator==(const const_iterator &RHS) const;
+ bool operator!=(const const_iterator &RHS) const;
+
+ const_iterator(); //< Default construct end iterator.
+ const_iterator(const StringRef &path);
+};
+
+/// @}
+/// @name Lexical Modifiers
+/// @{
+
+/// @brief Make \a path an absolute path.
+///
+/// Makes \a path absolute using the current directory if it is not already. An
+/// empty \a path will result in the current directory.
+///
+/// /absolute/path => /absolute/path
+/// relative/../path => <current-directory>/path
+///
+/// @param path A path that is modified to be an absolute path.
+/// @returns errc::success if \a path has been made absolute, otherwise a
+/// platform specific error_code.
+error_code make_absolute(SmallVectorImpl<char> &path);
+
+/// @brief Remove the last component from \a path if it exists.
+///
+/// directory/filename.cpp => directory/
+/// directory/ => directory/
+///
+/// @param path A path that is modified to not have a file component.
+/// @returns errc::success if \a path's file name has been removed (or there was
+/// not one to begin with), otherwise a platform specific error_code.
+error_code remove_filename(SmallVectorImpl<char> &path);
+
+/// @brief Replace the file extension of \a path with \a extension.
+///
+/// ./filename.cpp => ./filename.extension
+/// ./filename => ./filename.extension
+/// ./ => ? TODO: decide what semantics this has.
+///
+/// @param path A path that has its extension replaced with \a extension.
+/// @param extension The extension to be added. It may be empty. It may also
+/// optionally start with a '.', if it does not, one will be
+/// prepended.
+/// @returns errc::success if \a path's extension has been replaced, otherwise a
+/// platform specific error_code.
+error_code replace_extension(SmallVectorImpl<char> &path,
+ const Twine &extension);
+
+/// @brief Append to path.
+///
+/// /foo + bar/f => /foo/bar/f
+/// /foo/ + bar/f => /foo/bar/f
+/// foo + bar/f => foo/bar/f
+///
+/// @param path Set to \a path + \a component.
+/// @param component The component to be appended to \a path.
+/// @returns errc::success if \a component has been appended to \a path,
+/// otherwise a platform specific error_code.
+error_code append(SmallVectorImpl<char> &path, const Twine &component);
+
+/// @brief Append to path.
+///
+/// /foo + [bar,f] => /foo/bar/f
+/// /foo/ + [bar,f] => /foo/bar/f
+/// foo + [bar,f] => foo/bar/f
+///
+/// @param path Set to \a path + [\a begin, \a end).
+/// @param begin Start of components to append.
+/// @param end One past the end of components to append.
+/// @returns errc::success if [\a begin, \a end) has been appended to \a path,
+/// otherwise a platform specific error_code.
+error_code append(SmallVectorImpl<char> &path,
+ const_iterator begin, const_iterator end);
+
+/// @}
+/// @name Transforms (or some other better name)
+/// @{
+
+/// Convert path to the native form. This is used to give paths to users and
+/// operating system calls in the platform's normal way. For example, on Windows
+/// all '/' are converted to '\'.
+///
+/// @param path A path that is transformed to native format.
+/// @param result Holds the result of the transformation.
+/// @returns errc::success if \a path has been transformed and stored in result,
+/// otherwise a platform specific error_code.
+error_code native(const Twine &path, SmallVectorImpl<char> &result);
+
+/// @}
+/// @name Lexical Observers
+/// @{
+
+/// @brief Get the current path.
+///
+/// @param result Holds the current path on return.
+/// @results errc::success if the current path has been stored in result,
+/// otherwise a platform specific error_code.
+error_code current_path(SmallVectorImpl<char> &result);
+
+// The following are purely lexical.
+
+/// @brief Is the current path valid?
+///
+/// @param path Input path.
+/// @param result Set to true if the path is valid, false if it is not.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code is_valid(const Twine &path, bool &result);
+
+/// @brief Get root name.
+///
+/// //net/hello => //net
+/// c:/hello => c: (on Windows, on other platforms nothing)
+/// /hello => <empty>
+///
+/// @param path Input path.
+/// @param result Set to the root name of \a path if it has one, otherwise "".
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code root_name(const StringRef &path, StringRef &result);
+
+/// @brief Get root directory.
+///
+/// /goo/hello => /
+/// c:/hello => /
+/// d/file.txt => <empty>
+///
+/// @param path Input path.
+/// @param result Set to the root directory of \a path if it has one, otherwise
+/// "".
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code root_directory(const StringRef &path, StringRef &result);
+
+/// @brief Get root path.
+///
+/// Equivalent to root_name + root_directory.
+///
+/// @param path Input path.
+/// @param result Set to the root path of \a path if it has one, otherwise "".
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code root_path(const StringRef &path, StringRef &result);
+
+/// @brief Get relative path.
+///
+/// C:\hello\world => hello\world
+/// foo/bar => foo/bar
+/// /foo/bar => foo/bar
+///
+/// @param path Input path.
+/// @param result Set to the path starting after root_path if one exists,
+/// otherwise "".
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code relative_path(const StringRef &path, StringRef &result);
+
+/// @brief Get parent path.
+///
+/// / => <empty>
+/// /foo => /
+/// foo/../bar => foo/..
+///
+/// @param path Input path.
+/// @param result Set to the parent path of \a path if one exists, otherwise "".
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code parent_path(const StringRef &path, StringRef &result);
+
+/// @brief Get filename.
+///
+/// /foo.txt => foo.txt
+/// . => .
+/// .. => ..
+/// / => /
+///
+/// @param path Input path.
+/// @param result Set to the filename part of \a path. This is defined as the
+/// last component of \a path.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code filename(const StringRef &path, StringRef &result);
+
+/// @brief Get stem.
+///
+/// If filename contains a dot but not solely one or two dots, result is the
+/// substring of filename ending at (but not including) the last dot. Otherwise
+/// it is filename.
+///
+/// /foo/bar.txt => bar
+/// /foo/bar => bar
+/// /foo/.txt => <empty>
+/// /foo/. => .
+/// /foo/.. => ..
+///
+/// @param path Input path.
+/// @param result Set to the stem of \a path.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code stem(const StringRef &path, StringRef &result);
+
+/// @brief Get extension.
+///
+/// If filename contains a dot but not solely one or two dots, result is the
+/// substring of filename starting at (and including) the last dot, and ending
+/// at the end of \a path. Otherwise "".
+///
+/// /foo/bar.txt => .txt
+/// /foo/bar => <empty>
+/// /foo/.txt => .txt
+///
+/// @param path Input path.
+/// @param result Set to the extension of \a path.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code extension(const StringRef &path, StringRef &result);
+
+/// @brief Has root name?
+///
+/// root_name != ""
+///
+/// @param path Input path.
+/// @param result Set to true if the path has a root name, false otherwise.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code has_root_name(const Twine &path, bool &result);
+
+/// @brief Has root directory?
+///
+/// root_directory != ""
+///
+/// @param path Input path.
+/// @param result Set to true if the path has a root directory, false otherwise.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code has_root_directory(const Twine &path, bool &result);
+
+/// @brief Has root path?
+///
+/// root_path != ""
+///
+/// @param path Input path.
+/// @param result Set to true if the path has a root path, false otherwise.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code has_root_path(const Twine &path, bool &result);
+
+/// @brief Has relative path?
+///
+/// relative_path != ""
+///
+/// @param path Input path.
+/// @param result Set to true if the path has a relative path, false otherwise.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code has_relative_path(const Twine &path, bool &result);
+
+/// @brief Has parent path?
+///
+/// parent_path != ""
+///
+/// @param path Input path.
+/// @param result Set to true if the path has a parent path, false otherwise.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code has_parent_path(const Twine &path, bool &result);
+
+/// @brief Has filename?
+///
+/// filename != ""
+///
+/// @param path Input path.
+/// @param result Set to true if the path has a filename, false otherwise.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code has_filename(const Twine &path, bool &result);
+
+/// @brief Has stem?
+///
+/// stem != ""
+///
+/// @param path Input path.
+/// @param result Set to true if the path has a stem, false otherwise.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code has_stem(const Twine &path, bool &result);
+
+/// @brief Has extension?
+///
+/// extension != ""
+///
+/// @param path Input path.
+/// @param result Set to true if the path has a extension, false otherwise.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code has_extension(const Twine &path, bool &result);
+
+/// @brief Is path absolute?
+///
+/// @param path Input path.
+/// @param result Set to true if the path is absolute, false if it is not.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code is_absolute(const Twine &path, bool &result);
+
+/// @brief Is path relative?
+///
+/// @param path Input path.
+/// @param result Set to true if the path is relative, false if it is not.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code is_relative(const Twine &path, bool &result);
+// end purely lexical.
+
+} // end namespace path
+
+namespace fs {
+
+/// file_type - An "enum class" enumeration for the file system's view of the
+/// type.
+struct file_type {
+ enum _ {
+ status_error,
+ file_not_found,
+ regular_file,
+ directory_file,
+ symlink_file,
+ block_file,
+ character_file,
+ fifo_file,
+ socket_file,
+ type_unknown
+ };
+
+ file_type(_ v) : v_(v) {}
+ explicit file_type(int v) : v_(_(v)) {}
+ operator int() const {return v_;}
+
+private:
+ int v_;
+};
+
+/// copy_option - An "enum class" enumeration of copy semantics for copy
+/// operations.
+struct copy_option {
+ enum _ {
+ fail_if_exists,
+ overwrite_if_exists
+ };
+
+ copy_option(_ v) : v_(v) {}
+ explicit copy_option(int v) : v_(_(v)) {}
+ operator int() const {return v_;}
+
+private:
+ int v_;
+};
+
+/// space_info - Self explanatory.
+struct space_info {
+ uint64_t capacity;
+ uint64_t free;
+ uint64_t available;
+};
+
+/// file_status - Represents the result of a call to stat and friends. It has
+/// a platform specific member to store the result.
+class file_status
+{
+ // implementation defined status field.
+public:
+ explicit file_status(file_type v=file_type::status_error);
+
+ file_type type() const;
+ void type(file_type v);
+};
+
+/// @}
+/// @name Physical Operators
+/// @{
+
+/// @brief Copy the file at \a from to the path \a to.
+///
+/// @param from The path to copy the file from.
+/// @param to The path to copy the file to.
+/// @param copt Behavior if \a to already exists.
+/// @returns errc::success if the file has been successfully copied.
+/// errc::file_exists if \a to already exists and \a copt ==
+/// copy_option::fail_if_exists. Otherwise a platform specific
+/// error_code.
+error_code copy_file(const Twine &from, const Twine &to,
+ copy_option copt = copy_option::fail_if_exists);
+
+/// @brief Create all the non-existent directories in path.
+///
+/// @param path Directories to create.
+/// @param existed Set to true if \a path already existed, false otherwise.
+/// @returns errc::success if is_directory(path) and existed have been set,
+/// otherwise a platform specific error_code.
+error_code create_directories(const Twine &path, bool &existed);
+
+/// @brief Create the directory in path.
+///
+/// @param path Directory to create.
+/// @param existed Set to true if \a path already existed, false otherwise.
+/// @returns errc::success if is_directory(path) and existed have been set,
+/// otherwise a platform specific error_code.
+error_code create_directory(const Twine &path, bool &existed);
+
+/// @brief Create a hard link from \a from to \a to.
+///
+/// @param to The path to hard link to.
+/// @param from The path to hard link from. This is created.
+/// @returns errc::success if exists(to) && exists(from) && equivalent(to, from)
+/// , otherwise a platform specific error_code.
+error_code create_hard_link(const Twine &to, const Twine &from);
+
+/// @brief Create a symbolic link from \a from to \a to.
+///
+/// @param to The path to symbolically link to.
+/// @param from The path to symbolically link from. This is created.
+/// @returns errc::success if exists(to) && exists(from) && is_symlink(from),
+/// otherwise a platform specific error_code.
+error_code create_symlink(const Twine &to, const Twine &from);
+
+/// @brief Remove path. Equivalent to POSIX remove().
+///
+/// @param path Input path.
+/// @param existed Set to true if \a path existed, false if it did not.
+/// undefined otherwise.
+/// @results errc::success if path has been removed and existed has been
+/// successfully set, otherwise a platform specific error_code.
+error_code remove(const Twine &path, bool &existed);
+
+/// @brief Recursively remove all files below \a path, then \a path. Files are
+/// removed as if by POSIX remove().
+///
+/// @param path Input path.
+/// @param num_removed Number of files removed.
+/// @results errc::success if path has been removed and num_removed has been
+/// successfully set, otherwise a platform specific error_code.
+error_code remove_all(const Twine &path, uint32_t &num_removed);
+
+/// @brief Rename \a from to \a to. Files are renamed as if by POSIX rename().
+///
+/// @param from The path to rename from.
+/// @param to The path to rename to. This is created.
+error_code rename(const Twine &from, const Twine &to);
+
+/// @brief Resize path to size. File is resized as if by POSIX truncate().
+///
+/// @param path Input path.
+/// @param size Size to resize to.
+/// @returns errc::success if \a path has been resized to \a size, otherwise a
+/// platform specific error_code.
+error_code resize_file(const Twine &path, uint64_t size);
+
+/// @brief Make file readable.
+///
+/// @param path Input path.
+/// @param value If true, make readable, else, make unreadable.
+/// @results errc::success if readability has been successfully set, otherwise a
+/// platform specific error_code.
+error_code set_read(const Twine &path, bool value);
+
+/// @brief Make file writeable.
+///
+/// @param path Input path.
+/// @param value If true, make writeable, else, make unwriteable.
+/// @results errc::success if writeability has been successfully set, otherwise
+/// a platform specific error_code.
+error_code set_write(const Twine &path, bool value);
+
+/// @brief Make file executable.
+///
+/// @param path Input path.
+/// @param value If true, make executable, else, make unexecutable.
+/// @results errc::success if executability has been successfully set, otherwise
+/// a platform specific error_code.
+error_code set_execute(const Twine &path, bool value);
+
+/// @}
+/// @name Physical Observers
+/// @{
+
+/// @brief Does file exist?
+///
+/// @param status A file_status previously returned from stat.
+/// @param result Set to true if the file represented by status exists, false if
+/// it does not. Undefined otherwise.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code exists(file_status status, bool &result);
+
+/// @brief Does file exist?
+///
+/// @param path Input path.
+/// @param result Set to true if the file represented by status exists, false if
+/// it does not. Undefined otherwise.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code exists(const Twine &path, bool &result);
+
+/// @brief Do paths represent the same thing?
+///
+/// @param A Input path A.
+/// @param B Input path B.
+/// @param result Set to true if stat(A) and stat(B) have the same device and
+/// inode (or equivalent).
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code equivalent(const Twine &A, const Twine &B, bool &result);
+
+/// @brief Get file size.
+///
+/// @param path Input path.
+/// @param result Set to the size of the file in \a path.
+/// @returns errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code file_size(const Twine &path, uint64_t &result);
+
+/// @brief Does status represent a directory?
+///
+/// @param status A file_status previously returned from stat.
+/// @param result Set to true if the file represented by status is a directory,
+/// false if it is not. Undefined otherwise.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code is_directory(file_status status, bool &result);
+
+/// @brief Is path a directory?
+///
+/// @param path Input path.
+/// @param result Set to true if \a path is a directory, false if it is not.
+/// Undefined otherwise.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code is_directory(const Twine &path, bool &result);
+
+/// @brief Is path an empty file?
+///
+/// @param path Input path.
+/// @param result Set to true if \a path is a an empty file, false if it is not.
+/// Undefined otherwise.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code is_empty(const Twine &path, bool &result);
+
+/// @brief Does status represent a regular file?
+///
+/// @param status A file_status previously returned from stat.
+/// @param result Set to true if the file represented by status is a regular
+/// file, false if it is not. Undefined otherwise.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code is_regular_file(file_status status, bool &result);
+
+/// @brief Is path a regular file?
+///
+/// @param path Input path.
+/// @param result Set to true if \a path is a regular file, false if it is not.
+/// Undefined otherwise.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code is_regular_file(const Twine &path, bool &result);
+
+/// @brief Does status represent something that exists but is not a directory,
+/// regular file, or symlink?
+///
+/// @param status A file_status previously returned from stat.
+/// @param result Set to true if the file represented by status exists, but is
+/// not a directory, regular file, or a symlink, false if it does
+/// not. Undefined otherwise.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code is_other(file_status status, bool &result);
+
+/// @brief Is path something that exists but is not a directory,
+/// regular file, or symlink?
+///
+/// @param path Input path.
+/// @param result Set to true if \a path exists, but is not a directory, regular
+/// file, or a symlink, false if it does not. Undefined otherwise.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code is_other(const Twine &path, bool &result);
+
+/// @brief Does status represent a symlink?
+///
+/// @param status A file_status previously returned from stat.
+/// @param result Set to true if the file represented by status is a symlink,
+/// false if it is not. Undefined otherwise.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code is_symlink(file_status status, bool &result);
+
+/// @brief Is path a symlink?
+///
+/// @param path Input path.
+/// @param result Set to true if \a path is a symlink, false if it is not.
+/// Undefined otherwise.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code is_symlink(const Twine &path, bool &result);
+
+/// @brief Get last write time without changing it.
+///
+/// @param path Input path.
+/// @param result Set to the last write time (UNIX time) of \a path if it
+/// exists.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code last_write_time(const Twine &path, std::time_t &result);
+
+/// @brief Set last write time.
+///
+/// @param path Input path.
+/// @param value Time to set (UNIX time) \a path's last write time to.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code set_last_write_time(const Twine &path, std::time_t value);
+
+/// @brief Read a symlink's value.
+///
+/// @param path Input path.
+/// @param result Set to the value of the symbolic link \a path.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code read_symlink(const Twine &path, SmallVectorImpl<char> &result);
+
+/// @brief Get disk space usage information.
+///
+/// @param path Input path.
+/// @param result Set to the capacity, free, and available space on the device
+/// \a path is on.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code disk_space(const Twine &path, space_info &result);
+
+/// @brief Get file status as if by POSIX stat().
+///
+/// @param path Input path.
+/// @param result Set to the file status.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code status(const Twine &path, file_status &result);
+
+/// @brief Is status available?
+///
+/// @param path Input path.
+/// @param result Set to true if status() != status_error.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code status_known(const Twine &path, bool &result);
+
+/// @brief Get file status as if by POSIX lstat().
+///
+/// Does not resolve symlinks.
+///
+/// @param path Input path.
+/// @param result Set to the file status.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code symlink_status(const Twine &path, file_status &result);
+
+/// @brief Get the temporary directory.
+///
+/// @param result Set to the temporary directory.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+/// @see unique_file
+error_code temp_directory_path(SmallVectorImpl<char> &result);
+
+/// @brief Generate a unique path and open it as a file.
+///
+/// Generates a unique path suitable for a temporary file and then opens it as a
+/// file. The name is based on \a model with '%' replaced by a random char in
+/// [0-9a-f].
+///
+/// This is an atomic operation. Either the file is created and opened, or the
+/// file system is left untouched.
+///
+/// clang-%%-%%-%%-%%-%%.s => <current-directory>/clang-a0-b1-c2-d3-e4.s
+///
+/// @param model Name to base unique path off of.
+/// @param result Set to the opened file.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+/// @see temp_directory_path
+error_code unique_file(const Twine &model, void* i_have_not_decided_the_ty_yet);
+
+/// @brief Canonicalize path.
+///
+/// Sets result to the file system's idea of what path is. The result is always
+/// absolute and has the same capitalization as the file system.
+///
+/// @param path Input path.
+/// @param result Set to the canonicalized version of \a path.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code canonicalize(const Twine &path, SmallVectorImpl<char> &result);
+
+/// @brief Are \a path's first bytes \a magic?
+///
+/// @param path Input path.
+/// @param magic Byte sequence to compare \a path's first len(magic) bytes to.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code has_magic(const Twine &path, const Twine &magic);
+
+/// @brief Get \a path's first \a len bytes.
+///
+/// @param path Input path.
+/// @param len Number of magic bytes to get.
+/// @param result Set to the first \a len bytes in the file pointed to by
+/// \a path.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code get_magic(const Twine &path, uint32_t len,
+ SmallVectorImpl<char> &result);
+
+/// @brief Is file bitcode?
+///
+/// @param path Input path.
+/// @param result Set to true if \a path is a bitcode file, false if it is not,
+/// undefined otherwise.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code is_bitcode(const Twine &path, bool &result);
+
+/// @brief Is file a dynamic library?
+///
+/// @param path Input path.
+/// @param result Set to true if \a path is a dynamic library, false if it is
+/// not, undefined otherwise.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code is_dynamic_library(const Twine &path, bool &result);
+
+/// @brief Is an object file?
+///
+/// @param path Input path.
+/// @param result Set to true if \a path is an object file, false if it is not,
+/// undefined otherwise.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code is_object_file(const Twine &path, bool &result);
+
+/// @brief Can file be read?
+///
+/// @param path Input path.
+/// @param result Set to true if \a path is readable, false it it is not,
+/// undefined otherwise.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code can_read(const Twine &path, bool &result);
+
+/// @brief Can file be written?
+///
+/// @param path Input path.
+/// @param result Set to true if \a path is writeable, false it it is not,
+/// undefined otherwise.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code can_write(const Twine &path, bool &result);
+
+/// @brief Can file be executed?
+///
+/// @param path Input path.
+/// @param result Set to true if \a path is executable, false it it is not,
+/// undefined otherwise.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code can_execute(const Twine &path, bool &result);
+
+/// @brief Get library paths the system linker uses.
+///
+/// @param result Set to the list of system library paths.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code GetSystemLibraryPaths(SmallVectorImpl<std::string> &result);
+
+/// @brief Get bitcode library paths the system linker uses
+/// + LLVM_LIB_SEARCH_PATH + LLVM_LIBDIR.
+///
+/// @param result Set to the list of bitcode library paths.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code GetBitcodeLibraryPaths(SmallVectorImpl<std::string> &result);
+
+/// @brief Find a library.
+///
+/// Find the path to a library using its short name. Use the system
+/// dependent library paths to locate the library.
+///
+/// c => /usr/lib/libc.so
+///
+/// @param short_name Library name one would give to the system linker.
+/// @param result Set to the absolute path \a short_name represents.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code FindLibrary(const Twine &short_name, SmallVectorImpl<char> &result);
+
+/// @brief Get absolute path of main executable.
+///
+/// @param argv0 The program name as it was spelled on the command line.
+/// @param MainAddr Address of some symbol in the executable (not in a library).
+/// @param result Set to the absolute path of the current executable.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code GetMainExecutable(const char *argv0, void *MainAddr,
+ SmallVectorImpl<char> &result);
+
+/// @}
+/// @name Iterators
+/// @{
+
+/// directory_entry - A single entry in a directory. Caches the status either
+/// from the result of the iteration syscall, or the first time status or
+/// symlink_status is called.
+class directory_entry {
+ std::string Path;
+ mutable file_status Status;
+ mutable file_status SymlinkStatus;
+
+public:
+ explicit directory_entry(const Twine &path, file_status st = file_status(),
+ file_status symlink_st = file_status());
+
+ void assign(const Twine &path, file_status st = file_status(),
+ file_status symlink_st = file_status());
+ void replace_filename(const Twine &filename, file_status st = file_status(),
+ file_status symlink_st = file_status());
+
+ const SmallVectorImpl<char> &path() const;
+ error_code status(file_status &result) const;
+ error_code symlink_status(file_status &result) const;
+
+ bool operator==(const directory_entry& rhs) const;
+ bool operator!=(const directory_entry& rhs) const;
+ bool operator< (const directory_entry& rhs) const;
+ bool operator<=(const directory_entry& rhs) const;
+ bool operator> (const directory_entry& rhs) const;
+ bool operator>=(const directory_entry& rhs) const;
+};
+
+/// directory_iterator - Iterates through the entries in path. There is no
+/// operator++ because we need an error_code. If it's really needed we can make
+/// it call report_fatal_error on error.
+class directory_iterator {
+ // implementation directory iterator status
+
+public:
+ explicit directory_iterator(const Twine &path, error_code &ec);
+ // No operator++ because we need error_code.
+ directory_iterator &increment(error_code &ec);
+
+ const directory_entry &operator*() const;
+ const directory_entry *operator->() const;
+
+ // Other members as required by
+ // C++ Std, 24.1.1 Input iterators [input.iterators]
+};
+
+/// recursive_directory_iterator - Same as directory_iterator except for it
+/// recurses down into child directories.
+class recursive_directory_iterator {
+ uint16_t Level;
+ bool HasNoPushRequest;
+ // implementation directory iterator status
+
+public:
+ explicit recursive_directory_iterator(const Twine &path, error_code &ec);
+ // No operator++ because we need error_code.
+ directory_iterator &increment(error_code &ec);
+
+ const directory_entry &operator*() const;
+ const directory_entry *operator->() const;
+
+ // observers
+ /// Gets the current level. path is at level 0.
+ int level() const;
+ /// Returns true if no_push has been called for this directory_entry.
+ bool no_push_request() const;
+
+ // modifiers
+ /// Goes up one level if Level > 0.
+ void pop();
+ /// Does not go down into the current directory_entry.
+ void no_push();
+
+ // Other members as required by
+ // C++ Std, 24.1.1 Input iterators [input.iterators]
+};
+
+/// @}
+
+} // end namespace fs
+} // end namespace sys
+} // end namespace llvm
#ifndef LLVM_SUPPORT_POINTERLIKETYPETRAITS_H
#define LLVM_SUPPORT_POINTERLIKETYPETRAITS_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
--- /dev/null
+//===- llvm/System/Process.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 declares the llvm::sys::Process class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_PROCESS_H
+#define LLVM_SYSTEM_PROCESS_H
+
+#include "llvm/Support/TimeValue.h"
+
+namespace llvm {
+namespace sys {
+
+ /// This class provides an abstraction for getting information about the
+ /// currently executing process.
+ /// @since 1.4
+ /// @brief An abstraction for operating system processes.
+ class Process {
+ /// @name Accessors
+ /// @{
+ public:
+ /// This static function will return the operating system's virtual memory
+ /// page size.
+ /// @returns The number of bytes in a virtual memory page.
+ /// @brief Get the virtual memory page size
+ static unsigned GetPageSize();
+
+ /// This static function will return the total amount of memory allocated
+ /// by the process. This only counts the memory allocated via the malloc,
+ /// calloc and realloc functions and includes any "free" holes in the
+ /// allocated space.
+ /// @brief Return process memory usage.
+ static size_t GetMallocUsage();
+
+ /// This static function will return the total memory usage of the
+ /// process. This includes code, data, stack and mapped pages usage. Notei
+ /// that the value returned here is not necessarily the Running Set Size,
+ /// it is the total virtual memory usage, regardless of mapped state of
+ /// that memory.
+ static size_t GetTotalMemoryUsage();
+
+ /// This static function will set \p user_time to the amount of CPU time
+ /// spent in user (non-kernel) mode and \p sys_time to the amount of CPU
+ /// time spent in system (kernel) mode. If the operating system does not
+ /// support collection of these metrics, a zero TimeValue will be for both
+ /// values.
+ static void GetTimeUsage(
+ TimeValue& elapsed,
+ ///< Returns the TimeValue::now() giving current time
+ TimeValue& user_time,
+ ///< Returns the current amount of user time for the process
+ TimeValue& sys_time
+ ///< Returns the current amount of system time for the process
+ );
+
+ /// This static function will return the process' current user id number.
+ /// Not all operating systems support this feature. Where it is not
+ /// supported, the function should return 65536 as the value.
+ static int GetCurrentUserId();
+
+ /// This static function will return the process' current group id number.
+ /// Not all operating systems support this feature. Where it is not
+ /// supported, the function should return 65536 as the value.
+ static int GetCurrentGroupId();
+
+ /// This function makes the necessary calls to the operating system to
+ /// prevent core files or any other kind of large memory dumps that can
+ /// occur when a program fails.
+ /// @brief Prevent core file generation.
+ static void PreventCoreFiles();
+
+ /// This function determines if the standard input is connected directly
+ /// to a user's input (keyboard probably), rather than coming from a file
+ /// or pipe.
+ static bool StandardInIsUserInput();
+
+ /// This function determines if the standard output is connected to a
+ /// "tty" or "console" window. That is, the output would be displayed to
+ /// the user rather than being put on a pipe or stored in a file.
+ static bool StandardOutIsDisplayed();
+
+ /// This function determines if the standard error is connected to a
+ /// "tty" or "console" window. That is, the output would be displayed to
+ /// the user rather than being put on a pipe or stored in a file.
+ static bool StandardErrIsDisplayed();
+
+ /// This function determines if the given file descriptor is connected to
+ /// a "tty" or "console" window. That is, the output would be displayed to
+ /// the user rather than being put on a pipe or stored in a file.
+ static bool FileDescriptorIsDisplayed(int fd);
+
+ /// This function determines the number of columns in the window
+ /// if standard output is connected to a "tty" or "console"
+ /// window. If standard output is not connected to a tty or
+ /// console, or if the number of columns cannot be determined,
+ /// this routine returns zero.
+ static unsigned StandardOutColumns();
+
+ /// This function determines the number of columns in the window
+ /// if standard error is connected to a "tty" or "console"
+ /// window. If standard error is not connected to a tty or
+ /// console, or if the number of columns cannot be determined,
+ /// this routine returns zero.
+ static unsigned StandardErrColumns();
+
+ /// This function determines whether the terminal connected to standard
+ /// output supports colors. If standard output is not connected to a
+ /// terminal, this function returns false.
+ static bool StandardOutHasColors();
+
+ /// This function determines whether the terminal connected to standard
+ /// error supports colors. If standard error is not connected to a
+ /// terminal, this function returns false.
+ static bool StandardErrHasColors();
+
+ /// Whether changing colors requires the output to be flushed.
+ /// This is needed on systems that don't support escape sequences for
+ /// changing colors.
+ static bool ColorNeedsFlush();
+
+ /// This function returns the colorcode escape sequences.
+ /// If ColorNeedsFlush() is true then this function will change the colors
+ /// and return an empty escape sequence. In that case it is the
+ /// responsibility of the client to flush the output stream prior to
+ /// calling this function.
+ static const char *OutputColor(char c, bool bold, bool bg);
+
+ /// Same as OutputColor, but only enables the bold attribute.
+ static const char *OutputBold(bool bg);
+
+ /// Resets the terminals colors, or returns an escape sequence to do so.
+ static const char *ResetColor();
+ /// @}
+ };
+}
+}
+
+#endif
--- /dev/null
+//===- llvm/System/Program.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 declares the llvm::sys::Program class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_PROGRAM_H
+#define LLVM_SYSTEM_PROGRAM_H
+
+#include "llvm/Support/Path.h"
+
+namespace llvm {
+namespace sys {
+
+ // TODO: Add operations to communicate with the process, redirect its I/O,
+ // etc.
+
+ /// This class provides an abstraction for programs that are executable by the
+ /// operating system. It provides a platform generic way to find executable
+ /// programs from the path and to execute them in various ways. The sys::Path
+ /// class is used to specify the location of the Program.
+ /// @since 1.4
+ /// @brief An abstraction for finding and executing programs.
+ class Program {
+ /// Opaque handle for target specific data.
+ void *Data_;
+
+ // Noncopyable.
+ Program(const Program& other);
+ Program& operator=(const Program& other);
+
+ /// @name Methods
+ /// @{
+ public:
+
+ Program();
+ ~Program();
+
+ /// Return process ID of this program.
+ unsigned GetPid() const;
+
+ /// This function executes the program using the \p arguments provided. The
+ /// invoked program will inherit the stdin, stdout, and stderr file
+ /// descriptors, the environment and other configuration settings of the
+ /// invoking program. If Path::executable() does not return true when this
+ /// function is called then a std::string is thrown.
+ /// @returns false in case of error, true otherwise.
+ /// @see FindProgramByName
+ /// @brief Executes the program with the given set of \p args.
+ bool Execute
+ ( const Path& path, ///< sys::Path object providing the path of the
+ ///< program to be executed. It is presumed this is the result of
+ ///< the FindProgramByName method.
+ const char** args, ///< A vector of strings that are passed to the
+ ///< program. The first element should be the name of the program.
+ ///< The list *must* be terminated by a null char* entry.
+ const char ** env = 0, ///< An optional vector of strings to use for
+ ///< the program's environment. If not provided, the current program's
+ ///< environment will be used.
+ const sys::Path** redirects = 0, ///< An optional array of pointers to
+ ///< Paths. If the array is null, no redirection is done. The array
+ ///< should have a size of at least three. If the pointer in the array
+ ///< are not null, then the inferior process's stdin(0), stdout(1),
+ ///< and stderr(2) will be redirected to the corresponding Paths.
+ ///< When an empty Path is passed in, the corresponding file
+ ///< descriptor will be disconnected (ie, /dev/null'd) in a portable
+ ///< way.
+ unsigned memoryLimit = 0, ///< If non-zero, this specifies max. amount
+ ///< of memory can be allocated by process. If memory usage will be
+ ///< higher limit, the child is killed and this call returns. If zero
+ ///< - no memory limit.
+ std::string* ErrMsg = 0 ///< If non-zero, provides a pointer to a string
+ ///< instance in which error messages will be returned. If the string
+ ///< is non-empty upon return an error occurred while invoking the
+ ///< program.
+ );
+
+ /// This function waits for the program to exit. This function will block
+ /// the current program until the invoked program exits.
+ /// @returns an integer result code indicating the status of the program.
+ /// A zero or positive value indicates the result code of the program. A
+ /// negative value is the signal number on which it terminated.
+ /// @see Execute
+ /// @brief Waits for the program to exit.
+ int Wait
+ ( const Path& path, ///< The path to the child process executable.
+ unsigned secondsToWait, ///< If non-zero, this specifies the amount
+ ///< of time to wait for the child process to exit. If the time
+ ///< expires, the child is killed and this call returns. If zero,
+ ///< this function will wait until the child finishes or forever if
+ ///< it doesn't.
+ std::string* ErrMsg ///< If non-zero, provides a pointer to a string
+ ///< instance in which error messages will be returned. If the string
+ ///< is non-empty upon return an error occurred while waiting.
+ );
+
+ /// This function terminates the program.
+ /// @returns true if an error occured.
+ /// @see Execute
+ /// @brief Terminates the program.
+ bool Kill
+ ( std::string* ErrMsg = 0 ///< If non-zero, provides a pointer to a string
+ ///< instance in which error messages will be returned. If the string
+ ///< is non-empty upon return an error occurred while killing the
+ ///< program.
+ );
+
+ /// This static constructor (factory) will attempt to locate a program in
+ /// the operating system's file system using some pre-determined set of
+ /// locations to search (e.g. the PATH on Unix). Paths with slashes are
+ /// returned unmodified.
+ /// @returns A Path object initialized to the path of the program or a
+ /// Path object that is empty (invalid) if the program could not be found.
+ /// @brief Construct a Program by finding it by name.
+ static Path FindProgramByName(const std::string& name);
+
+ // These methods change the specified standard stream (stdin,
+ // stdout, or stderr) to binary mode. They return true if an error
+ // occurred
+ static bool ChangeStdinToBinary();
+ static bool ChangeStdoutToBinary();
+ static bool ChangeStderrToBinary();
+
+ /// A convenience function equivalent to Program prg; prg.Execute(..);
+ /// prg.Wait(..);
+ /// @see Execute, Wait
+ static int ExecuteAndWait(const Path& path,
+ const char** args,
+ const char ** env = 0,
+ const sys::Path** redirects = 0,
+ unsigned secondsToWait = 0,
+ unsigned memoryLimit = 0,
+ std::string* ErrMsg = 0);
+
+ /// A convenience function equivalent to Program prg; prg.Execute(..);
+ /// @see Execute
+ static void ExecuteNoWait(const Path& path,
+ const char** args,
+ const char ** env = 0,
+ const sys::Path** redirects = 0,
+ unsigned memoryLimit = 0,
+ std::string* ErrMsg = 0);
+
+ /// @}
+
+ };
+}
+}
+
+#endif
--- /dev/null
+//===- RWMutex.h - Reader/Writer Mutual Exclusion Lock ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the llvm::sys::RWMutex class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_RWMUTEX_H
+#define LLVM_SYSTEM_RWMUTEX_H
+
+#include "llvm/Support/Threading.h"
+#include <cassert>
+
+namespace llvm
+{
+ namespace sys
+ {
+ /// @brief Platform agnostic RWMutex class.
+ class RWMutexImpl
+ {
+ /// @name Constructors
+ /// @{
+ public:
+
+ /// Initializes the lock but doesn't acquire it.
+ /// @brief Default Constructor.
+ explicit RWMutexImpl();
+
+ /// Releases and removes the lock
+ /// @brief Destructor
+ ~RWMutexImpl();
+
+ /// @}
+ /// @name Methods
+ /// @{
+ public:
+
+ /// Attempts to unconditionally acquire the lock in reader mode. If the
+ /// lock is held by a writer, this method will wait until it can acquire
+ /// the lock.
+ /// @returns false if any kind of error occurs, true otherwise.
+ /// @brief Unconditionally acquire the lock in reader mode.
+ bool reader_acquire();
+
+ /// Attempts to release the lock in reader mode.
+ /// @returns false if any kind of error occurs, true otherwise.
+ /// @brief Unconditionally release the lock in reader mode.
+ bool reader_release();
+
+ /// Attempts to unconditionally acquire the lock in reader mode. If the
+ /// lock is held by any readers, this method will wait until it can
+ /// acquire the lock.
+ /// @returns false if any kind of error occurs, true otherwise.
+ /// @brief Unconditionally acquire the lock in writer mode.
+ bool writer_acquire();
+
+ /// Attempts to release the lock in writer mode.
+ /// @returns false if any kind of error occurs, true otherwise.
+ /// @brief Unconditionally release the lock in write mode.
+ bool writer_release();
+
+ //@}
+ /// @name Platform Dependent Data
+ /// @{
+ private:
+ void* data_; ///< We don't know what the data will be
+
+ /// @}
+ /// @name Do Not Implement
+ /// @{
+ private:
+ RWMutexImpl(const RWMutexImpl & original);
+ void operator=(const RWMutexImpl &);
+ /// @}
+ };
+
+ /// SmartMutex - An R/W mutex with a compile time constant parameter that
+ /// indicates whether this mutex should become a no-op when we're not
+ /// running in multithreaded mode.
+ template<bool mt_only>
+ class SmartRWMutex : public RWMutexImpl {
+ unsigned readers, writers;
+ public:
+ explicit SmartRWMutex() : RWMutexImpl(), readers(0), writers(0) { }
+
+ bool reader_acquire() {
+ if (!mt_only || llvm_is_multithreaded())
+ return RWMutexImpl::reader_acquire();
+
+ // Single-threaded debugging code. This would be racy in multithreaded
+ // mode, but provides not sanity checks in single threaded mode.
+ ++readers;
+ return true;
+ }
+
+ bool reader_release() {
+ if (!mt_only || llvm_is_multithreaded())
+ return RWMutexImpl::reader_release();
+
+ // Single-threaded debugging code. This would be racy in multithreaded
+ // mode, but provides not sanity checks in single threaded mode.
+ assert(readers > 0 && "Reader lock not acquired before release!");
+ --readers;
+ return true;
+ }
+
+ bool writer_acquire() {
+ if (!mt_only || llvm_is_multithreaded())
+ return RWMutexImpl::writer_acquire();
+
+ // Single-threaded debugging code. This would be racy in multithreaded
+ // mode, but provides not sanity checks in single threaded mode.
+ assert(writers == 0 && "Writer lock already acquired!");
+ ++writers;
+ return true;
+ }
+
+ bool writer_release() {
+ if (!mt_only || llvm_is_multithreaded())
+ return RWMutexImpl::writer_release();
+
+ // Single-threaded debugging code. This would be racy in multithreaded
+ // mode, but provides not sanity checks in single threaded mode.
+ assert(writers == 1 && "Writer lock not acquired before release!");
+ --writers;
+ return true;
+ }
+
+ private:
+ SmartRWMutex(const SmartRWMutex<mt_only> & original);
+ void operator=(const SmartRWMutex<mt_only> &);
+ };
+ typedef SmartRWMutex<false> RWMutex;
+
+ /// ScopedReader - RAII acquisition of a reader lock
+ template<bool mt_only>
+ struct SmartScopedReader {
+ SmartRWMutex<mt_only>& mutex;
+
+ explicit SmartScopedReader(SmartRWMutex<mt_only>& m) : mutex(m) {
+ mutex.reader_acquire();
+ }
+
+ ~SmartScopedReader() {
+ mutex.reader_release();
+ }
+ };
+ typedef SmartScopedReader<false> ScopedReader;
+
+ /// ScopedWriter - RAII acquisition of a writer lock
+ template<bool mt_only>
+ struct SmartScopedWriter {
+ SmartRWMutex<mt_only>& mutex;
+
+ explicit SmartScopedWriter(SmartRWMutex<mt_only>& m) : mutex(m) {
+ mutex.writer_acquire();
+ }
+
+ ~SmartScopedWriter() {
+ mutex.writer_release();
+ }
+ };
+ typedef SmartScopedWriter<false> ScopedWriter;
+ }
+}
+
+#endif
--- /dev/null
+//===- llvm/System/Signals.h - Signal Handling support ----------*- 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 some helpful functions for dealing with the possibility of
+// unix signals occuring while your program is running.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_SIGNALS_H
+#define LLVM_SYSTEM_SIGNALS_H
+
+#include "llvm/Support/Path.h"
+
+namespace llvm {
+namespace sys {
+
+ /// This function runs all the registered interrupt handlers, including the
+ /// removal of files registered by RemoveFileOnSignal.
+ void RunInterruptHandlers();
+
+ /// This function registers signal handlers to ensure that if a signal gets
+ /// delivered that the named file is removed.
+ /// @brief Remove a file if a fatal signal occurs.
+ bool RemoveFileOnSignal(const Path &Filename, std::string* ErrMsg = 0);
+
+ /// This function removes a file from the list of files to be removed on
+ /// signal delivery.
+ void DontRemoveFileOnSignal(const Path &Filename);
+
+ /// When an error signal (such as SIBABRT or SIGSEGV) is delivered to the
+ /// process, print a stack trace and then exit.
+ /// @brief Print a stack trace if a fatal signal occurs.
+ void PrintStackTraceOnErrorSignal();
+
+ /// AddSignalHandler - Add a function to be called when an abort/kill signal
+ /// is delivered to the process. The handler can have a cookie passed to it
+ /// to identify what instance of the handler it is.
+ void AddSignalHandler(void (*FnPtr)(void *), void *Cookie);
+
+ /// This function registers a function to be called when the user "interrupts"
+ /// the program (typically by pressing ctrl-c). When the user interrupts the
+ /// program, the specified interrupt function is called instead of the program
+ /// being killed, and the interrupt function automatically disabled. Note
+ /// that interrupt functions are not allowed to call any non-reentrant
+ /// functions. An null interrupt function pointer disables the current
+ /// installed function. Note also that the handler may be executed on a
+ /// different thread on some platforms.
+ /// @brief Register a function to be called when ctrl-c is pressed.
+ void SetInterruptFunction(void (*IF)());
+} // End sys namespace
+} // End llvm namespace
+
+#endif
--- /dev/null
+/*===- llvm/System/Solaris.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 contains portability fixes for Solaris hosts.
+ *
+ *===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_SYSTEM_SOLARIS_H
+#define LLVM_SYSTEM_SOLARIS_H
+
+#include <sys/types.h>
+#include <sys/regset.h>
+
+#undef CS
+#undef DS
+#undef ES
+#undef FS
+#undef GS
+#undef SS
+#undef EAX
+#undef ECX
+#undef EDX
+#undef EBX
+#undef ESP
+#undef EBP
+#undef ESI
+#undef EDI
+#undef EIP
+#undef UESP
+#undef EFL
+#undef ERR
+#undef TRAPNO
+
+#endif
--- /dev/null
+//===- SwapByteOrder.h - Generic and optimized byte swaps -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares generic and optimized functions to swap the byte order of
+// an integral type.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_SWAP_BYTE_ORDER_H
+#define LLVM_SYSTEM_SWAP_BYTE_ORDER_H
+
+#include "llvm/Support/DataTypes.h"
+#include <cstddef>
+#include <limits>
+
+namespace llvm {
+namespace sys {
+
+/// SwapByteOrder_16 - This function returns a byte-swapped representation of
+/// the 16-bit argument.
+inline uint16_t SwapByteOrder_16(uint16_t value) {
+#if defined(_MSC_VER) && !defined(_DEBUG)
+ // The DLL version of the runtime lacks these functions (bug!?), but in a
+ // release build they're replaced with BSWAP instructions anyway.
+ return _byteswap_ushort(value);
+#else
+ uint16_t Hi = value << 8;
+ uint16_t Lo = value >> 8;
+ return Hi | Lo;
+#endif
+}
+
+/// SwapByteOrder_32 - This function returns a byte-swapped representation of
+/// the 32-bit argument.
+inline uint32_t SwapByteOrder_32(uint32_t value) {
+#if defined(__llvm__) || \
+(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && !defined(__ICC)
+ return __builtin_bswap32(value);
+#elif defined(_MSC_VER) && !defined(_DEBUG)
+ return _byteswap_ulong(value);
+#else
+ uint32_t Byte0 = value & 0x000000FF;
+ uint32_t Byte1 = value & 0x0000FF00;
+ uint32_t Byte2 = value & 0x00FF0000;
+ uint32_t Byte3 = value & 0xFF000000;
+ return (Byte0 << 24) | (Byte1 << 8) | (Byte2 >> 8) | (Byte3 >> 24);
+#endif
+}
+
+/// SwapByteOrder_64 - This function returns a byte-swapped representation of
+/// the 64-bit argument.
+inline uint64_t SwapByteOrder_64(uint64_t value) {
+#if defined(__llvm__) || \
+(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && !defined(__ICC)
+ return __builtin_bswap64(value);
+#elif defined(_MSC_VER) && !defined(_DEBUG)
+ return _byteswap_uint64(value);
+#else
+ uint64_t Hi = SwapByteOrder_32(uint32_t(value));
+ uint32_t Lo = SwapByteOrder_32(uint32_t(value >> 32));
+ return (Hi << 32) | Lo;
+#endif
+}
+
+inline unsigned char SwapByteOrder(unsigned char C) { return C; }
+inline signed char SwapByteOrder(signed char C) { return C; }
+inline char SwapByteOrder(char C) { return C; }
+
+inline unsigned short SwapByteOrder(unsigned short C) { return SwapByteOrder_16(C); }
+inline signed short SwapByteOrder( signed short C) { return SwapByteOrder_16(C); }
+
+inline unsigned int SwapByteOrder(unsigned int C) { return SwapByteOrder_32(C); }
+inline signed int SwapByteOrder( signed int C) { return SwapByteOrder_32(C); }
+
+#if __LONG_MAX__ == __INT_MAX__
+inline unsigned long SwapByteOrder(unsigned long C) { return SwapByteOrder_32(C); }
+inline signed long SwapByteOrder( signed long C) { return SwapByteOrder_32(C); }
+#elif __LONG_MAX__ == __LONG_LONG_MAX__
+inline unsigned long SwapByteOrder(unsigned long C) { return SwapByteOrder_64(C); }
+inline signed long SwapByteOrder( signed long C) { return SwapByteOrder_64(C); }
+#else
+#error "Unknown long size!"
+#endif
+
+inline unsigned long long SwapByteOrder(unsigned long long C) {
+ return SwapByteOrder_64(C);
+}
+inline signed long long SwapByteOrder(signed long long C) {
+ return SwapByteOrder_64(C);
+}
+
+} // end namespace sys
+} // end namespace llvm
+
+#endif
--- /dev/null
+//===- llvm/System/ThreadLocal.h - Thread Local Data ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the llvm::sys::ThreadLocal class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_THREAD_LOCAL_H
+#define LLVM_SYSTEM_THREAD_LOCAL_H
+
+#include "llvm/Support/Threading.h"
+#include <cassert>
+
+namespace llvm {
+ namespace sys {
+ // ThreadLocalImpl - Common base class of all ThreadLocal instantiations.
+ // YOU SHOULD NEVER USE THIS DIRECTLY.
+ class ThreadLocalImpl {
+ void* data;
+ public:
+ ThreadLocalImpl();
+ virtual ~ThreadLocalImpl();
+ void setInstance(const void* d);
+ const void* getInstance();
+ void removeInstance();
+ };
+
+ /// ThreadLocal - A class used to abstract thread-local storage. It holds,
+ /// for each thread, a pointer a single object of type T.
+ template<class T>
+ class ThreadLocal : public ThreadLocalImpl {
+ public:
+ ThreadLocal() : ThreadLocalImpl() { }
+
+ /// get - Fetches a pointer to the object associated with the current
+ /// thread. If no object has yet been associated, it returns NULL;
+ T* get() { return static_cast<T*>(getInstance()); }
+
+ // set - Associates a pointer to an object with the current thread.
+ void set(T* d) { setInstance(d); }
+
+ // erase - Removes the pointer associated with the current thread.
+ void erase() { removeInstance(); }
+ };
+ }
+}
+
+#endif
--- /dev/null
+//===-- llvm/System/Threading.h - Control multithreading mode --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// TThis file defines llvm_start_multithreaded() and friends.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_THREADING_H
+#define LLVM_SYSTEM_THREADING_H
+
+namespace llvm {
+ /// llvm_start_multithreaded - Allocate and initialize structures needed to
+ /// make LLVM safe for multithreading. The return value indicates whether
+ /// multithreaded initialization succeeded. LLVM will still be operational
+ /// on "failed" return, and will still be safe for hosting threading
+ /// applications in the JIT, but will not be safe for concurrent calls to the
+ /// LLVM APIs.
+ /// THIS MUST EXECUTE IN ISOLATION FROM ALL OTHER LLVM API CALLS.
+ bool llvm_start_multithreaded();
+
+ /// llvm_stop_multithreaded - Deallocate structures necessary to make LLVM
+ /// safe for multithreading.
+ /// THIS MUST EXECUTE IN ISOLATION FROM ALL OTHER LLVM API CALLS.
+ void llvm_stop_multithreaded();
+
+ /// llvm_is_multithreaded - Check whether LLVM is executing in thread-safe
+ /// mode or not.
+ bool llvm_is_multithreaded();
+
+ /// acquire_global_lock - Acquire the global lock. This is a no-op if called
+ /// before llvm_start_multithreaded().
+ void llvm_acquire_global_lock();
+
+ /// release_global_lock - Release the global lock. This is a no-op if called
+ /// before llvm_start_multithreaded().
+ void llvm_release_global_lock();
+
+ /// llvm_execute_on_thread - Execute the given \arg UserFn on a separate
+ /// thread, passing it the provided \arg UserData.
+ ///
+ /// This function does not guarantee that the code will actually be executed
+ /// on a separate thread or honoring the requested stack size, but tries to do
+ /// so where system support is available.
+ ///
+ /// \param UserFn - The callback to execute.
+ /// \param UserData - An argument to pass to the callback function.
+ /// \param RequestedStackSize - If non-zero, a requested size (in bytes) for
+ /// the thread stack.
+ void llvm_execute_on_thread(void (*UserFn)(void*), void *UserData,
+ unsigned RequestedStackSize = 0);
+}
+
+#endif
--- /dev/null
+//===-- TimeValue.h - Declare OS TimeValue Concept --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file declares the operating system TimeValue concept.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/DataTypes.h"
+#include <string>
+
+#ifndef LLVM_SYSTEM_TIMEVALUE_H
+#define LLVM_SYSTEM_TIMEVALUE_H
+
+namespace llvm {
+namespace sys {
+ /// This class is used where a precise fixed point in time is required. The
+ /// range of TimeValue spans many hundreds of billions of years both past and
+ /// present. The precision of TimeValue is to the nanosecond. However, the
+ /// actual precision of its values will be determined by the resolution of
+ /// the system clock. The TimeValue class is used in conjunction with several
+ /// other lib/System interfaces to specify the time at which a call should
+ /// timeout, etc.
+ /// @since 1.4
+ /// @brief Provides an abstraction for a fixed point in time.
+ class TimeValue {
+
+ /// @name Constants
+ /// @{
+ public:
+
+ /// A constant TimeValue representing the smallest time
+ /// value permissable by the class. MinTime is some point
+ /// in the distant past, about 300 billion years BCE.
+ /// @brief The smallest possible time value.
+ static const TimeValue MinTime;
+
+ /// A constant TimeValue representing the largest time
+ /// value permissable by the class. MaxTime is some point
+ /// in the distant future, about 300 billion years AD.
+ /// @brief The largest possible time value.
+ static const TimeValue MaxTime;
+
+ /// A constant TimeValue representing the base time,
+ /// or zero time of 00:00:00 (midnight) January 1st, 2000.
+ /// @brief 00:00:00 Jan 1, 2000 UTC.
+ static const TimeValue ZeroTime;
+
+ /// A constant TimeValue for the Posix base time which is
+ /// 00:00:00 (midnight) January 1st, 1970.
+ /// @brief 00:00:00 Jan 1, 1970 UTC.
+ static const TimeValue PosixZeroTime;
+
+ /// A constant TimeValue for the Win32 base time which is
+ /// 00:00:00 (midnight) January 1st, 1601.
+ /// @brief 00:00:00 Jan 1, 1601 UTC.
+ static const TimeValue Win32ZeroTime;
+
+ /// @}
+ /// @name Types
+ /// @{
+ public:
+ typedef int64_t SecondsType; ///< Type used for representing seconds.
+ typedef int32_t NanoSecondsType;///< Type used for representing nanoseconds.
+
+ enum TimeConversions {
+ NANOSECONDS_PER_SECOND = 1000000000, ///< One Billion
+ MICROSECONDS_PER_SECOND = 1000000, ///< One Million
+ MILLISECONDS_PER_SECOND = 1000, ///< One Thousand
+ NANOSECONDS_PER_MICROSECOND = 1000, ///< One Thousand
+ NANOSECONDS_PER_MILLISECOND = 1000000,///< One Million
+ NANOSECONDS_PER_POSIX_TICK = 100, ///< Posix tick is 100 Hz (10ms)
+ NANOSECONDS_PER_WIN32_TICK = 100 ///< Win32 tick is 100 Hz (10ms)
+ };
+
+ /// @}
+ /// @name Constructors
+ /// @{
+ public:
+ /// Caller provides the exact value in seconds and nanoseconds. The
+ /// \p nanos argument defaults to zero for convenience.
+ /// @brief Explicit constructor
+ explicit TimeValue (SecondsType seconds, NanoSecondsType nanos = 0)
+ : seconds_( seconds ), nanos_( nanos ) { this->normalize(); }
+
+ /// Caller provides the exact value as a double in seconds with the
+ /// fractional part representing nanoseconds.
+ /// @brief Double Constructor.
+ explicit TimeValue( double new_time )
+ : seconds_( 0 ) , nanos_ ( 0 ) {
+ SecondsType integer_part = static_cast<SecondsType>( new_time );
+ seconds_ = integer_part;
+ nanos_ = static_cast<NanoSecondsType>( (new_time -
+ static_cast<double>(integer_part)) * NANOSECONDS_PER_SECOND );
+ this->normalize();
+ }
+
+ /// This is a static constructor that returns a TimeValue that represents
+ /// the current time.
+ /// @brief Creates a TimeValue with the current time (UTC).
+ static TimeValue now();
+
+ /// @}
+ /// @name Operators
+ /// @{
+ public:
+ /// Add \p that to \p this.
+ /// @returns this
+ /// @brief Incrementing assignment operator.
+ TimeValue& operator += (const TimeValue& that ) {
+ this->seconds_ += that.seconds_ ;
+ this->nanos_ += that.nanos_ ;
+ this->normalize();
+ return *this;
+ }
+
+ /// Subtract \p that from \p this.
+ /// @returns this
+ /// @brief Decrementing assignment operator.
+ TimeValue& operator -= (const TimeValue &that ) {
+ this->seconds_ -= that.seconds_ ;
+ this->nanos_ -= that.nanos_ ;
+ this->normalize();
+ return *this;
+ }
+
+ /// Determine if \p this is less than \p that.
+ /// @returns True iff *this < that.
+ /// @brief True if this < that.
+ int operator < (const TimeValue &that) const { return that > *this; }
+
+ /// Determine if \p this is greather than \p that.
+ /// @returns True iff *this > that.
+ /// @brief True if this > that.
+ int operator > (const TimeValue &that) const {
+ if ( this->seconds_ > that.seconds_ ) {
+ return 1;
+ } else if ( this->seconds_ == that.seconds_ ) {
+ if ( this->nanos_ > that.nanos_ ) return 1;
+ }
+ return 0;
+ }
+
+ /// Determine if \p this is less than or equal to \p that.
+ /// @returns True iff *this <= that.
+ /// @brief True if this <= that.
+ int operator <= (const TimeValue &that) const { return that >= *this; }
+
+ /// Determine if \p this is greater than or equal to \p that.
+ /// @returns True iff *this >= that.
+ /// @brief True if this >= that.
+ int operator >= (const TimeValue &that) const {
+ if ( this->seconds_ > that.seconds_ ) {
+ return 1;
+ } else if ( this->seconds_ == that.seconds_ ) {
+ if ( this->nanos_ >= that.nanos_ ) return 1;
+ }
+ return 0;
+ }
+
+ /// Determines if two TimeValue objects represent the same moment in time.
+ /// @brief True iff *this == that.
+ /// @brief True if this == that.
+ int operator == (const TimeValue &that) const {
+ return (this->seconds_ == that.seconds_) &&
+ (this->nanos_ == that.nanos_);
+ }
+
+ /// Determines if two TimeValue objects represent times that are not the
+ /// same.
+ /// @return True iff *this != that.
+ /// @brief True if this != that.
+ int operator != (const TimeValue &that) const { return !(*this == that); }
+
+ /// Adds two TimeValue objects together.
+ /// @returns The sum of the two operands as a new TimeValue
+ /// @brief Addition operator.
+ friend TimeValue operator + (const TimeValue &tv1, const TimeValue &tv2);
+
+ /// Subtracts two TimeValue objects.
+ /// @returns The difference of the two operands as a new TimeValue
+ /// @brief Subtraction operator.
+ friend TimeValue operator - (const TimeValue &tv1, const TimeValue &tv2);
+
+ /// @}
+ /// @name Accessors
+ /// @{
+ public:
+
+ /// Returns only the seconds component of the TimeValue. The nanoseconds
+ /// portion is ignored. No rounding is performed.
+ /// @brief Retrieve the seconds component
+ SecondsType seconds() const { return seconds_; }
+
+ /// Returns only the nanoseconds component of the TimeValue. The seconds
+ /// portion is ignored.
+ /// @brief Retrieve the nanoseconds component.
+ NanoSecondsType nanoseconds() const { return nanos_; }
+
+ /// Returns only the fractional portion of the TimeValue rounded down to the
+ /// nearest microsecond (divide by one thousand).
+ /// @brief Retrieve the fractional part as microseconds;
+ uint32_t microseconds() const {
+ return nanos_ / NANOSECONDS_PER_MICROSECOND;
+ }
+
+ /// Returns only the fractional portion of the TimeValue rounded down to the
+ /// nearest millisecond (divide by one million).
+ /// @brief Retrieve the fractional part as milliseconds;
+ uint32_t milliseconds() const {
+ return nanos_ / NANOSECONDS_PER_MILLISECOND;
+ }
+
+ /// Returns the TimeValue as a number of microseconds. Note that the value
+ /// returned can overflow because the range of a uint64_t is smaller than
+ /// the range of a TimeValue. Nevertheless, this is useful on some operating
+ /// systems and is therefore provided.
+ /// @brief Convert to a number of microseconds (can overflow)
+ uint64_t usec() const {
+ return seconds_ * MICROSECONDS_PER_SECOND +
+ ( nanos_ / NANOSECONDS_PER_MICROSECOND );
+ }
+
+ /// Returns the TimeValue as a number of milliseconds. Note that the value
+ /// returned can overflow because the range of a uint64_t is smaller than
+ /// the range of a TimeValue. Nevertheless, this is useful on some operating
+ /// systems and is therefore provided.
+ /// @brief Convert to a number of milliseconds (can overflow)
+ uint64_t msec() const {
+ return seconds_ * MILLISECONDS_PER_SECOND +
+ ( nanos_ / NANOSECONDS_PER_MILLISECOND );
+ }
+
+ /// Converts the TimeValue into the corresponding number of "ticks" for
+ /// Posix, correcting for the difference in Posix zero time.
+ /// @brief Convert to unix time (100 nanoseconds since 12:00:00a Jan 1,1970)
+ uint64_t toPosixTime() const {
+ uint64_t result = seconds_ - PosixZeroTime.seconds_;
+ result += nanos_ / NANOSECONDS_PER_POSIX_TICK;
+ return result;
+ }
+
+ /// Converts the TimeValue into the corresponding number of seconds
+ /// since the epoch (00:00:00 Jan 1,1970).
+ uint64_t toEpochTime() const {
+ return seconds_ - PosixZeroTime.seconds_;
+ }
+
+ /// Converts the TimeValue into the corresponding number of "ticks" for
+ /// Win32 platforms, correcting for the difference in Win32 zero time.
+ /// @brief Convert to windows time (seconds since 12:00:00a Jan 1, 1601)
+ uint64_t toWin32Time() const {
+ uint64_t result = seconds_ - Win32ZeroTime.seconds_;
+ result += nanos_ / NANOSECONDS_PER_WIN32_TICK;
+ return result;
+ }
+
+ /// Provides the seconds and nanoseconds as results in its arguments after
+ /// correction for the Posix zero time.
+ /// @brief Convert to timespec time (ala POSIX.1b)
+ void getTimespecTime( uint64_t& seconds, uint32_t& nanos ) const {
+ seconds = seconds_ - PosixZeroTime.seconds_;
+ nanos = nanos_;
+ }
+
+ /// Provides conversion of the TimeValue into a readable time & date.
+ /// @returns std::string containing the readable time value
+ /// @brief Convert time to a string.
+ std::string str() const;
+
+ /// @}
+ /// @name Mutators
+ /// @{
+ public:
+ /// The seconds component of the TimeValue is set to \p sec without
+ /// modifying the nanoseconds part. This is useful for whole second
+ /// arithmetic.
+ /// @brief Set the seconds component.
+ void seconds (SecondsType sec ) {
+ this->seconds_ = sec;
+ this->normalize();
+ }
+
+ /// The nanoseconds component of the TimeValue is set to \p nanos without
+ /// modifying the seconds part. This is useful for basic computations
+ /// involving just the nanoseconds portion. Note that the TimeValue will be
+ /// normalized after this call so that the fractional (nanoseconds) portion
+ /// will have the smallest equivalent value.
+ /// @brief Set the nanoseconds component using a number of nanoseconds.
+ void nanoseconds ( NanoSecondsType nanos ) {
+ this->nanos_ = nanos;
+ this->normalize();
+ }
+
+ /// The seconds component remains unchanged.
+ /// @brief Set the nanoseconds component using a number of microseconds.
+ void microseconds ( int32_t micros ) {
+ this->nanos_ = micros * NANOSECONDS_PER_MICROSECOND;
+ this->normalize();
+ }
+
+ /// The seconds component remains unchanged.
+ /// @brief Set the nanoseconds component using a number of milliseconds.
+ void milliseconds ( int32_t millis ) {
+ this->nanos_ = millis * NANOSECONDS_PER_MILLISECOND;
+ this->normalize();
+ }
+
+ /// @brief Converts from microsecond format to TimeValue format
+ void usec( int64_t microseconds ) {
+ this->seconds_ = microseconds / MICROSECONDS_PER_SECOND;
+ this->nanos_ = NanoSecondsType(microseconds % MICROSECONDS_PER_SECOND) *
+ NANOSECONDS_PER_MICROSECOND;
+ this->normalize();
+ }
+
+ /// @brief Converts from millisecond format to TimeValue format
+ void msec( int64_t milliseconds ) {
+ this->seconds_ = milliseconds / MILLISECONDS_PER_SECOND;
+ this->nanos_ = NanoSecondsType(milliseconds % MILLISECONDS_PER_SECOND) *
+ NANOSECONDS_PER_MILLISECOND;
+ this->normalize();
+ }
+
+ /// Converts the \p seconds argument from PosixTime to the corresponding
+ /// TimeValue and assigns that value to \p this.
+ /// @brief Convert seconds form PosixTime to TimeValue
+ void fromEpochTime( SecondsType seconds ) {
+ seconds_ = seconds + PosixZeroTime.seconds_;
+ nanos_ = 0;
+ this->normalize();
+ }
+
+ /// Converts the \p win32Time argument from Windows FILETIME to the
+ /// corresponding TimeValue and assigns that value to \p this.
+ /// @brief Convert seconds form Windows FILETIME to TimeValue
+ void fromWin32Time( uint64_t win32Time ) {
+ this->seconds_ = win32Time / 10000000 + Win32ZeroTime.seconds_;
+ this->nanos_ = NanoSecondsType(win32Time % 10000000) * 100;
+ }
+
+ /// @}
+ /// @name Implementation
+ /// @{
+ private:
+ /// This causes the values to be represented so that the fractional
+ /// part is minimized, possibly incrementing the seconds part.
+ /// @brief Normalize to canonical form.
+ void normalize();
+
+ /// @}
+ /// @name Data
+ /// @{
+ private:
+ /// Store the values as a <timeval>.
+ SecondsType seconds_;///< Stores the seconds part of the TimeVal
+ NanoSecondsType nanos_; ///< Stores the nanoseconds part of the TimeVal
+ /// @}
+
+ };
+
+inline TimeValue operator + (const TimeValue &tv1, const TimeValue &tv2) {
+ TimeValue sum (tv1.seconds_ + tv2.seconds_, tv1.nanos_ + tv2.nanos_);
+ sum.normalize ();
+ return sum;
+}
+
+inline TimeValue operator - (const TimeValue &tv1, const TimeValue &tv2) {
+ TimeValue difference (tv1.seconds_ - tv2.seconds_, tv1.nanos_ - tv2.nanos_ );
+ difference.normalize ();
+ return difference;
+}
+
+}
+}
+
+#endif
#ifndef LLVM_SUPPORT_TIMER_H
#define LLVM_SUPPORT_TIMER_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/ADT/StringRef.h"
#include <cassert>
#include <string>
--- /dev/null
+//===- llvm/System/Valgrind.h - Communication with Valgrind -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Methods for communicating with a valgrind instance this program is running
+// under. These are all no-ops unless LLVM was configured on a system with the
+// valgrind headers installed and valgrind is controlling this process.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_VALGRIND_H
+#define LLVM_SYSTEM_VALGRIND_H
+
+#include <stddef.h>
+
+namespace llvm {
+namespace sys {
+ // True if Valgrind is controlling this process.
+ bool RunningOnValgrind();
+
+ // Discard valgrind's translation of code in the range [Addr .. Addr + Len).
+ // Otherwise valgrind may continue to execute the old version of the code.
+ void ValgrindDiscardTranslations(const void *Addr, size_t Len);
+}
+}
+
+#endif
#define LLVM_SUPPORT_RAW_OSTREAM_H
#include "llvm/ADT/StringRef.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
class format_object_base;
--- /dev/null
+//===---------------------------- system_error ----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This was lifted from libc++ and modified for C++03. This is called
+// system_error even though it does not define that class because that's what
+// it's called in C++0x. We don't define system_error because it is only used
+// for exception handling, which we don't use in LLVM.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_SYSTEM_ERROR_H
+#define LLVM_SYSTEM_SYSTEM_ERROR_H
+
+/*
+ system_error synopsis
+
+namespace std
+{
+
+class error_category
+{
+public:
+ virtual ~error_category();
+
+ error_category(const error_category&) = delete;
+ error_category& operator=(const error_category&) = delete;
+
+ virtual const char* name() const = 0;
+ virtual error_condition default_error_condition(int ev) const;
+ virtual bool equivalent(int code, const error_condition& condition) const;
+ virtual bool equivalent(const error_code& code, int condition) const;
+ virtual std::string message(int ev) const = 0;
+
+ bool operator==(const error_category& rhs) const;
+ bool operator!=(const error_category& rhs) const;
+ bool operator<(const error_category& rhs) const;
+};
+
+const error_category& generic_category();
+const error_category& system_category();
+
+template <class T> struct is_error_code_enum
+ : public false_type {};
+
+template <class T> struct is_error_condition_enum
+ : public false_type {};
+
+class error_code
+{
+public:
+ // constructors:
+ error_code();
+ error_code(int val, const error_category& cat);
+ template <class ErrorCodeEnum>
+ error_code(ErrorCodeEnum e);
+
+ // modifiers:
+ void assign(int val, const error_category& cat);
+ template <class ErrorCodeEnum>
+ error_code& operator=(ErrorCodeEnum e);
+ void clear();
+
+ // observers:
+ int value() const;
+ const error_category& category() const;
+ error_condition default_error_condition() const;
+ std::string message() const;
+ explicit operator bool() const;
+};
+
+// non-member functions:
+bool operator<(const error_code& lhs, const error_code& rhs);
+template <class charT, class traits>
+ basic_ostream<charT,traits>&
+ operator<<(basic_ostream<charT,traits>& os, const error_code& ec);
+
+class error_condition
+{
+public:
+ // constructors:
+ error_condition();
+ error_condition(int val, const error_category& cat);
+ template <class ErrorConditionEnum>
+ error_condition(ErrorConditionEnum e);
+
+ // modifiers:
+ void assign(int val, const error_category& cat);
+ template <class ErrorConditionEnum>
+ error_condition& operator=(ErrorConditionEnum e);
+ void clear();
+
+ // observers:
+ int value() const;
+ const error_category& category() const;
+ std::string message() const;
+ explicit operator bool() const;
+};
+
+bool operator<(const error_condition& lhs, const error_condition& rhs);
+
+class system_error
+ : public runtime_error
+{
+public:
+ system_error(error_code ec, const std::string& what_arg);
+ system_error(error_code ec, const char* what_arg);
+ system_error(error_code ec);
+ system_error(int ev, const error_category& ecat, const std::string& what_arg);
+ system_error(int ev, const error_category& ecat, const char* what_arg);
+ system_error(int ev, const error_category& ecat);
+
+ const error_code& code() const throw();
+ const char* what() const throw();
+};
+
+enum class errc
+{
+ address_family_not_supported, // EAFNOSUPPORT
+ address_in_use, // EADDRINUSE
+ address_not_available, // EADDRNOTAVAIL
+ already_connected, // EISCONN
+ argument_list_too_long, // E2BIG
+ argument_out_of_domain, // EDOM
+ bad_address, // EFAULT
+ bad_file_descriptor, // EBADF
+ bad_message, // EBADMSG
+ broken_pipe, // EPIPE
+ connection_aborted, // ECONNABORTED
+ connection_already_in_progress, // EALREADY
+ connection_refused, // ECONNREFUSED
+ connection_reset, // ECONNRESET
+ cross_device_link, // EXDEV
+ destination_address_required, // EDESTADDRREQ
+ device_or_resource_busy, // EBUSY
+ directory_not_empty, // ENOTEMPTY
+ executable_format_error, // ENOEXEC
+ file_exists, // EEXIST
+ file_too_large, // EFBIG
+ filename_too_long, // ENAMETOOLONG
+ function_not_supported, // ENOSYS
+ host_unreachable, // EHOSTUNREACH
+ identifier_removed, // EIDRM
+ illegal_byte_sequence, // EILSEQ
+ inappropriate_io_control_operation, // ENOTTY
+ interrupted, // EINTR
+ invalid_argument, // EINVAL
+ invalid_seek, // ESPIPE
+ io_error, // EIO
+ is_a_directory, // EISDIR
+ message_size, // EMSGSIZE
+ network_down, // ENETDOWN
+ network_reset, // ENETRESET
+ network_unreachable, // ENETUNREACH
+ no_buffer_space, // ENOBUFS
+ no_child_process, // ECHILD
+ no_link, // ENOLINK
+ no_lock_available, // ENOLCK
+ no_message_available, // ENODATA
+ no_message, // ENOMSG
+ no_protocol_option, // ENOPROTOOPT
+ no_space_on_device, // ENOSPC
+ no_stream_resources, // ENOSR
+ no_such_device_or_address, // ENXIO
+ no_such_device, // ENODEV
+ no_such_file_or_directory, // ENOENT
+ no_such_process, // ESRCH
+ not_a_directory, // ENOTDIR
+ not_a_socket, // ENOTSOCK
+ not_a_stream, // ENOSTR
+ not_connected, // ENOTCONN
+ not_enough_memory, // ENOMEM
+ not_supported, // ENOTSUP
+ operation_canceled, // ECANCELED
+ operation_in_progress, // EINPROGRESS
+ operation_not_permitted, // EPERM
+ operation_not_supported, // EOPNOTSUPP
+ operation_would_block, // EWOULDBLOCK
+ owner_dead, // EOWNERDEAD
+ permission_denied, // EACCES
+ protocol_error, // EPROTO
+ protocol_not_supported, // EPROTONOSUPPORT
+ read_only_file_system, // EROFS
+ resource_deadlock_would_occur, // EDEADLK
+ resource_unavailable_try_again, // EAGAIN
+ result_out_of_range, // ERANGE
+ state_not_recoverable, // ENOTRECOVERABLE
+ stream_timeout, // ETIME
+ text_file_busy, // ETXTBSY
+ timed_out, // ETIMEDOUT
+ too_many_files_open_in_system, // ENFILE
+ too_many_files_open, // EMFILE
+ too_many_links, // EMLINK
+ too_many_symbolic_link_levels, // ELOOP
+ value_too_large, // EOVERFLOW
+ wrong_protocol_type // EPROTOTYPE
+};
+
+template <> struct is_error_condition_enum<errc> : true_type { }
+
+error_code make_error_code(errc e);
+error_condition make_error_condition(errc e);
+
+// Comparison operators:
+bool operator==(const error_code& lhs, const error_code& rhs);
+bool operator==(const error_code& lhs, const error_condition& rhs);
+bool operator==(const error_condition& lhs, const error_code& rhs);
+bool operator==(const error_condition& lhs, const error_condition& rhs);
+bool operator!=(const error_code& lhs, const error_code& rhs);
+bool operator!=(const error_code& lhs, const error_condition& rhs);
+bool operator!=(const error_condition& lhs, const error_code& rhs);
+bool operator!=(const error_condition& lhs, const error_condition& rhs);
+
+template <> struct hash<std::error_code>;
+
+} // std
+
+*/
+
+#include "llvm/Config/config.h"
+#include "llvm/Support/type_traits.h"
+#include <cerrno>
+#include <string>
+
+// This must be here instead of a .inc file because it is used in the definition
+// of the enum values below.
+#ifdef LLVM_ON_WIN32
+ // VS 2008 needs this for some of the defines below.
+# include <WinSock2.h>
+
+ // The following numbers were taken from VS2010.
+# ifndef EAFNOSUPPORT
+# define EAFNOSUPPORT WSAEAFNOSUPPORT
+# endif
+# ifndef EADDRINUSE
+# define EADDRINUSE WSAEADDRINUSE
+# endif
+# ifndef EADDRNOTAVAIL
+# define EADDRNOTAVAIL WSAEADDRNOTAVAIL
+# endif
+# ifndef EISCONN
+# define EISCONN WSAEISCONN
+# endif
+# ifndef E2BIG
+# define E2BIG WSAE2BIG
+# endif
+# ifndef EDOM
+# define EDOM WSAEDOM
+# endif
+# ifndef EFAULT
+# define EFAULT WSAEFAULT
+# endif
+# ifndef EBADF
+# define EBADF WSAEBADF
+# endif
+# ifndef EBADMSG
+# define EBADMSG 104
+# endif
+# ifndef EPIPE
+# define EPIPE WSAEPIPE
+# endif
+# ifndef ECONNABORTED
+# define ECONNABORTED WSAECONNABORTED
+# endif
+# ifndef EALREADY
+# define EALREADY WSAEALREADY
+# endif
+# ifndef ECONNREFUSED
+# define ECONNREFUSED WSAECONNREFUSED
+# endif
+# ifndef ECONNRESET
+# define ECONNRESET WSAECONNRESET
+# endif
+# ifndef EXDEV
+# define EXDEV WSAEXDEV
+# endif
+# ifndef EDESTADDRREQ
+# define EDESTADDRREQ WSAEDESTADDRREQ
+# endif
+# ifndef EBUSY
+# define EBUSY WSAEBUSY
+# endif
+# ifndef ENOTEMPTY
+# define ENOTEMPTY WSAENOTEMPTY
+# endif
+# ifndef ENOEXEC
+# define ENOEXEC WSAENOEXEC
+# endif
+# ifndef EEXIST
+# define EEXIST WSAEEXIST
+# endif
+# ifndef EFBIG
+# define EFBIG WSAEFBIG
+# endif
+# ifndef ENAMETOOLONG
+# define ENAMETOOLONG WSAENAMETOOLONG
+# endif
+# ifndef ENOSYS
+# define ENOSYS WSAENOSYS
+# endif
+# ifndef EHOSTUNREACH
+# define EHOSTUNREACH WSAEHOSTUNREACH
+# endif
+# ifndef EIDRM
+# define EIDRM 111
+# endif
+# ifndef EILSEQ
+# define EILSEQ WSAEILSEQ
+# endif
+# ifndef ENOTTY
+# define ENOTTY WSAENOTTY
+# endif
+# ifndef EINTR
+# define EINTR WSAEINTR
+# endif
+# ifndef EINVAL
+# define EINVAL WSAEINVAL
+# endif
+# ifndef ESPIPE
+# define ESPIPE WSAESPIPE
+# endif
+# ifndef EIO
+# define EIO WSAEIO
+# endif
+# ifndef EISDIR
+# define EISDIR WSAEISDIR
+# endif
+# ifndef EMSGSIZE
+# define EMSGSIZE WSAEMSGSIZE
+# endif
+# ifndef ENETDOWN
+# define ENETDOWN WSAENETDOWN
+# endif
+# ifndef ENETRESET
+# define ENETRESET WSAENETRESET
+# endif
+# ifndef ENETUNREACH
+# define ENETUNREACH WSAENETUNREACH
+# endif
+# ifndef ENOBUFS
+# define ENOBUFS WSAENOBUFS
+# endif
+# ifndef ECHILD
+# define ECHILD WSAECHILD
+# endif
+# ifndef ENOLINK
+# define ENOLINK 121
+# endif
+# ifndef ENOLCK
+# define ENOLCK WSAENOLCK
+# endif
+# ifndef ENODATA
+# define ENODATA 120
+# endif
+# ifndef ENOMSG
+# define ENOMSG 122
+# endif
+# ifndef ENOPROTOOPT
+# define ENOPROTOOPT WSAENOPROTOOPT
+# endif
+# ifndef ENOSPC
+# define ENOSPC WSAENOSPC
+# endif
+# ifndef ENOSR
+# define ENOSR 124
+# endif
+# ifndef ENXIO
+# define ENXIO WSAENXIO
+# endif
+# ifndef ENODEV
+# define ENODEV WSAENODEV
+# endif
+# ifndef ENOENT
+# define ENOENT WSAENOENT
+# endif
+# ifndef ESRCH
+# define ESRCH WSAESRCH
+# endif
+# ifndef ENOTDIR
+# define ENOTDIR WSAENOTDIR
+# endif
+# ifndef ENOTSOCK
+# define ENOTSOCK WSAENOTSOCK
+# endif
+# ifndef ENOSTR
+# define ENOSTR 125
+# endif
+# ifndef ENOTCONN
+# define ENOTCONN WSAENOTCONN
+# endif
+# ifndef ENOMEM
+# define ENOMEM WSAENOMEM
+# endif
+# ifndef ENOTSUP
+# define ENOTSUP 129
+# endif
+# ifndef ECANCELED
+# define ECANCELED 105
+# endif
+# ifndef EINPROGRESS
+# define EINPROGRESS WSAEINPROGRESS
+# endif
+# ifndef EPERM
+# define EPERM WSAEPERM
+# endif
+# ifndef EOPNOTSUPP
+# define EOPNOTSUPP WSAEOPNOTSUPP
+# endif
+# ifndef EWOULDBLOCK
+# define EWOULDBLOCK WSAEWOULDBLOCK
+# endif
+# ifndef EOWNERDEAD
+# define EOWNERDEAD 133
+# endif
+# ifndef EACCES
+# define EACCES WSAEACCES
+# endif
+# ifndef EPROTO
+# define EPROTO 134
+# endif
+# ifndef EPROTONOSUPPORT
+# define EPROTONOSUPPORT WSAEPROTONOSUPPORT
+# endif
+# ifndef EROFS
+# define EROFS WSAEROFS
+# endif
+# ifndef EDEADLK
+# define EDEADLK WSAEDEADLK
+# endif
+# ifndef EAGAIN
+# define EAGAIN WSAEAGAIN
+# endif
+# ifndef ERANGE
+# define ERANGE WSAERANGE
+# endif
+# ifndef ENOTRECOVERABLE
+# define ENOTRECOVERABLE 127
+# endif
+# ifndef ETIME
+# define ETIME 137
+# endif
+# ifndef ETXTBSY
+# define ETXTBSY 139
+# endif
+# ifndef ETIMEDOUT
+# define ETIMEDOUT WSAETIMEDOUT
+# endif
+# ifndef ENFILE
+# define ENFILE WSAENFILE
+# endif
+# ifndef EMFILE
+# define EMFILE WSAEMFILE
+# endif
+# ifndef EMLINK
+# define EMLINK WSAEMLINK
+# endif
+# ifndef ELOOP
+# define ELOOP WSAELOOP
+# endif
+# ifndef EOVERFLOW
+# define EOVERFLOW 132
+# endif
+# ifndef EPROTOTYPE
+# define EPROTOTYPE WSAEPROTOTYPE
+# endif
+#endif
+
+namespace llvm {
+
+template <class T, T v>
+struct integral_constant {
+ typedef T value_type;
+ static const value_type value = v;
+ typedef integral_constant<T,v> type;
+ operator value_type() { return value; }
+};
+
+typedef integral_constant<bool, true> true_type;
+typedef integral_constant<bool, false> false_type;
+
+// is_error_code_enum
+
+template <class Tp> struct is_error_code_enum : public false_type {};
+
+// is_error_condition_enum
+
+template <class Tp> struct is_error_condition_enum : public false_type {};
+
+// Some error codes are not present on all platforms, so we provide equivalents
+// for them:
+
+//enum class errc
+struct errc {
+enum _ {
+ success = 0,
+ address_family_not_supported = EAFNOSUPPORT,
+ address_in_use = EADDRINUSE,
+ address_not_available = EADDRNOTAVAIL,
+ already_connected = EISCONN,
+ argument_list_too_long = E2BIG,
+ argument_out_of_domain = EDOM,
+ bad_address = EFAULT,
+ bad_file_descriptor = EBADF,
+#ifdef EBADMSG
+ bad_message = EBADMSG,
+#else
+ bad_message = EINVAL,
+#endif
+ broken_pipe = EPIPE,
+ connection_aborted = ECONNABORTED,
+ connection_already_in_progress = EALREADY,
+ connection_refused = ECONNREFUSED,
+ connection_reset = ECONNRESET,
+ cross_device_link = EXDEV,
+ destination_address_required = EDESTADDRREQ,
+ device_or_resource_busy = EBUSY,
+ directory_not_empty = ENOTEMPTY,
+ executable_format_error = ENOEXEC,
+ file_exists = EEXIST,
+ file_too_large = EFBIG,
+ filename_too_long = ENAMETOOLONG,
+ function_not_supported = ENOSYS,
+ host_unreachable = EHOSTUNREACH,
+ identifier_removed = EIDRM,
+ illegal_byte_sequence = EILSEQ,
+ inappropriate_io_control_operation = ENOTTY,
+ interrupted = EINTR,
+ invalid_argument = EINVAL,
+ invalid_seek = ESPIPE,
+ io_error = EIO,
+ is_a_directory = EISDIR,
+ message_size = EMSGSIZE,
+ network_down = ENETDOWN,
+ network_reset = ENETRESET,
+ network_unreachable = ENETUNREACH,
+ no_buffer_space = ENOBUFS,
+ no_child_process = ECHILD,
+#ifdef ENOLINK
+ no_link = ENOLINK,
+#else
+ no_link = EINVAL,
+#endif
+ no_lock_available = ENOLCK,
+#ifdef ENODATA
+ no_message_available = ENODATA,
+#else
+ no_message_available = ENOMSG,
+#endif
+ no_message = ENOMSG,
+ no_protocol_option = ENOPROTOOPT,
+ no_space_on_device = ENOSPC,
+#ifdef ENOSR
+ no_stream_resources = ENOSR,
+#else
+ no_stream_resources = ENOMEM,
+#endif
+ no_such_device_or_address = ENXIO,
+ no_such_device = ENODEV,
+ no_such_file_or_directory = ENOENT,
+ no_such_process = ESRCH,
+ not_a_directory = ENOTDIR,
+ not_a_socket = ENOTSOCK,
+#ifdef ENOSTR
+ not_a_stream = ENOSTR,
+#else
+ not_a_stream = EINVAL,
+#endif
+ not_connected = ENOTCONN,
+ not_enough_memory = ENOMEM,
+ not_supported = ENOTSUP,
+#ifdef ECANCELED
+ operation_canceled = ECANCELED,
+#else
+ operation_canceled = EINVAL,
+#endif
+ operation_in_progress = EINPROGRESS,
+ operation_not_permitted = EPERM,
+ operation_not_supported = EOPNOTSUPP,
+ operation_would_block = EWOULDBLOCK,
+#ifdef EOWNERDEAD
+ owner_dead = EOWNERDEAD,
+#else
+ owner_dead = EINVAL,
+#endif
+ permission_denied = EACCES,
+#ifdef EPROTO
+ protocol_error = EPROTO,
+#else
+ protocol_error = EINVAL,
+#endif
+ protocol_not_supported = EPROTONOSUPPORT,
+ read_only_file_system = EROFS,
+ resource_deadlock_would_occur = EDEADLK,
+ resource_unavailable_try_again = EAGAIN,
+ result_out_of_range = ERANGE,
+#ifdef ENOTRECOVERABLE
+ state_not_recoverable = ENOTRECOVERABLE,
+#else
+ state_not_recoverable = EINVAL,
+#endif
+#ifdef ETIME
+ stream_timeout = ETIME,
+#else
+ stream_timeout = ETIMEDOUT,
+#endif
+ text_file_busy = ETXTBSY,
+ timed_out = ETIMEDOUT,
+ too_many_files_open_in_system = ENFILE,
+ too_many_files_open = EMFILE,
+ too_many_links = EMLINK,
+ too_many_symbolic_link_levels = ELOOP,
+ value_too_large = EOVERFLOW,
+ wrong_protocol_type = EPROTOTYPE
+};
+
+ _ v_;
+
+ errc(_ v) : v_(v) {}
+ operator int() const {return v_;}
+};
+
+template <> struct is_error_condition_enum<errc> : true_type { };
+
+template <> struct is_error_condition_enum<errc::_> : true_type { };
+
+class error_condition;
+class error_code;
+
+// class error_category
+
+class _do_message;
+
+class error_category
+{
+public:
+ virtual ~error_category();
+
+private:
+ error_category();
+ error_category(const error_category&);// = delete;
+ error_category& operator=(const error_category&);// = delete;
+
+public:
+ virtual const char* name() const = 0;
+ virtual error_condition default_error_condition(int _ev) const;
+ virtual bool equivalent(int _code, const error_condition& _condition) const;
+ virtual bool equivalent(const error_code& _code, int _condition) const;
+ virtual std::string message(int _ev) const = 0;
+
+ bool operator==(const error_category& _rhs) const {return this == &_rhs;}
+
+ bool operator!=(const error_category& _rhs) const {return !(*this == _rhs);}
+
+ bool operator< (const error_category& _rhs) const {return this < &_rhs;}
+
+ friend class _do_message;
+};
+
+class _do_message : public error_category
+{
+public:
+ virtual std::string message(int ev) const;
+};
+
+const error_category& generic_category();
+const error_category& system_category();
+
+class error_condition
+{
+ int _val_;
+ const error_category* _cat_;
+public:
+ error_condition() : _val_(0), _cat_(&generic_category()) {}
+
+ error_condition(int _val, const error_category& _cat)
+ : _val_(_val), _cat_(&_cat) {}
+
+ template <class E>
+ error_condition(E _e, typename enable_if_c<
+ is_error_condition_enum<E>::value
+ >::type* = 0)
+ {*this = make_error_condition(_e);}
+
+ void assign(int _val, const error_category& _cat) {
+ _val_ = _val;
+ _cat_ = &_cat;
+ }
+
+ template <class E>
+ typename enable_if_c
+ <
+ is_error_condition_enum<E>::value,
+ error_condition&
+ >::type
+ operator=(E _e)
+ {*this = make_error_condition(_e); return *this;}
+
+ void clear() {
+ _val_ = 0;
+ _cat_ = &generic_category();
+ }
+
+ int value() const {return _val_;}
+
+ const error_category& category() const {return *_cat_;}
+ std::string message() const;
+
+ // explicit
+ operator bool() const {return _val_ != 0;}
+};
+
+inline error_condition make_error_condition(errc _e) {
+ return error_condition(static_cast<int>(_e), generic_category());
+}
+
+inline bool operator<(const error_condition& _x, const error_condition& _y) {
+ return _x.category() < _y.category()
+ || (_x.category() == _y.category() && _x.value() < _y.value());
+}
+
+// error_code
+
+class error_code {
+ int _val_;
+ const error_category* _cat_;
+public:
+ error_code() : _val_(0), _cat_(&system_category()) {}
+
+ error_code(int _val, const error_category& _cat)
+ : _val_(_val), _cat_(&_cat) {}
+
+ template <class E>
+ error_code(E _e, typename enable_if_c<
+ is_error_code_enum<E>::value
+ >::type* = 0) {
+ *this = make_error_code(_e);
+ }
+
+ void assign(int _val, const error_category& _cat) {
+ _val_ = _val;
+ _cat_ = &_cat;
+ }
+
+ template <class E>
+ typename enable_if_c
+ <
+ is_error_code_enum<E>::value,
+ error_code&
+ >::type
+ operator=(E _e)
+ {*this = make_error_code(_e); return *this;}
+
+ void clear() {
+ _val_ = 0;
+ _cat_ = &system_category();
+ }
+
+ int value() const {return _val_;}
+
+ const error_category& category() const {return *_cat_;}
+
+ error_condition default_error_condition() const
+ {return _cat_->default_error_condition(_val_);}
+
+ std::string message() const;
+
+ // explicit
+ operator bool() const {return _val_ != 0;}
+};
+
+inline error_code make_error_code(errc _e) {
+ return error_code(static_cast<int>(_e), generic_category());
+}
+
+inline bool operator<(const error_code& _x, const error_code& _y) {
+ return _x.category() < _y.category()
+ || (_x.category() == _y.category() && _x.value() < _y.value());
+}
+
+inline bool operator==(const error_code& _x, const error_code& _y) {
+ return _x.category() == _y.category() && _x.value() == _y.value();
+}
+
+inline bool operator==(const error_code& _x, const error_condition& _y) {
+ return _x.category().equivalent(_x.value(), _y)
+ || _y.category().equivalent(_x, _y.value());
+}
+
+inline bool operator==(const error_condition& _x, const error_code& _y) {
+ return _y == _x;
+}
+
+inline bool operator==(const error_condition& _x, const error_condition& _y) {
+ return _x.category() == _y.category() && _x.value() == _y.value();
+}
+
+inline bool operator!=(const error_code& _x, const error_code& _y) {
+ return !(_x == _y);
+}
+
+inline bool operator!=(const error_code& _x, const error_condition& _y) {
+ return !(_x == _y);
+}
+
+inline bool operator!=(const error_condition& _x, const error_code& _y) {
+ return !(_x == _y);
+}
+
+inline bool operator!=(const error_condition& _x, const error_condition& _y) {
+ return !(_x == _y);
+}
+
+// system_error
+
+} // end namespace llvm
+
+// This needs to stay here for KillTheDoctor.
+#ifdef LLVM_ON_WIN32
+// FIXME: These two headers really really really need to be removed from here.
+// Not only is it a violation of System, they define the stupid min and
+// max macros :(.
+#include <Windows.h>
+#include <WinError.h>
+
+namespace llvm {
+
+// To construct an error_code after an API error:
+//
+// error_code( ::GetLastError(), system_category() )
+struct windows_error {
+enum _ {
+ success = 0,
+ // These names and values are based on Windows winerror.h
+ // This is not a complete list.
+ invalid_function = ERROR_INVALID_FUNCTION,
+ file_not_found = ERROR_FILE_NOT_FOUND,
+ path_not_found = ERROR_PATH_NOT_FOUND,
+ too_many_open_files = ERROR_TOO_MANY_OPEN_FILES,
+ access_denied = ERROR_ACCESS_DENIED,
+ invalid_handle = ERROR_INVALID_HANDLE,
+ arena_trashed = ERROR_ARENA_TRASHED,
+ not_enough_memory = ERROR_NOT_ENOUGH_MEMORY,
+ invalid_block = ERROR_INVALID_BLOCK,
+ bad_environment = ERROR_BAD_ENVIRONMENT,
+ bad_format = ERROR_BAD_FORMAT,
+ invalid_access = ERROR_INVALID_ACCESS,
+ outofmemory = ERROR_OUTOFMEMORY,
+ invalid_drive = ERROR_INVALID_DRIVE,
+ current_directory = ERROR_CURRENT_DIRECTORY,
+ not_same_device = ERROR_NOT_SAME_DEVICE,
+ no_more_files = ERROR_NO_MORE_FILES,
+ write_protect = ERROR_WRITE_PROTECT,
+ bad_unit = ERROR_BAD_UNIT,
+ not_ready = ERROR_NOT_READY,
+ bad_command = ERROR_BAD_COMMAND,
+ crc = ERROR_CRC,
+ bad_length = ERROR_BAD_LENGTH,
+ seek = ERROR_SEEK,
+ not_dos_disk = ERROR_NOT_DOS_DISK,
+ sector_not_found = ERROR_SECTOR_NOT_FOUND,
+ out_of_paper = ERROR_OUT_OF_PAPER,
+ write_fault = ERROR_WRITE_FAULT,
+ read_fault = ERROR_READ_FAULT,
+ gen_failure = ERROR_GEN_FAILURE,
+ sharing_violation = ERROR_SHARING_VIOLATION,
+ lock_violation = ERROR_LOCK_VIOLATION,
+ wrong_disk = ERROR_WRONG_DISK,
+ sharing_buffer_exceeded = ERROR_SHARING_BUFFER_EXCEEDED,
+ handle_eof = ERROR_HANDLE_EOF,
+ handle_disk_full = ERROR_HANDLE_DISK_FULL,
+ rem_not_list = ERROR_REM_NOT_LIST,
+ dup_name = ERROR_DUP_NAME,
+ bad_net_path = ERROR_BAD_NETPATH,
+ network_busy = ERROR_NETWORK_BUSY,
+ file_exists = ERROR_FILE_EXISTS,
+ cannot_make = ERROR_CANNOT_MAKE,
+ broken_pipe = ERROR_BROKEN_PIPE,
+ open_failed = ERROR_OPEN_FAILED,
+ buffer_overflow = ERROR_BUFFER_OVERFLOW,
+ disk_full = ERROR_DISK_FULL,
+ lock_failed = ERROR_LOCK_FAILED,
+ busy = ERROR_BUSY,
+ cancel_violation = ERROR_CANCEL_VIOLATION,
+ already_exists = ERROR_ALREADY_EXISTS
+};
+ _ v_;
+
+ windows_error(_ v) : v_(v) {}
+ explicit windows_error(DWORD v) : v_(_(v)) {}
+ operator int() const {return v_;}
+};
+
+
+template <> struct is_error_code_enum<windows_error> : true_type { };
+
+template <> struct is_error_code_enum<windows_error::_> : true_type { };
+
+inline error_code make_error_code(windows_error e) {
+ return error_code(static_cast<int>(e), system_category());
+}
+
+} // end namespace llvm
+
+#endif // LLVM_ON_WINDOWS
+
+#endif
+++ /dev/null
-//===-- llvm/System/AIXDataTypesFix.h - Fix datatype defs ------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file overrides default system-defined types and limits which cannot be
-// done in DataTypes.h.in because it is processed by autoheader first, which
-// comments out any #undef statement
-//
-//===----------------------------------------------------------------------===//
-
-// No include guards desired!
-
-#ifndef SUPPORT_DATATYPES_H
-#error "AIXDataTypesFix.h must only be included via DataTypes.h!"
-#endif
-
-// GCC is strict about defining large constants: they must have LL modifier.
-// These will be defined properly at the end of DataTypes.h
-#undef INT64_MAX
-#undef INT64_MIN
+++ /dev/null
-//===- llvm/System/Alarm.h - Alarm Generation support ----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides an operating system independent interface to alarm(2)
-// type functionality. The Alarm class allows a one-shot alarm to be set up
-// at some number of seconds in the future. When the alarm triggers, a method
-// is called to process the event
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SYSTEM_ALARM_H
-#define LLVM_SYSTEM_ALARM_H
-
-namespace llvm {
-namespace sys {
-
- /// This function registers an alarm to trigger some number of \p seconds in
- /// the future. When that time arrives, the AlarmStatus function will begin
- /// to return 1 instead of 0. The user must poll the status of the alarm by
- /// making occasional calls to AlarmStatus. If the user sends an interrupt
- /// signal, AlarmStatus will begin returning -1, even if the alarm event
- /// occurred.
- /// @returns nothing
- void SetupAlarm(
- unsigned seconds ///< Number of seconds in future when alarm arrives
- );
-
- /// This function terminates the alarm previously set up
- /// @returns nothing
- void TerminateAlarm();
-
- /// This function acquires the status of the alarm.
- /// @returns -1=cancelled, 0=untriggered, 1=triggered
- int AlarmStatus();
-
- /// Sleep for n seconds. Warning: mixing calls to Sleep() and other *Alarm
- /// calls may be a bad idea on some platforms (source: Linux man page).
- /// @returns nothing.
- void Sleep(unsigned n);
-
-
-} // End sys namespace
-} // End llvm namespace
-
-#endif
+++ /dev/null
-//===- llvm/System/Atomic.h - Atomic Operations -----------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares the llvm::sys atomic operations.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SYSTEM_ATOMIC_H
-#define LLVM_SYSTEM_ATOMIC_H
-
-#include "llvm/System/DataTypes.h"
-
-namespace llvm {
- namespace sys {
- void MemoryFence();
-
-#ifdef _MSC_VER
- typedef long cas_flag;
-#else
- typedef uint32_t cas_flag;
-#endif
- cas_flag CompareAndSwap(volatile cas_flag* ptr,
- cas_flag new_value,
- cas_flag old_value);
- cas_flag AtomicIncrement(volatile cas_flag* ptr);
- cas_flag AtomicDecrement(volatile cas_flag* ptr);
- cas_flag AtomicAdd(volatile cas_flag* ptr, cas_flag val);
- cas_flag AtomicMul(volatile cas_flag* ptr, cas_flag val);
- cas_flag AtomicDiv(volatile cas_flag* ptr, cas_flag val);
- }
-}
-
-#endif
+++ /dev/null
-/*===-- include/System/DataTypes.h - Define fixed size types -----*- C -*-===*\
-|* *|
-|* The LLVM Compiler Infrastructure *|
-|* *|
-|* This file is distributed under the University of Illinois Open Source *|
-|* License. See LICENSE.TXT for details. *|
-|* *|
-|*===----------------------------------------------------------------------===*|
-|* *|
-|* This file contains definitions to figure out the size of _HOST_ data types.*|
-|* This file is important because different host OS's define different macros,*|
-|* which makes portability tough. This file exports the following *|
-|* definitions: *|
-|* *|
-|* [u]int(32|64)_t : typedefs for signed and unsigned 32/64 bit system types*|
-|* [U]INT(8|16|32|64)_(MIN|MAX) : Constants for the min and max values. *|
-|* *|
-|* No library is required when using these functinons. *|
-|* *|
-|*===----------------------------------------------------------------------===*/
-
-/* Please leave this file C-compatible. */
-
-#ifndef SUPPORT_DATATYPES_H
-#define SUPPORT_DATATYPES_H
-
-#cmakedefine HAVE_SYS_TYPES_H ${HAVE_SYS_TYPES_H}
-#cmakedefine HAVE_INTTYPES_H ${HAVE_INTTYPES_H}
-#cmakedefine HAVE_STDINT_H ${HAVE_STDINT_H}
-#cmakedefine HAVE_UINT64_T ${HAVE_UINT64_T}
-#cmakedefine HAVE_U_INT64_T ${HAVE_U_INT64_T}
-
-#ifdef __cplusplus
-#include <cmath>
-#else
-#include <math.h>
-#endif
-
-#ifndef _MSC_VER
-
-/* Note that this header's correct operation depends on __STDC_LIMIT_MACROS
- being defined. We would define it here, but in order to prevent Bad Things
- happening when system headers or C++ STL headers include stdint.h before we
- define it here, we define it on the g++ command line (in Makefile.rules). */
-#if !defined(__STDC_LIMIT_MACROS)
-# error "Must #define __STDC_LIMIT_MACROS before #including System/DataTypes.h"
-#endif
-
-#if !defined(__STDC_CONSTANT_MACROS)
-# error "Must #define __STDC_CONSTANT_MACROS before " \
- "#including System/DataTypes.h"
-#endif
-
-/* Note that <inttypes.h> includes <stdint.h>, if this is a C99 system. */
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
-
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-
-#ifdef _AIX
-#include "llvm/System/AIXDataTypesFix.h"
-#endif
-
-/* Handle incorrect definition of uint64_t as u_int64_t */
-#ifndef HAVE_UINT64_T
-#ifdef HAVE_U_INT64_T
-typedef u_int64_t uint64_t;
-#else
-# error "Don't have a definition for uint64_t on this platform"
-#endif
-#endif
-
-#ifdef _OpenBSD_
-#define INT8_MAX 127
-#define INT8_MIN -128
-#define UINT8_MAX 255
-#define INT16_MAX 32767
-#define INT16_MIN -32768
-#define UINT16_MAX 65535
-#define INT32_MAX 2147483647
-#define INT32_MIN -2147483648
-#define UINT32_MAX 4294967295U
-#endif
-
-#else /* _MSC_VER */
-/* Visual C++ doesn't provide standard integer headers, but it does provide
- built-in data types. */
-#include <stdlib.h>
-#include <stddef.h>
-#include <sys/types.h>
-#ifdef __cplusplus
-#include <cmath>
-#else
-#include <math.h>
-#endif
-typedef __int64 int64_t;
-typedef unsigned __int64 uint64_t;
-typedef signed int int32_t;
-typedef unsigned int uint32_t;
-typedef short int16_t;
-typedef unsigned short uint16_t;
-typedef signed char int8_t;
-typedef unsigned char uint8_t;
-typedef signed int ssize_t;
-#ifndef INT8_MAX
-# define INT8_MAX 127
-#endif
-#ifndef INT8_MIN
-# define INT8_MIN -128
-#endif
-#ifndef UINT8_MAX
-# define UINT8_MAX 255
-#endif
-#ifndef INT16_MAX
-# define INT16_MAX 32767
-#endif
-#ifndef INT16_MIN
-# define INT16_MIN -32768
-#endif
-#ifndef UINT16_MAX
-# define UINT16_MAX 65535
-#endif
-#ifndef INT32_MAX
-# define INT32_MAX 2147483647
-#endif
-#ifndef INT32_MIN
-# define INT32_MIN -2147483648
-#endif
-#ifndef UINT32_MAX
-# define UINT32_MAX 4294967295U
-#endif
-/* Certain compatibility updates to VC++ introduce the `cstdint'
- * header, which defines the INT*_C macros. On default installs they
- * are absent. */
-#ifndef INT8_C
-# define INT8_C(C) C##i8
-#endif
-#ifndef UINT8_C
-# define UINT8_C(C) C##ui8
-#endif
-#ifndef INT16_C
-# define INT16_C(C) C##i16
-#endif
-#ifndef UINT16_C
-# define UINT16_C(C) C##ui16
-#endif
-#ifndef INT32_C
-# define INT32_C(C) C##i32
-#endif
-#ifndef UINT32_C
-# define UINT32_C(C) C##ui32
-#endif
-#ifndef INT64_C
-# define INT64_C(C) C##i64
-#endif
-#ifndef UINT64_C
-# define UINT64_C(C) C##ui64
-#endif
-#endif /* _MSC_VER */
-
-/* Set defaults for constants which we cannot find. */
-#if !defined(INT64_MAX)
-# define INT64_MAX 9223372036854775807LL
-#endif
-#if !defined(INT64_MIN)
-# define INT64_MIN ((-INT64_MAX)-1)
-#endif
-#if !defined(UINT64_MAX)
-# define UINT64_MAX 0xffffffffffffffffULL
-#endif
-
-#if __GNUC__ > 3
-#define END_WITH_NULL __attribute__((sentinel))
-#else
-#define END_WITH_NULL
-#endif
-
-#ifndef HUGE_VALF
-#define HUGE_VALF (float)HUGE_VAL
-#endif
-
-#endif /* SUPPORT_DATATYPES_H */
+++ /dev/null
-/*===-- include/System/DataTypes.h - Define fixed size types -----*- C -*-===*\
-|* *|
-|* The LLVM Compiler Infrastructure *|
-|* *|
-|* This file is distributed under the University of Illinois Open Source *|
-|* License. See LICENSE.TXT for details. *|
-|* *|
-|*===----------------------------------------------------------------------===*|
-|* *|
-|* This file contains definitions to figure out the size of _HOST_ data types.*|
-|* This file is important because different host OS's define different macros,*|
-|* which makes portability tough. This file exports the following *|
-|* definitions: *|
-|* *|
-|* [u]int(32|64)_t : typedefs for signed and unsigned 32/64 bit system types*|
-|* [U]INT(8|16|32|64)_(MIN|MAX) : Constants for the min and max values. *|
-|* *|
-|* No library is required when using these functions. *|
-|* *|
-|*===----------------------------------------------------------------------===*/
-
-/* Please leave this file C-compatible. */
-
-#ifndef SUPPORT_DATATYPES_H
-#define SUPPORT_DATATYPES_H
-
-#undef HAVE_SYS_TYPES_H
-#undef HAVE_INTTYPES_H
-#undef HAVE_STDINT_H
-#undef HAVE_UINT64_T
-#undef HAVE_U_INT64_T
-
-#ifdef __cplusplus
-#include <cmath>
-#else
-#include <math.h>
-#endif
-
-/* Note that this header's correct operation depends on __STDC_LIMIT_MACROS
- being defined. We would define it here, but in order to prevent Bad Things
- happening when system headers or C++ STL headers include stdint.h before we
- define it here, we define it on the g++ command line (in Makefile.rules). */
-#if !defined(__STDC_LIMIT_MACROS)
-# error "Must #define __STDC_LIMIT_MACROS before #including System/DataTypes.h"
-#endif
-
-#if !defined(__STDC_CONSTANT_MACROS)
-# error "Must #define __STDC_CONSTANT_MACROS before " \
- "#including System/DataTypes.h"
-#endif
-
-/* Note that <inttypes.h> includes <stdint.h>, if this is a C99 system. */
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
-
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-
-#ifdef _AIX
-#include "llvm/System/AIXDataTypesFix.h"
-#endif
-
-/* Handle incorrect definition of uint64_t as u_int64_t */
-#ifndef HAVE_UINT64_T
-#ifdef HAVE_U_INT64_T
-typedef u_int64_t uint64_t;
-#else
-# error "Don't have a definition for uint64_t on this platform"
-#endif
-#endif
-
-#ifdef _OpenBSD_
-#define INT8_MAX 127
-#define INT8_MIN -128
-#define UINT8_MAX 255
-#define INT16_MAX 32767
-#define INT16_MIN -32768
-#define UINT16_MAX 65535
-#define INT32_MAX 2147483647
-#define INT32_MIN -2147483648
-#define UINT32_MAX 4294967295U
-#endif
-
-/* Set defaults for constants which we cannot find. */
-#if !defined(INT64_MAX)
-# define INT64_MAX 9223372036854775807LL
-#endif
-#if !defined(INT64_MIN)
-# define INT64_MIN ((-INT64_MAX)-1)
-#endif
-#if !defined(UINT64_MAX)
-# define UINT64_MAX 0xffffffffffffffffULL
-#endif
-
-#if __GNUC__ > 3
-#define END_WITH_NULL __attribute__((sentinel))
-#else
-#define END_WITH_NULL
-#endif
-
-#ifndef HUGE_VALF
-#define HUGE_VALF (float)HUGE_VAL
-#endif
-
-#endif /* SUPPORT_DATATYPES_H */
+++ /dev/null
-//===- llvm/Support/Disassembler.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 implements the necessary glue to call external disassembler
-// libraries.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SYSTEM_DISASSEMBLER_H
-#define LLVM_SYSTEM_DISASSEMBLER_H
-
-#include "llvm/System/DataTypes.h"
-#include <string>
-
-namespace llvm {
-namespace sys {
-
-/// This function returns true, if there is possible to use some external
-/// disassembler library. False otherwise.
-bool hasDisassembler();
-
-/// This function provides some "glue" code to call external disassembler
-/// libraries.
-std::string disassembleBuffer(uint8_t* start, size_t length, uint64_t pc = 0);
-
-}
-}
-
-#endif // LLVM_SYSTEM_DISASSEMBLER_H
+++ /dev/null
-//===-- llvm/System/DynamicLibrary.h - Portable Dynamic Library -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares the sys::DynamicLibrary class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SYSTEM_DYNAMIC_LIBRARY_H
-#define LLVM_SYSTEM_DYNAMIC_LIBRARY_H
-
-#include <string>
-
-namespace llvm {
-namespace sys {
-
- /// This class provides a portable interface to dynamic libraries which also
- /// might be known as shared libraries, shared objects, dynamic shared
- /// objects, or dynamic link libraries. Regardless of the terminology or the
- /// operating system interface, this class provides a portable interface that
- /// allows dynamic libraries to be loaded and searched for externally
- /// defined symbols. This is typically used to provide "plug-in" support.
- /// It also allows for symbols to be defined which don't live in any library,
- /// but rather the main program itself, useful on Windows where the main
- /// executable cannot be searched.
- class DynamicLibrary {
- DynamicLibrary(); // DO NOT IMPLEMENT
- public:
- /// This function allows a library to be loaded without instantiating a
- /// DynamicLibrary object. Consequently, it is marked as being permanent
- /// and will only be unloaded when the program terminates. This returns
- /// false on success or returns true and fills in *ErrMsg on failure.
- /// @brief Open a dynamic library permanently.
- ///
- /// NOTE: This function is not thread safe.
- ///
- static bool LoadLibraryPermanently(const char *filename,
- std::string *ErrMsg = 0);
-
- /// This function will search through all previously loaded dynamic
- /// libraries for the symbol \p symbolName. If it is found, the addressof
- /// that symbol is returned. If not, null is returned. Note that this will
- /// search permanently loaded libraries (LoadLibraryPermanently) as well
- /// as ephemerally loaded libraries (constructors).
- /// @throws std::string on error.
- /// @brief Search through libraries for address of a symbol
- ///
- /// NOTE: This function is not thread safe.
- ///
- static void *SearchForAddressOfSymbol(const char *symbolName);
-
- /// @brief Convenience function for C++ophiles.
- ///
- /// NOTE: This function is not thread safe.
- ///
- static void *SearchForAddressOfSymbol(const std::string &symbolName) {
- return SearchForAddressOfSymbol(symbolName.c_str());
- }
-
- /// This functions permanently adds the symbol \p symbolName with the
- /// value \p symbolValue. These symbols are searched before any
- /// libraries.
- /// @brief Add searchable symbol/value pair.
- ///
- /// NOTE: This function is not thread safe.
- ///
- static void AddSymbol(const char *symbolName, void *symbolValue);
-
- /// @brief Convenience function for C++ophiles.
- ///
- /// NOTE: This function is not thread safe.
- ///
- static void AddSymbol(const std::string &symbolName, void *symbolValue) {
- AddSymbol(symbolName.c_str(), symbolValue);
- }
- };
-
-} // End sys namespace
-} // End llvm namespace
-
-#endif // LLVM_SYSTEM_DYNAMIC_LIBRARY_H
+++ /dev/null
-//===- llvm/System/Errno.h - Portable+convenient errno handling -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares some portable and convenient functions to deal with errno.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SYSTEM_ERRNO_H
-#define LLVM_SYSTEM_ERRNO_H
-
-#include <string>
-
-namespace llvm {
-namespace sys {
-
-/// Returns a string representation of the errno value, using whatever
-/// thread-safe variant of strerror() is available. Be sure to call this
-/// immediately after the function that set errno, or errno may have been
-/// overwritten by an intervening call.
-std::string StrError();
-
-/// Like the no-argument version above, but uses \p errnum instead of errno.
-std::string StrError(int errnum);
-
-} // namespace sys
-} // namespace llvm
-
-#endif // LLVM_SYSTEM_ERRNO_H
+++ /dev/null
-//===- llvm/System/FEnv.h - Host floating-point exceptions ------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides an operating system independent interface to
-// floating-point exception interfaces.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SYSTEM_FENV_H
-#define LLVM_SYSTEM_FENV_H
-
-#include "llvm/Config/config.h"
-#include <cerrno>
-#ifdef HAVE_FENV_H
-#include <fenv.h>
-#endif
-
-// FIXME: Clang's #include handling apparently doesn't work for libstdc++'s
-// fenv.h; see PR6907 for details.
-#if defined(__clang__) && defined(_GLIBCXX_FENV_H)
-#undef HAVE_FENV_H
-#endif
-
-namespace llvm {
-namespace sys {
-
-/// llvm_fenv_clearexcept - Clear the floating-point exception state.
-static inline void llvm_fenv_clearexcept() {
-#ifdef HAVE_FENV_H
- feclearexcept(FE_ALL_EXCEPT);
-#endif
- errno = 0;
-}
-
-/// llvm_fenv_testexcept - Test if a floating-point exception was raised.
-static inline bool llvm_fenv_testexcept() {
- int errno_val = errno;
- if (errno_val == ERANGE || errno_val == EDOM)
- return true;
-#ifdef HAVE_FENV_H
- if (fetestexcept(FE_ALL_EXCEPT & ~FE_INEXACT))
- return true;
-#endif
- return false;
-}
-
-} // End sys namespace
-} // End llvm namespace
-
-#endif
+++ /dev/null
-//===- llvm/System/Host.h - Host machine characteristics --------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Methods for querying the nature of the host machine.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SYSTEM_HOST_H
-#define LLVM_SYSTEM_HOST_H
-
-#include "llvm/ADT/StringMap.h"
-#include <string>
-
-namespace llvm {
-namespace sys {
-
- inline bool isLittleEndianHost() {
- union {
- int i;
- char c;
- };
- i = 1;
- return c;
- }
-
- inline bool isBigEndianHost() {
- return !isLittleEndianHost();
- }
-
- /// getHostTriple() - Return the target triple of the running
- /// system.
- ///
- /// The target triple is a string in the format of:
- /// CPU_TYPE-VENDOR-OPERATING_SYSTEM
- /// or
- /// CPU_TYPE-VENDOR-KERNEL-OPERATING_SYSTEM
- std::string getHostTriple();
-
- /// getHostCPUName - Get the LLVM name for the host CPU. The particular format
- /// of the name is target dependent, and suitable for passing as -mcpu to the
- /// target which matches the host.
- ///
- /// \return - The host CPU name, or empty if the CPU could not be determined.
- std::string getHostCPUName();
-
- /// getHostCPUFeatures - Get the LLVM names for the host CPU features.
- /// The particular format of the names are target dependent, and suitable for
- /// passing as -mattr to the target which matches the host.
- ///
- /// \param Features - A string mapping feature names to either
- /// true (if enabled) or false (if disabled). This routine makes no guarantees
- /// about exactly which features may appear in this map, except that they are
- /// all valid LLVM feature names.
- ///
- /// \return - True on success.
- bool getHostCPUFeatures(StringMap<bool> &Features);
-}
-}
-
-#endif
+++ /dev/null
-//===- llvm/System/IncludeFile.h - Ensure Linking Of Library ---*- 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 FORCE_DEFINING_FILE_TO_BE_LINKED and DEFINE_FILE_FOR
-// macros.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SYSTEM_INCLUDEFILE_H
-#define LLVM_SYSTEM_INCLUDEFILE_H
-
-/// This macro is the public interface that IncludeFile.h exports. This gives
-/// us the option to implement the "link the definition" capability in any
-/// manner that we choose. All header files that depend on a specific .cpp
-/// file being linked at run time should use this macro instead of the
-/// IncludeFile class directly.
-///
-/// For example, foo.h would use:<br/>
-/// <tt>FORCE_DEFINING_FILE_TO_BE_LINKED(foo)</tt><br/>
-///
-/// And, foo.cp would use:<br/>
-/// <tt>DEFINING_FILE_FOR(foo)</tt><br/>
-#ifdef __GNUC__
-// If the `used' attribute is available, use it to create a variable
-// with an initializer that will force the linking of the defining file.
-#define FORCE_DEFINING_FILE_TO_BE_LINKED(name) \
- namespace llvm { \
- extern const char name ## LinkVar; \
- __attribute__((used)) static const char *const name ## LinkObj = \
- &name ## LinkVar; \
- }
-#else
-// Otherwise use a constructor call.
-#define FORCE_DEFINING_FILE_TO_BE_LINKED(name) \
- namespace llvm { \
- extern const char name ## LinkVar; \
- static const IncludeFile name ## LinkObj ( &name ## LinkVar ); \
- }
-#endif
-
-/// This macro is the counterpart to FORCE_DEFINING_FILE_TO_BE_LINKED. It should
-/// be used in a .cpp file to define the name referenced in a header file that
-/// will cause linkage of the .cpp file. It should only be used at extern level.
-#define DEFINING_FILE_FOR(name) \
- namespace llvm { const char name ## LinkVar = 0; }
-
-namespace llvm {
-
-/// This class is used in the implementation of FORCE_DEFINING_FILE_TO_BE_LINKED
-/// macro to make sure that the implementation of a header file is included
-/// into a tool that uses the header. This is solely
-/// to overcome problems linking .a files and not getting the implementation
-/// of compilation units we need. This is commonly an issue with the various
-/// Passes but also occurs elsewhere in LLVM. We like to use .a files because
-/// they link faster and provide the smallest executables. However, sometimes
-/// those executables are too small, if the program doesn't reference something
-/// that might be needed, especially by a loaded share object. This little class
-/// helps to resolve that problem. The basic strategy is to use this class in
-/// a header file and pass the address of a variable to the constructor. If the
-/// variable is defined in the header file's corresponding .cpp file then all
-/// tools/libraries that \#include the header file will require the .cpp as
-/// well.
-/// For example:<br/>
-/// <tt>extern int LinkMyCodeStub;</tt><br/>
-/// <tt>static IncludeFile LinkMyModule(&LinkMyCodeStub);</tt><br/>
-/// @brief Class to ensure linking of corresponding object file.
-struct IncludeFile {
- explicit IncludeFile(const void *);
-};
-
-}
-
-#endif
+++ /dev/null
-LLVM System Interface Library
--------------------------------------------------------------------------------
-The LLVM System Interface Library is licensed under the Illinois Open Source
-License and has the following additional copyright:
-
-Copyright (C) 2004 eXtensible Systems, Inc.
+++ /dev/null
-//===- llvm/System/Memory.h - Memory Support --------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares the llvm::sys::Memory class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SYSTEM_MEMORY_H
-#define LLVM_SYSTEM_MEMORY_H
-
-#include "llvm/System/DataTypes.h"
-#include <string>
-
-namespace llvm {
-namespace sys {
-
- /// This class encapsulates the notion of a memory block which has an address
- /// and a size. It is used by the Memory class (a friend) as the result of
- /// various memory allocation operations.
- /// @see Memory
- /// @brief Memory block abstraction.
- class MemoryBlock {
- public:
- MemoryBlock() : Address(0), Size(0) { }
- MemoryBlock(void *addr, size_t size) : Address(addr), Size(size) { }
- void *base() const { return Address; }
- size_t size() const { return Size; }
- private:
- void *Address; ///< Address of first byte of memory area
- size_t Size; ///< Size, in bytes of the memory area
- friend class Memory;
- };
-
- /// This class provides various memory handling functions that manipulate
- /// MemoryBlock instances.
- /// @since 1.4
- /// @brief An abstraction for memory operations.
- class Memory {
- public:
- /// This method allocates a block of Read/Write/Execute memory that is
- /// suitable for executing dynamically generated code (e.g. JIT). An
- /// attempt to allocate \p NumBytes bytes of virtual memory is made.
- /// \p NearBlock may point to an existing allocation in which case
- /// an attempt is made to allocate more memory near the existing block.
- ///
- /// On success, this returns a non-null memory block, otherwise it returns
- /// a null memory block and fills in *ErrMsg.
- ///
- /// @brief Allocate Read/Write/Execute memory.
- static MemoryBlock AllocateRWX(size_t NumBytes,
- const MemoryBlock *NearBlock,
- std::string *ErrMsg = 0);
-
- /// This method releases a block of Read/Write/Execute memory that was
- /// allocated with the AllocateRWX method. It should not be used to
- /// release any memory block allocated any other way.
- ///
- /// On success, this returns false, otherwise it returns true and fills
- /// in *ErrMsg.
- /// @brief Release Read/Write/Execute memory.
- static bool ReleaseRWX(MemoryBlock &block, std::string *ErrMsg = 0);
-
-
- /// InvalidateInstructionCache - Before the JIT can run a block of code
- /// that has been emitted it must invalidate the instruction cache on some
- /// platforms.
- static void InvalidateInstructionCache(const void *Addr, size_t Len);
-
- /// setExecutable - Before the JIT can run a block of code, it has to be
- /// given read and executable privilege. Return true if it is already r-x
- /// or the system is able to change its previlege.
- static bool setExecutable (MemoryBlock &M, std::string *ErrMsg = 0);
-
- /// setWritable - When adding to a block of code, the JIT may need
- /// to mark a block of code as RW since the protections are on page
- /// boundaries, and the JIT internal allocations are not page aligned.
- static bool setWritable (MemoryBlock &M, std::string *ErrMsg = 0);
-
- /// setRangeExecutable - Mark the page containing a range of addresses
- /// as executable.
- static bool setRangeExecutable(const void *Addr, size_t Size);
-
- /// setRangeWritable - Mark the page containing a range of addresses
- /// as writable.
- static bool setRangeWritable(const void *Addr, size_t Size);
- };
-}
-}
-
-#endif
+++ /dev/null
-//===- llvm/System/Mutex.h - Mutex Operating System Concept -----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares the llvm::sys::Mutex class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SYSTEM_MUTEX_H
-#define LLVM_SYSTEM_MUTEX_H
-
-#include "llvm/System/Threading.h"
-#include <cassert>
-
-namespace llvm
-{
- namespace sys
- {
- /// @brief Platform agnostic Mutex class.
- class MutexImpl
- {
- /// @name Constructors
- /// @{
- public:
-
- /// Initializes the lock but doesn't acquire it. if \p recursive is set
- /// to false, the lock will not be recursive which makes it cheaper but
- /// also more likely to deadlock (same thread can't acquire more than
- /// once).
- /// @brief Default Constructor.
- explicit MutexImpl(bool recursive = true);
-
- /// Releases and removes the lock
- /// @brief Destructor
- ~MutexImpl();
-
- /// @}
- /// @name Methods
- /// @{
- public:
-
- /// Attempts to unconditionally acquire the lock. If the lock is held by
- /// another thread, this method will wait until it can acquire the lock.
- /// @returns false if any kind of error occurs, true otherwise.
- /// @brief Unconditionally acquire the lock.
- bool acquire();
-
- /// Attempts to release the lock. If the lock is held by the current
- /// thread, the lock is released allowing other threads to acquire the
- /// lock.
- /// @returns false if any kind of error occurs, true otherwise.
- /// @brief Unconditionally release the lock.
- bool release();
-
- /// Attempts to acquire the lock without blocking. If the lock is not
- /// available, this function returns false quickly (without blocking). If
- /// the lock is available, it is acquired.
- /// @returns false if any kind of error occurs or the lock is not
- /// available, true otherwise.
- /// @brief Try to acquire the lock.
- bool tryacquire();
-
- //@}
- /// @name Platform Dependent Data
- /// @{
- private:
- void* data_; ///< We don't know what the data will be
-
- /// @}
- /// @name Do Not Implement
- /// @{
- private:
- MutexImpl(const MutexImpl & original);
- void operator=(const MutexImpl &);
- /// @}
- };
-
-
- /// SmartMutex - A mutex with a compile time constant parameter that
- /// indicates whether this mutex should become a no-op when we're not
- /// running in multithreaded mode.
- template<bool mt_only>
- class SmartMutex : public MutexImpl {
- unsigned acquired;
- bool recursive;
- public:
- explicit SmartMutex(bool rec = true) :
- MutexImpl(rec), acquired(0), recursive(rec) { }
-
- bool acquire() {
- if (!mt_only || llvm_is_multithreaded()) {
- return MutexImpl::acquire();
- } else {
- // Single-threaded debugging code. This would be racy in
- // multithreaded mode, but provides not sanity checks in single
- // threaded mode.
- assert((recursive || acquired == 0) && "Lock already acquired!!");
- ++acquired;
- return true;
- }
- }
-
- bool release() {
- if (!mt_only || llvm_is_multithreaded()) {
- return MutexImpl::release();
- } else {
- // Single-threaded debugging code. This would be racy in
- // multithreaded mode, but provides not sanity checks in single
- // threaded mode.
- assert(((recursive && acquired) || (acquired == 1)) &&
- "Lock not acquired before release!");
- --acquired;
- return true;
- }
- }
-
- bool tryacquire() {
- if (!mt_only || llvm_is_multithreaded())
- return MutexImpl::tryacquire();
- else return true;
- }
-
- private:
- SmartMutex(const SmartMutex<mt_only> & original);
- void operator=(const SmartMutex<mt_only> &);
- };
-
- /// Mutex - A standard, always enforced mutex.
- typedef SmartMutex<false> Mutex;
-
- template<bool mt_only>
- class SmartScopedLock {
- SmartMutex<mt_only>& mtx;
-
- public:
- SmartScopedLock(SmartMutex<mt_only>& m) : mtx(m) {
- mtx.acquire();
- }
-
- ~SmartScopedLock() {
- mtx.release();
- }
- };
-
- typedef SmartScopedLock<false> ScopedLock;
- }
-}
-
-#endif
+++ /dev/null
-//===- llvm/System/Path.h - Path Operating System Concept -------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares the llvm::sys::Path class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SYSTEM_PATH_H
-#define LLVM_SYSTEM_PATH_H
-
-#include "llvm/ADT/StringRef.h"
-#include "llvm/System/TimeValue.h"
-#include <set>
-#include <string>
-#include <vector>
-
-namespace llvm {
-namespace sys {
-
- /// This structure provides basic file system information about a file. It
- /// is patterned after the stat(2) Unix operating system call but made
- /// platform independent and eliminates many of the unix-specific fields.
- /// However, to support llvm-ar, the mode, user, and group fields are
- /// retained. These pertain to unix security and may not have a meaningful
- /// value on non-Unix platforms. However, the other fields should
- /// always be applicable on all platforms. The structure is filled in by
- /// the PathWithStatus class.
- /// @brief File status structure
- class FileStatus {
- public:
- uint64_t fileSize; ///< Size of the file in bytes
- TimeValue modTime; ///< Time of file's modification
- uint32_t mode; ///< Mode of the file, if applicable
- uint32_t user; ///< User ID of owner, if applicable
- uint32_t group; ///< Group ID of owner, if applicable
- uint64_t uniqueID; ///< A number to uniquely ID this file
- bool isDir : 1; ///< True if this is a directory.
- bool isFile : 1; ///< True if this is a file.
-
- FileStatus() : fileSize(0), modTime(0,0), mode(0777), user(999),
- group(999), uniqueID(0), isDir(false), isFile(false) { }
-
- TimeValue getTimestamp() const { return modTime; }
- uint64_t getSize() const { return fileSize; }
- uint32_t getMode() const { return mode; }
- uint32_t getUser() const { return user; }
- uint32_t getGroup() const { return group; }
- uint64_t getUniqueID() const { return uniqueID; }
- };
-
- /// This class provides an abstraction for the path to a file or directory
- /// in the operating system's filesystem and provides various basic operations
- /// on it. Note that this class only represents the name of a path to a file
- /// or directory which may or may not be valid for a given machine's file
- /// system. The class is patterned after the java.io.File class with various
- /// extensions and several omissions (not relevant to LLVM). A Path object
- /// ensures that the path it encapsulates is syntactically valid for the
- /// operating system it is running on but does not ensure correctness for
- /// any particular file system. That is, a syntactically valid path might
- /// specify path components that do not exist in the file system and using
- /// such a Path to act on the file system could produce errors. There is one
- /// invalid Path value which is permitted: the empty path. The class should
- /// never allow a syntactically invalid non-empty path name to be assigned.
- /// Empty paths are required in order to indicate an error result in some
- /// situations. If the path is empty, the isValid operation will return
- /// false. All operations will fail if isValid is false. Operations that
- /// change the path will either return false if it would cause a syntactically
- /// invalid path name (in which case the Path object is left unchanged) or
- /// throw an std::string exception indicating the error. The methods are
- /// grouped into four basic categories: Path Accessors (provide information
- /// about the path without accessing disk), Disk Accessors (provide
- /// information about the underlying file or directory), Path Mutators
- /// (change the path information, not the disk), and Disk Mutators (change
- /// the disk file/directory referenced by the path). The Disk Mutator methods
- /// all have the word "disk" embedded in their method name to reinforce the
- /// notion that the operation modifies the file system.
- /// @since 1.4
- /// @brief An abstraction for operating system paths.
- class Path {
- /// @name Constructors
- /// @{
- public:
- /// Construct a path to the root directory of the file system. The root
- /// directory is a top level directory above which there are no more
- /// directories. For example, on UNIX, the root directory is /. On Windows
- /// it is file:///. Other operating systems may have different notions of
- /// what the root directory is or none at all. In that case, a consistent
- /// default root directory will be used.
- static Path GetRootDirectory();
-
- /// Construct a path to a unique temporary directory that is created in
- /// a "standard" place for the operating system. The directory is
- /// guaranteed to be created on exit from this function. If the directory
- /// cannot be created, the function will throw an exception.
- /// @returns an invalid path (empty) on error
- /// @param ErrMsg Optional place for an error message if an error occurs
- /// @brief Constrct a path to an new, unique, existing temporary
- /// directory.
- static Path GetTemporaryDirectory(std::string* ErrMsg = 0);
-
- /// Construct a vector of sys::Path that contains the "standard" system
- /// library paths suitable for linking into programs.
- /// @brief Construct a path to the system library directory
- static void GetSystemLibraryPaths(std::vector<sys::Path>& Paths);
-
- /// Construct a vector of sys::Path that contains the "standard" bitcode
- /// library paths suitable for linking into an llvm program. This function
- /// *must* return the value of LLVM_LIB_SEARCH_PATH as well as the value
- /// of LLVM_LIBDIR. It also must provide the System library paths as
- /// returned by GetSystemLibraryPaths.
- /// @see GetSystemLibraryPaths
- /// @brief Construct a list of directories in which bitcode could be
- /// found.
- static void GetBitcodeLibraryPaths(std::vector<sys::Path>& Paths);
-
- /// Find the path to a library using its short name. Use the system
- /// dependent library paths to locate the library.
- /// @brief Find a library.
- static Path FindLibrary(std::string& short_name);
-
- /// Construct a path to the default LLVM configuration directory. The
- /// implementation must ensure that this is a well-known (same on many
- /// systems) directory in which llvm configuration files exist. For
- /// example, on Unix, the /etc/llvm directory has been selected.
- /// @brief Construct a path to the default LLVM configuration directory
- static Path GetLLVMDefaultConfigDir();
-
- /// Construct a path to the LLVM installed configuration directory. The
- /// implementation must ensure that this refers to the "etc" directory of
- /// the LLVM installation. This is the location where configuration files
- /// will be located for a particular installation of LLVM on a machine.
- /// @brief Construct a path to the LLVM installed configuration directory
- static Path GetLLVMConfigDir();
-
- /// Construct a path to the current user's home directory. The
- /// implementation must use an operating system specific mechanism for
- /// determining the user's home directory. For example, the environment
- /// variable "HOME" could be used on Unix. If a given operating system
- /// does not have the concept of a user's home directory, this static
- /// constructor must provide the same result as GetRootDirectory.
- /// @brief Construct a path to the current user's "home" directory
- static Path GetUserHomeDirectory();
-
- /// Construct a path to the current directory for the current process.
- /// @returns The current working directory.
- /// @brief Returns the current working directory.
- static Path GetCurrentDirectory();
-
- /// Return the suffix commonly used on file names that contain an
- /// executable.
- /// @returns The executable file suffix for the current platform.
- /// @brief Return the executable file suffix.
- static StringRef GetEXESuffix();
-
- /// Return the suffix commonly used on file names that contain a shared
- /// object, shared archive, or dynamic link library. Such files are
- /// linked at runtime into a process and their code images are shared
- /// between processes.
- /// @returns The dynamic link library suffix for the current platform.
- /// @brief Return the dynamic link library suffix.
- static StringRef GetDLLSuffix();
-
- /// GetMainExecutable - Return the path to the main executable, given the
- /// value of argv[0] from program startup and the address of main itself.
- /// In extremis, this function may fail and return an empty path.
- static Path GetMainExecutable(const char *argv0, void *MainAddr);
-
- /// This is one of the very few ways in which a path can be constructed
- /// with a syntactically invalid name. The only *legal* invalid name is an
- /// empty one. Other invalid names are not permitted. Empty paths are
- /// provided so that they can be used to indicate null or error results in
- /// other lib/System functionality.
- /// @brief Construct an empty (and invalid) path.
- Path() : path() {}
- Path(const Path &that) : path(that.path) {}
-
- /// This constructor will accept a char* or std::string as a path. No
- /// checking is done on this path to determine if it is valid. To
- /// determine validity of the path, use the isValid method.
- /// @param p The path to assign.
- /// @brief Construct a Path from a string.
- explicit Path(StringRef p);
-
- /// This constructor will accept a character range as a path. No checking
- /// is done on this path to determine if it is valid. To determine
- /// validity of the path, use the isValid method.
- /// @param StrStart A pointer to the first character of the path name
- /// @param StrLen The length of the path name at StrStart
- /// @brief Construct a Path from a string.
- Path(const char *StrStart, unsigned StrLen);
-
- /// @}
- /// @name Operators
- /// @{
- public:
- /// Makes a copy of \p that to \p this.
- /// @returns \p this
- /// @brief Assignment Operator
- Path &operator=(const Path &that) {
- path = that.path;
- return *this;
- }
-
- /// Makes a copy of \p that to \p this.
- /// @param that A StringRef denoting the path
- /// @returns \p this
- /// @brief Assignment Operator
- Path &operator=(StringRef that);
-
- /// Compares \p this Path with \p that Path for equality.
- /// @returns true if \p this and \p that refer to the same thing.
- /// @brief Equality Operator
- bool operator==(const Path &that) const;
-
- /// Compares \p this Path with \p that Path for inequality.
- /// @returns true if \p this and \p that refer to different things.
- /// @brief Inequality Operator
- bool operator!=(const Path &that) const { return !(*this == that); }
-
- /// Determines if \p this Path is less than \p that Path. This is required
- /// so that Path objects can be placed into ordered collections (e.g.
- /// std::map). The comparison is done lexicographically as defined by
- /// the std::string::compare method.
- /// @returns true if \p this path is lexicographically less than \p that.
- /// @brief Less Than Operator
- bool operator<(const Path& that) const;
-
- /// @}
- /// @name Path Accessors
- /// @{
- public:
- /// This function will use an operating system specific algorithm to
- /// determine if the current value of \p this is a syntactically valid
- /// path name for the operating system. The path name does not need to
- /// exist, validity is simply syntactical. Empty paths are always invalid.
- /// @returns true iff the path name is syntactically legal for the
- /// host operating system.
- /// @brief Determine if a path is syntactically valid or not.
- bool isValid() const;
-
- /// This function determines if the contents of the path name are empty.
- /// That is, the path name has a zero length. This does NOT determine if
- /// if the file is empty. To get the length of the file itself, Use the
- /// PathWithStatus::getFileStatus() method and then the getSize() method
- /// on the returned FileStatus object.
- /// @returns true iff the path is empty.
- /// @brief Determines if the path name is empty (invalid).
- bool isEmpty() const { return path.empty(); }
-
- /// This function returns the last component of the path name. The last
- /// component is the file or directory name occuring after the last
- /// directory separator. If no directory separator is present, the entire
- /// path name is returned (i.e. same as toString).
- /// @returns StringRef containing the last component of the path name.
- /// @brief Returns the last component of the path name.
- StringRef getLast() const;
-
- /// This function strips off the path and suffix of the file or directory
- /// name and returns just the basename. For example /a/foo.bar would cause
- /// this function to return "foo".
- /// @returns StringRef containing the basename of the path
- /// @brief Get the base name of the path
- StringRef getBasename() const;
-
- /// This function strips off the suffix of the path beginning with the
- /// path separator ('/' on Unix, '\' on Windows) and returns the result.
- StringRef getDirname() const;
-
- /// This function strips off the path and basename(up to and
- /// including the last dot) of the file or directory name and
- /// returns just the suffix. For example /a/foo.bar would cause
- /// this function to return "bar".
- /// @returns StringRef containing the suffix of the path
- /// @brief Get the suffix of the path
- StringRef getSuffix() const;
-
- /// Obtain a 'C' string for the path name.
- /// @returns a 'C' string containing the path name.
- /// @brief Returns the path as a C string.
- const char *c_str() const { return path.c_str(); }
- const std::string &str() const { return path; }
-
-
- /// size - Return the length in bytes of this path name.
- size_t size() const { return path.size(); }
-
- /// empty - Returns true if the path is empty.
- unsigned empty() const { return path.empty(); }
-
- /// @}
- /// @name Disk Accessors
- /// @{
- public:
- /// This function determines if the path name is absolute, as opposed to
- /// relative.
- /// @brief Determine if the path is absolute.
- bool isAbsolute() const;
-
- /// This function determines if the path name is absolute, as opposed to
- /// relative.
- /// @brief Determine if the path is absolute.
- static bool isAbsolute(const char *NameStart, unsigned NameLen);
-
- /// This function opens the file associated with the path name provided by
- /// the Path object and reads its magic number. If the magic number at the
- /// start of the file matches \p magic, true is returned. In all other
- /// cases (file not found, file not accessible, etc.) it returns false.
- /// @returns true if the magic number of the file matches \p magic.
- /// @brief Determine if file has a specific magic number
- bool hasMagicNumber(StringRef magic) const;
-
- /// This function retrieves the first \p len bytes of the file associated
- /// with \p this. These bytes are returned as the "magic number" in the
- /// \p Magic parameter.
- /// @returns true if the Path is a file and the magic number is retrieved,
- /// false otherwise.
- /// @brief Get the file's magic number.
- bool getMagicNumber(std::string& Magic, unsigned len) const;
-
- /// This function determines if the path name in the object references an
- /// archive file by looking at its magic number.
- /// @returns true if the file starts with the magic number for an archive
- /// file.
- /// @brief Determine if the path references an archive file.
- bool isArchive() const;
-
- /// This function determines if the path name in the object references an
- /// LLVM Bitcode file by looking at its magic number.
- /// @returns true if the file starts with the magic number for LLVM
- /// bitcode files.
- /// @brief Determine if the path references a bitcode file.
- bool isBitcodeFile() const;
-
- /// This function determines if the path name in the object references a
- /// native Dynamic Library (shared library, shared object) by looking at
- /// the file's magic number. The Path object must reference a file, not a
- /// directory.
- /// @returns true if the file starts with the magic number for a native
- /// shared library.
- /// @brief Determine if the path references a dynamic library.
- bool isDynamicLibrary() const;
-
- /// This function determines if the path name in the object references a
- /// native object file by looking at it's magic number. The term object
- /// file is defined as "an organized collection of separate, named
- /// sequences of binary data." This covers the obvious file formats such
- /// as COFF and ELF, but it also includes llvm ir bitcode, archives,
- /// libraries, etc...
- /// @returns true if the file starts with the magic number for an object
- /// file.
- /// @brief Determine if the path references an object file.
- bool isObjectFile() const;
-
- /// This function determines if the path name references an existing file
- /// or directory in the file system.
- /// @returns true if the pathname references an existing file or
- /// directory.
- /// @brief Determines if the path is a file or directory in
- /// the file system.
- bool exists() const;
-
- /// This function determines if the path name references an
- /// existing directory.
- /// @returns true if the pathname references an existing directory.
- /// @brief Determines if the path is a directory in the file system.
- bool isDirectory() const;
-
- /// This function determines if the path name references an
- /// existing symbolic link.
- /// @returns true if the pathname references an existing symlink.
- /// @brief Determines if the path is a symlink in the file system.
- bool isSymLink() const;
-
- /// This function determines if the path name references a readable file
- /// or directory in the file system. This function checks for
- /// the existence and readability (by the current program) of the file
- /// or directory.
- /// @returns true if the pathname references a readable file.
- /// @brief Determines if the path is a readable file or directory
- /// in the file system.
- bool canRead() const;
-
- /// This function determines if the path name references a writable file
- /// or directory in the file system. This function checks for the
- /// existence and writability (by the current program) of the file or
- /// directory.
- /// @returns true if the pathname references a writable file.
- /// @brief Determines if the path is a writable file or directory
- /// in the file system.
- bool canWrite() const;
-
- /// This function checks that what we're trying to work only on a regular
- /// file. Check for things like /dev/null, any block special file, or
- /// other things that aren't "regular" regular files.
- /// @returns true if the file is S_ISREG.
- /// @brief Determines if the file is a regular file
- bool isRegularFile() const;
-
- /// This function determines if the path name references an executable
- /// file in the file system. This function checks for the existence and
- /// executability (by the current program) of the file.
- /// @returns true if the pathname references an executable file.
- /// @brief Determines if the path is an executable file in the file
- /// system.
- bool canExecute() const;
-
- /// This function builds a list of paths that are the names of the
- /// files and directories in a directory.
- /// @returns true if an error occurs, true otherwise
- /// @brief Build a list of directory's contents.
- bool getDirectoryContents(
- std::set<Path> &paths, ///< The resulting list of file & directory names
- std::string* ErrMsg ///< Optional place to return an error message.
- ) const;
-
- /// @}
- /// @name Path Mutators
- /// @{
- public:
- /// The path name is cleared and becomes empty. This is an invalid
- /// path name but is the *only* invalid path name. This is provided
- /// so that path objects can be used to indicate the lack of a
- /// valid path being found.
- /// @brief Make the path empty.
- void clear() { path.clear(); }
-
- /// This method sets the Path object to \p unverified_path. This can fail
- /// if the \p unverified_path does not pass the syntactic checks of the
- /// isValid() method. If verification fails, the Path object remains
- /// unchanged and false is returned. Otherwise true is returned and the
- /// Path object takes on the path value of \p unverified_path
- /// @returns true if the path was set, false otherwise.
- /// @param unverified_path The path to be set in Path object.
- /// @brief Set a full path from a StringRef
- bool set(StringRef unverified_path);
-
- /// One path component is removed from the Path. If only one component is
- /// present in the path, the Path object becomes empty. If the Path object
- /// is empty, no change is made.
- /// @returns false if the path component could not be removed.
- /// @brief Removes the last directory component of the Path.
- bool eraseComponent();
-
- /// The \p component is added to the end of the Path if it is a legal
- /// name for the operating system. A directory separator will be added if
- /// needed.
- /// @returns false if the path component could not be added.
- /// @brief Appends one path component to the Path.
- bool appendComponent(StringRef component);
-
- /// A period and the \p suffix are appended to the end of the pathname.
- /// The precondition for this function is that the Path reference a file
- /// name (i.e. isFile() returns true). If the Path is not a file, no
- /// action is taken and the function returns false. If the path would
- /// become invalid for the host operating system, false is returned. When
- /// the \p suffix is empty, no action is performed.
- /// @returns false if the suffix could not be added, true if it was.
- /// @brief Adds a period and the \p suffix to the end of the pathname.
- bool appendSuffix(StringRef suffix);
-
- /// The suffix of the filename is erased. The suffix begins with and
- /// includes the last . character in the filename after the last directory
- /// separator and extends until the end of the name. If no . character is
- /// after the last directory separator, then the file name is left
- /// unchanged (i.e. it was already without a suffix) but the function
- /// returns false.
- /// @returns false if there was no suffix to remove, true otherwise.
- /// @brief Remove the suffix from a path name.
- bool eraseSuffix();
-
- /// The current Path name is made unique in the file system. Upon return,
- /// the Path will have been changed to make a unique file in the file
- /// system or it will not have been changed if the current path name is
- /// already unique.
- /// @throws std::string if an unrecoverable error occurs.
- /// @brief Make the current path name unique in the file system.
- bool makeUnique( bool reuse_current /*= true*/, std::string* ErrMsg );
-
- /// The current Path name is made absolute by prepending the
- /// current working directory if necessary.
- void makeAbsolute();
-
- /// @}
- /// @name Disk Mutators
- /// @{
- public:
- /// This method attempts to make the file referenced by the Path object
- /// available for reading so that the canRead() method will return true.
- /// @brief Make the file readable;
- bool makeReadableOnDisk(std::string* ErrMsg = 0);
-
- /// This method attempts to make the file referenced by the Path object
- /// available for writing so that the canWrite() method will return true.
- /// @brief Make the file writable;
- bool makeWriteableOnDisk(std::string* ErrMsg = 0);
-
- /// This method attempts to make the file referenced by the Path object
- /// available for execution so that the canExecute() method will return
- /// true.
- /// @brief Make the file readable;
- bool makeExecutableOnDisk(std::string* ErrMsg = 0);
-
- /// This method allows the last modified time stamp and permission bits
- /// to be set on the disk object referenced by the Path.
- /// @throws std::string if an error occurs.
- /// @returns true on error.
- /// @brief Set the status information.
- bool setStatusInfoOnDisk(const FileStatus &SI,
- std::string *ErrStr = 0) const;
-
- /// This method attempts to create a directory in the file system with the
- /// same name as the Path object. The \p create_parents parameter controls
- /// whether intermediate directories are created or not. if \p
- /// create_parents is true, then an attempt will be made to create all
- /// intermediate directories, as needed. If \p create_parents is false,
- /// then only the final directory component of the Path name will be
- /// created. The created directory will have no entries.
- /// @returns true if the directory could not be created, false otherwise
- /// @brief Create the directory this Path refers to.
- bool createDirectoryOnDisk(
- bool create_parents = false, ///< Determines whether non-existent
- ///< directory components other than the last one (the "parents")
- ///< are created or not.
- std::string* ErrMsg = 0 ///< Optional place to put error messages.
- );
-
- /// This method attempts to create a file in the file system with the same
- /// name as the Path object. The intermediate directories must all exist
- /// at the time this method is called. Use createDirectoriesOnDisk to
- /// accomplish that. The created file will be empty upon return from this
- /// function.
- /// @returns true if the file could not be created, false otherwise.
- /// @brief Create the file this Path refers to.
- bool createFileOnDisk(
- std::string* ErrMsg = 0 ///< Optional place to put error messages.
- );
-
- /// This is like createFile except that it creates a temporary file. A
- /// unique temporary file name is generated based on the contents of
- /// \p this before the call. The new name is assigned to \p this and the
- /// file is created. Note that this will both change the Path object
- /// *and* create the corresponding file. This function will ensure that
- /// the newly generated temporary file name is unique in the file system.
- /// @returns true if the file couldn't be created, false otherwise.
- /// @brief Create a unique temporary file
- bool createTemporaryFileOnDisk(
- bool reuse_current = false, ///< When set to true, this parameter
- ///< indicates that if the current file name does not exist then
- ///< it will be used without modification.
- std::string* ErrMsg = 0 ///< Optional place to put error messages
- );
-
- /// This method renames the file referenced by \p this as \p newName. The
- /// file referenced by \p this must exist. The file referenced by
- /// \p newName does not need to exist.
- /// @returns true on error, false otherwise
- /// @brief Rename one file as another.
- bool renamePathOnDisk(const Path& newName, std::string* ErrMsg);
-
- /// This method attempts to destroy the file or directory named by the
- /// last component of the Path. If the Path refers to a directory and the
- /// \p destroy_contents is false, an attempt will be made to remove just
- /// the directory (the final Path component). If \p destroy_contents is
- /// true, an attempt will be made to remove the entire contents of the
- /// directory, recursively. If the Path refers to a file, the
- /// \p destroy_contents parameter is ignored.
- /// @param destroy_contents Indicates whether the contents of a destroyed
- /// @param Err An optional string to receive an error message.
- /// directory should also be destroyed (recursively).
- /// @returns false if the file/directory was destroyed, true on error.
- /// @brief Removes the file or directory from the filesystem.
- bool eraseFromDisk(bool destroy_contents = false,
- std::string *Err = 0) const;
-
-
- /// MapInFilePages - This is a low level system API to map in the file
- /// that is currently opened as FD into the current processes' address
- /// space for read only access. This function may return null on failure
- /// or if the system cannot provide the following constraints:
- /// 1) The pages must be valid after the FD is closed, until
- /// UnMapFilePages is called.
- /// 2) Any padding after the end of the file must be zero filled, if
- /// present.
- /// 3) The pages must be contiguous.
- ///
- /// This API is not intended for general use, clients should use
- /// MemoryBuffer::getFile instead.
- static const char *MapInFilePages(int FD, uint64_t FileSize);
-
- /// UnMapFilePages - Free pages mapped into the current process by
- /// MapInFilePages.
- ///
- /// This API is not intended for general use, clients should use
- /// MemoryBuffer::getFile instead.
- static void UnMapFilePages(const char *Base, uint64_t FileSize);
-
- /// @}
- /// @name Data
- /// @{
- protected:
- // Our win32 implementation relies on this string being mutable.
- mutable std::string path; ///< Storage for the path name.
-
-
- /// @}
- };
-
- /// This class is identical to Path class except it allows you to obtain the
- /// file status of the Path as well. The reason for the distinction is one of
- /// efficiency. First, the file status requires additional space and the space
- /// is incorporated directly into PathWithStatus without an additional malloc.
- /// Second, obtaining status information is an expensive operation on most
- /// operating systems so we want to be careful and explicity about where we
- /// allow this operation in LLVM.
- /// @brief Path with file status class.
- class PathWithStatus : public Path {
- /// @name Constructors
- /// @{
- public:
- /// @brief Default constructor
- PathWithStatus() : Path(), status(), fsIsValid(false) {}
-
- /// @brief Copy constructor
- PathWithStatus(const PathWithStatus &that)
- : Path(static_cast<const Path&>(that)), status(that.status),
- fsIsValid(that.fsIsValid) {}
-
- /// This constructor allows construction from a Path object
- /// @brief Path constructor
- PathWithStatus(const Path &other)
- : Path(other), status(), fsIsValid(false) {}
-
- /// This constructor will accept a char* or std::string as a path. No
- /// checking is done on this path to determine if it is valid. To
- /// determine validity of the path, use the isValid method.
- /// @brief Construct a Path from a string.
- explicit PathWithStatus(
- StringRef p ///< The path to assign.
- ) : Path(p), status(), fsIsValid(false) {}
-
- /// This constructor will accept a character range as a path. No checking
- /// is done on this path to determine if it is valid. To determine
- /// validity of the path, use the isValid method.
- /// @brief Construct a Path from a string.
- explicit PathWithStatus(
- const char *StrStart, ///< Pointer to the first character of the path
- unsigned StrLen ///< Length of the path.
- ) : Path(StrStart, StrLen), status(), fsIsValid(false) {}
-
- /// Makes a copy of \p that to \p this.
- /// @returns \p this
- /// @brief Assignment Operator
- PathWithStatus &operator=(const PathWithStatus &that) {
- static_cast<Path&>(*this) = static_cast<const Path&>(that);
- status = that.status;
- fsIsValid = that.fsIsValid;
- return *this;
- }
-
- /// Makes a copy of \p that to \p this.
- /// @returns \p this
- /// @brief Assignment Operator
- PathWithStatus &operator=(const Path &that) {
- static_cast<Path&>(*this) = static_cast<const Path&>(that);
- fsIsValid = false;
- return *this;
- }
-
- /// @}
- /// @name Methods
- /// @{
- public:
- /// This function returns status information about the file. The type of
- /// path (file or directory) is updated to reflect the actual contents
- /// of the file system.
- /// @returns 0 on failure, with Error explaining why (if non-zero)
- /// @returns a pointer to a FileStatus structure on success.
- /// @brief Get file status.
- const FileStatus *getFileStatus(
- bool forceUpdate = false, ///< Force an update from the file system
- std::string *Error = 0 ///< Optional place to return an error msg.
- ) const;
-
- /// @}
- /// @name Data
- /// @{
- private:
- mutable FileStatus status; ///< Status information.
- mutable bool fsIsValid; ///< Whether we've obtained it or not
-
- /// @}
- };
-
- /// This enumeration delineates the kinds of files that LLVM knows about.
- enum LLVMFileType {
- Unknown_FileType = 0, ///< Unrecognized file
- Bitcode_FileType, ///< Bitcode file
- Archive_FileType, ///< ar style archive file
- ELF_Relocatable_FileType, ///< ELF Relocatable object file
- ELF_Executable_FileType, ///< ELF Executable image
- ELF_SharedObject_FileType, ///< ELF dynamically linked shared lib
- ELF_Core_FileType, ///< ELF core image
- Mach_O_Object_FileType, ///< Mach-O Object file
- Mach_O_Executable_FileType, ///< Mach-O Executable
- Mach_O_FixedVirtualMemorySharedLib_FileType, ///< Mach-O Shared Lib, FVM
- Mach_O_Core_FileType, ///< Mach-O Core File
- Mach_O_PreloadExecutable_FileType, ///< Mach-O Preloaded Executable
- Mach_O_DynamicallyLinkedSharedLib_FileType, ///< Mach-O dynlinked shared lib
- Mach_O_DynamicLinker_FileType, ///< The Mach-O dynamic linker
- Mach_O_Bundle_FileType, ///< Mach-O Bundle file
- Mach_O_DynamicallyLinkedSharedLibStub_FileType, ///< Mach-O Shared lib stub
- COFF_FileType ///< COFF object file or lib
- };
-
- /// This utility function allows any memory block to be examined in order
- /// to determine its file type.
- LLVMFileType IdentifyFileType(const char*magic, unsigned length);
-
- /// This function can be used to copy the file specified by Src to the
- /// file specified by Dest. If an error occurs, Dest is removed.
- /// @returns true if an error occurs, false otherwise
- /// @brief Copy one file to another.
- bool CopyFile(const Path& Dest, const Path& Src, std::string* ErrMsg);
-
- /// This is the OS-specific path separator: a colon on Unix or a semicolon
- /// on Windows.
- extern const char PathSeparator;
-}
-
-}
-
-#endif
+++ /dev/null
-//===- llvm/System/PathV2.h - Path Operating System Concept -----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares the llvm::sys::path namespace. It is designed after
-// TR2/boost filesystem (v3), but modified to remove exception handling and the
-// path class.
-//
-// All functions return an error_code and their actual work via the last out
-// argument. The out argument is defined if and only if errc::success is
-// returned. A function may return any error code in the generic or system
-// category. However, they shall be equivalent to any error conditions listed
-// in each functions respective documentation if the condition applies. [ note:
-// this does not guarantee that error_code will be in the set of explicitly
-// listed codes, but it does guarantee that if any of the explicitly listed
-// errors occur, the correct error_code will be used ]. All functions may
-// return errc::not_enough_memory if there is not enough memory to complete the
-// operation.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ADT/SmallString.h"
-#include "llvm/System/DataTypes.h"
-#include "llvm/System/system_error.h"
-#include <ctime>
-#include <iterator>
-#include <string>
-
-namespace llvm {
-
-// Forward decls.
-class StringRef;
-class Twine;
-
-namespace sys {
-namespace path {
-
-/// @name Lexical Component Iterator
-/// @{
-
-/// @brief Path iterator.
-///
-/// This is a bidirectional iterator that iterates over the individual
-/// components in \a path. The forward traversal order is as follows:
-/// * The root-name element, if present.
-/// * The root-directory element, if present.
-/// * Each successive filename element, if present.
-/// * Dot, if one or more trailing non-root slash characters are present.
-/// The backwards traversal order is the reverse of forward traversal.
-///
-/// Iteration examples. Each component is separated by ',':
-/// / => /
-/// /foo => /,foo
-/// foo/ => foo,.
-/// /foo/bar => /,foo,bar
-/// ../ => ..,.
-/// C:\foo\bar => C:,/,foo,bar
-///
-class const_iterator {
- StringRef Path; //< The entire path.
- StringRef Component; //< The current component.
-
-public:
- typedef const StringRef value_type;
- typedef value_type &reference;
- typedef value_type *pointer;
- typedef std::bidirectional_iterator_tag iterator_category;
- reference operator*() const;
- pointer operator->() const;
- const_iterator &operator++(); // preincrement
- const_iterator &operator++(int); // postincrement
- const_iterator &operator--(); // predecrement
- const_iterator &operator--(int); // postdecrement
- bool operator==(const const_iterator &RHS) const;
- bool operator!=(const const_iterator &RHS) const;
-
- const_iterator(); //< Default construct end iterator.
- const_iterator(const StringRef &path);
-};
-
-/// @}
-/// @name Lexical Modifiers
-/// @{
-
-/// @brief Make \a path an absolute path.
-///
-/// Makes \a path absolute using the current directory if it is not already. An
-/// empty \a path will result in the current directory.
-///
-/// /absolute/path => /absolute/path
-/// relative/../path => <current-directory>/path
-///
-/// @param path A path that is modified to be an absolute path.
-/// @returns errc::success if \a path has been made absolute, otherwise a
-/// platform specific error_code.
-error_code make_absolute(SmallVectorImpl<char> &path);
-
-/// @brief Remove the last component from \a path if it exists.
-///
-/// directory/filename.cpp => directory/
-/// directory/ => directory/
-///
-/// @param path A path that is modified to not have a file component.
-/// @returns errc::success if \a path's file name has been removed (or there was
-/// not one to begin with), otherwise a platform specific error_code.
-error_code remove_filename(SmallVectorImpl<char> &path);
-
-/// @brief Replace the file extension of \a path with \a extension.
-///
-/// ./filename.cpp => ./filename.extension
-/// ./filename => ./filename.extension
-/// ./ => ? TODO: decide what semantics this has.
-///
-/// @param path A path that has its extension replaced with \a extension.
-/// @param extension The extension to be added. It may be empty. It may also
-/// optionally start with a '.', if it does not, one will be
-/// prepended.
-/// @returns errc::success if \a path's extension has been replaced, otherwise a
-/// platform specific error_code.
-error_code replace_extension(SmallVectorImpl<char> &path,
- const Twine &extension);
-
-/// @brief Append to path.
-///
-/// /foo + bar/f => /foo/bar/f
-/// /foo/ + bar/f => /foo/bar/f
-/// foo + bar/f => foo/bar/f
-///
-/// @param path Set to \a path + \a component.
-/// @param component The component to be appended to \a path.
-/// @returns errc::success if \a component has been appended to \a path,
-/// otherwise a platform specific error_code.
-error_code append(SmallVectorImpl<char> &path, const Twine &component);
-
-/// @brief Append to path.
-///
-/// /foo + [bar,f] => /foo/bar/f
-/// /foo/ + [bar,f] => /foo/bar/f
-/// foo + [bar,f] => foo/bar/f
-///
-/// @param path Set to \a path + [\a begin, \a end).
-/// @param begin Start of components to append.
-/// @param end One past the end of components to append.
-/// @returns errc::success if [\a begin, \a end) has been appended to \a path,
-/// otherwise a platform specific error_code.
-error_code append(SmallVectorImpl<char> &path,
- const_iterator begin, const_iterator end);
-
-/// @}
-/// @name Transforms (or some other better name)
-/// @{
-
-/// Convert path to the native form. This is used to give paths to users and
-/// operating system calls in the platform's normal way. For example, on Windows
-/// all '/' are converted to '\'.
-///
-/// @param path A path that is transformed to native format.
-/// @param result Holds the result of the transformation.
-/// @returns errc::success if \a path has been transformed and stored in result,
-/// otherwise a platform specific error_code.
-error_code native(const Twine &path, SmallVectorImpl<char> &result);
-
-/// @}
-/// @name Lexical Observers
-/// @{
-
-/// @brief Get the current path.
-///
-/// @param result Holds the current path on return.
-/// @results errc::success if the current path has been stored in result,
-/// otherwise a platform specific error_code.
-error_code current_path(SmallVectorImpl<char> &result);
-
-// The following are purely lexical.
-
-/// @brief Is the current path valid?
-///
-/// @param path Input path.
-/// @param result Set to true if the path is valid, false if it is not.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code is_valid(const Twine &path, bool &result);
-
-/// @brief Get root name.
-///
-/// //net/hello => //net
-/// c:/hello => c: (on Windows, on other platforms nothing)
-/// /hello => <empty>
-///
-/// @param path Input path.
-/// @param result Set to the root name of \a path if it has one, otherwise "".
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code root_name(const StringRef &path, StringRef &result);
-
-/// @brief Get root directory.
-///
-/// /goo/hello => /
-/// c:/hello => /
-/// d/file.txt => <empty>
-///
-/// @param path Input path.
-/// @param result Set to the root directory of \a path if it has one, otherwise
-/// "".
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code root_directory(const StringRef &path, StringRef &result);
-
-/// @brief Get root path.
-///
-/// Equivalent to root_name + root_directory.
-///
-/// @param path Input path.
-/// @param result Set to the root path of \a path if it has one, otherwise "".
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code root_path(const StringRef &path, StringRef &result);
-
-/// @brief Get relative path.
-///
-/// C:\hello\world => hello\world
-/// foo/bar => foo/bar
-/// /foo/bar => foo/bar
-///
-/// @param path Input path.
-/// @param result Set to the path starting after root_path if one exists,
-/// otherwise "".
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code relative_path(const StringRef &path, StringRef &result);
-
-/// @brief Get parent path.
-///
-/// / => <empty>
-/// /foo => /
-/// foo/../bar => foo/..
-///
-/// @param path Input path.
-/// @param result Set to the parent path of \a path if one exists, otherwise "".
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code parent_path(const StringRef &path, StringRef &result);
-
-/// @brief Get filename.
-///
-/// /foo.txt => foo.txt
-/// . => .
-/// .. => ..
-/// / => /
-///
-/// @param path Input path.
-/// @param result Set to the filename part of \a path. This is defined as the
-/// last component of \a path.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code filename(const StringRef &path, StringRef &result);
-
-/// @brief Get stem.
-///
-/// If filename contains a dot but not solely one or two dots, result is the
-/// substring of filename ending at (but not including) the last dot. Otherwise
-/// it is filename.
-///
-/// /foo/bar.txt => bar
-/// /foo/bar => bar
-/// /foo/.txt => <empty>
-/// /foo/. => .
-/// /foo/.. => ..
-///
-/// @param path Input path.
-/// @param result Set to the stem of \a path.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code stem(const StringRef &path, StringRef &result);
-
-/// @brief Get extension.
-///
-/// If filename contains a dot but not solely one or two dots, result is the
-/// substring of filename starting at (and including) the last dot, and ending
-/// at the end of \a path. Otherwise "".
-///
-/// /foo/bar.txt => .txt
-/// /foo/bar => <empty>
-/// /foo/.txt => .txt
-///
-/// @param path Input path.
-/// @param result Set to the extension of \a path.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code extension(const StringRef &path, StringRef &result);
-
-/// @brief Has root name?
-///
-/// root_name != ""
-///
-/// @param path Input path.
-/// @param result Set to true if the path has a root name, false otherwise.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code has_root_name(const Twine &path, bool &result);
-
-/// @brief Has root directory?
-///
-/// root_directory != ""
-///
-/// @param path Input path.
-/// @param result Set to true if the path has a root directory, false otherwise.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code has_root_directory(const Twine &path, bool &result);
-
-/// @brief Has root path?
-///
-/// root_path != ""
-///
-/// @param path Input path.
-/// @param result Set to true if the path has a root path, false otherwise.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code has_root_path(const Twine &path, bool &result);
-
-/// @brief Has relative path?
-///
-/// relative_path != ""
-///
-/// @param path Input path.
-/// @param result Set to true if the path has a relative path, false otherwise.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code has_relative_path(const Twine &path, bool &result);
-
-/// @brief Has parent path?
-///
-/// parent_path != ""
-///
-/// @param path Input path.
-/// @param result Set to true if the path has a parent path, false otherwise.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code has_parent_path(const Twine &path, bool &result);
-
-/// @brief Has filename?
-///
-/// filename != ""
-///
-/// @param path Input path.
-/// @param result Set to true if the path has a filename, false otherwise.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code has_filename(const Twine &path, bool &result);
-
-/// @brief Has stem?
-///
-/// stem != ""
-///
-/// @param path Input path.
-/// @param result Set to true if the path has a stem, false otherwise.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code has_stem(const Twine &path, bool &result);
-
-/// @brief Has extension?
-///
-/// extension != ""
-///
-/// @param path Input path.
-/// @param result Set to true if the path has a extension, false otherwise.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code has_extension(const Twine &path, bool &result);
-
-/// @brief Is path absolute?
-///
-/// @param path Input path.
-/// @param result Set to true if the path is absolute, false if it is not.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code is_absolute(const Twine &path, bool &result);
-
-/// @brief Is path relative?
-///
-/// @param path Input path.
-/// @param result Set to true if the path is relative, false if it is not.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code is_relative(const Twine &path, bool &result);
-// end purely lexical.
-
-} // end namespace path
-
-namespace fs {
-
-/// file_type - An "enum class" enumeration for the file system's view of the
-/// type.
-struct file_type {
- enum _ {
- status_error,
- file_not_found,
- regular_file,
- directory_file,
- symlink_file,
- block_file,
- character_file,
- fifo_file,
- socket_file,
- type_unknown
- };
-
- file_type(_ v) : v_(v) {}
- explicit file_type(int v) : v_(_(v)) {}
- operator int() const {return v_;}
-
-private:
- int v_;
-};
-
-/// copy_option - An "enum class" enumeration of copy semantics for copy
-/// operations.
-struct copy_option {
- enum _ {
- fail_if_exists,
- overwrite_if_exists
- };
-
- copy_option(_ v) : v_(v) {}
- explicit copy_option(int v) : v_(_(v)) {}
- operator int() const {return v_;}
-
-private:
- int v_;
-};
-
-/// space_info - Self explanatory.
-struct space_info {
- uint64_t capacity;
- uint64_t free;
- uint64_t available;
-};
-
-/// file_status - Represents the result of a call to stat and friends. It has
-/// a platform specific member to store the result.
-class file_status
-{
- // implementation defined status field.
-public:
- explicit file_status(file_type v=file_type::status_error);
-
- file_type type() const;
- void type(file_type v);
-};
-
-/// @}
-/// @name Physical Operators
-/// @{
-
-/// @brief Copy the file at \a from to the path \a to.
-///
-/// @param from The path to copy the file from.
-/// @param to The path to copy the file to.
-/// @param copt Behavior if \a to already exists.
-/// @returns errc::success if the file has been successfully copied.
-/// errc::file_exists if \a to already exists and \a copt ==
-/// copy_option::fail_if_exists. Otherwise a platform specific
-/// error_code.
-error_code copy_file(const Twine &from, const Twine &to,
- copy_option copt = copy_option::fail_if_exists);
-
-/// @brief Create all the non-existent directories in path.
-///
-/// @param path Directories to create.
-/// @param existed Set to true if \a path already existed, false otherwise.
-/// @returns errc::success if is_directory(path) and existed have been set,
-/// otherwise a platform specific error_code.
-error_code create_directories(const Twine &path, bool &existed);
-
-/// @brief Create the directory in path.
-///
-/// @param path Directory to create.
-/// @param existed Set to true if \a path already existed, false otherwise.
-/// @returns errc::success if is_directory(path) and existed have been set,
-/// otherwise a platform specific error_code.
-error_code create_directory(const Twine &path, bool &existed);
-
-/// @brief Create a hard link from \a from to \a to.
-///
-/// @param to The path to hard link to.
-/// @param from The path to hard link from. This is created.
-/// @returns errc::success if exists(to) && exists(from) && equivalent(to, from)
-/// , otherwise a platform specific error_code.
-error_code create_hard_link(const Twine &to, const Twine &from);
-
-/// @brief Create a symbolic link from \a from to \a to.
-///
-/// @param to The path to symbolically link to.
-/// @param from The path to symbolically link from. This is created.
-/// @returns errc::success if exists(to) && exists(from) && is_symlink(from),
-/// otherwise a platform specific error_code.
-error_code create_symlink(const Twine &to, const Twine &from);
-
-/// @brief Remove path. Equivalent to POSIX remove().
-///
-/// @param path Input path.
-/// @param existed Set to true if \a path existed, false if it did not.
-/// undefined otherwise.
-/// @results errc::success if path has been removed and existed has been
-/// successfully set, otherwise a platform specific error_code.
-error_code remove(const Twine &path, bool &existed);
-
-/// @brief Recursively remove all files below \a path, then \a path. Files are
-/// removed as if by POSIX remove().
-///
-/// @param path Input path.
-/// @param num_removed Number of files removed.
-/// @results errc::success if path has been removed and num_removed has been
-/// successfully set, otherwise a platform specific error_code.
-error_code remove_all(const Twine &path, uint32_t &num_removed);
-
-/// @brief Rename \a from to \a to. Files are renamed as if by POSIX rename().
-///
-/// @param from The path to rename from.
-/// @param to The path to rename to. This is created.
-error_code rename(const Twine &from, const Twine &to);
-
-/// @brief Resize path to size. File is resized as if by POSIX truncate().
-///
-/// @param path Input path.
-/// @param size Size to resize to.
-/// @returns errc::success if \a path has been resized to \a size, otherwise a
-/// platform specific error_code.
-error_code resize_file(const Twine &path, uint64_t size);
-
-/// @brief Make file readable.
-///
-/// @param path Input path.
-/// @param value If true, make readable, else, make unreadable.
-/// @results errc::success if readability has been successfully set, otherwise a
-/// platform specific error_code.
-error_code set_read(const Twine &path, bool value);
-
-/// @brief Make file writeable.
-///
-/// @param path Input path.
-/// @param value If true, make writeable, else, make unwriteable.
-/// @results errc::success if writeability has been successfully set, otherwise
-/// a platform specific error_code.
-error_code set_write(const Twine &path, bool value);
-
-/// @brief Make file executable.
-///
-/// @param path Input path.
-/// @param value If true, make executable, else, make unexecutable.
-/// @results errc::success if executability has been successfully set, otherwise
-/// a platform specific error_code.
-error_code set_execute(const Twine &path, bool value);
-
-/// @}
-/// @name Physical Observers
-/// @{
-
-/// @brief Does file exist?
-///
-/// @param status A file_status previously returned from stat.
-/// @param result Set to true if the file represented by status exists, false if
-/// it does not. Undefined otherwise.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code exists(file_status status, bool &result);
-
-/// @brief Does file exist?
-///
-/// @param path Input path.
-/// @param result Set to true if the file represented by status exists, false if
-/// it does not. Undefined otherwise.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code exists(const Twine &path, bool &result);
-
-/// @brief Do paths represent the same thing?
-///
-/// @param A Input path A.
-/// @param B Input path B.
-/// @param result Set to true if stat(A) and stat(B) have the same device and
-/// inode (or equivalent).
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code equivalent(const Twine &A, const Twine &B, bool &result);
-
-/// @brief Get file size.
-///
-/// @param path Input path.
-/// @param result Set to the size of the file in \a path.
-/// @returns errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code file_size(const Twine &path, uint64_t &result);
-
-/// @brief Does status represent a directory?
-///
-/// @param status A file_status previously returned from stat.
-/// @param result Set to true if the file represented by status is a directory,
-/// false if it is not. Undefined otherwise.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code is_directory(file_status status, bool &result);
-
-/// @brief Is path a directory?
-///
-/// @param path Input path.
-/// @param result Set to true if \a path is a directory, false if it is not.
-/// Undefined otherwise.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code is_directory(const Twine &path, bool &result);
-
-/// @brief Is path an empty file?
-///
-/// @param path Input path.
-/// @param result Set to true if \a path is a an empty file, false if it is not.
-/// Undefined otherwise.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code is_empty(const Twine &path, bool &result);
-
-/// @brief Does status represent a regular file?
-///
-/// @param status A file_status previously returned from stat.
-/// @param result Set to true if the file represented by status is a regular
-/// file, false if it is not. Undefined otherwise.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code is_regular_file(file_status status, bool &result);
-
-/// @brief Is path a regular file?
-///
-/// @param path Input path.
-/// @param result Set to true if \a path is a regular file, false if it is not.
-/// Undefined otherwise.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code is_regular_file(const Twine &path, bool &result);
-
-/// @brief Does status represent something that exists but is not a directory,
-/// regular file, or symlink?
-///
-/// @param status A file_status previously returned from stat.
-/// @param result Set to true if the file represented by status exists, but is
-/// not a directory, regular file, or a symlink, false if it does
-/// not. Undefined otherwise.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code is_other(file_status status, bool &result);
-
-/// @brief Is path something that exists but is not a directory,
-/// regular file, or symlink?
-///
-/// @param path Input path.
-/// @param result Set to true if \a path exists, but is not a directory, regular
-/// file, or a symlink, false if it does not. Undefined otherwise.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code is_other(const Twine &path, bool &result);
-
-/// @brief Does status represent a symlink?
-///
-/// @param status A file_status previously returned from stat.
-/// @param result Set to true if the file represented by status is a symlink,
-/// false if it is not. Undefined otherwise.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code is_symlink(file_status status, bool &result);
-
-/// @brief Is path a symlink?
-///
-/// @param path Input path.
-/// @param result Set to true if \a path is a symlink, false if it is not.
-/// Undefined otherwise.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code is_symlink(const Twine &path, bool &result);
-
-/// @brief Get last write time without changing it.
-///
-/// @param path Input path.
-/// @param result Set to the last write time (UNIX time) of \a path if it
-/// exists.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code last_write_time(const Twine &path, std::time_t &result);
-
-/// @brief Set last write time.
-///
-/// @param path Input path.
-/// @param value Time to set (UNIX time) \a path's last write time to.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code set_last_write_time(const Twine &path, std::time_t value);
-
-/// @brief Read a symlink's value.
-///
-/// @param path Input path.
-/// @param result Set to the value of the symbolic link \a path.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code read_symlink(const Twine &path, SmallVectorImpl<char> &result);
-
-/// @brief Get disk space usage information.
-///
-/// @param path Input path.
-/// @param result Set to the capacity, free, and available space on the device
-/// \a path is on.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code disk_space(const Twine &path, space_info &result);
-
-/// @brief Get file status as if by POSIX stat().
-///
-/// @param path Input path.
-/// @param result Set to the file status.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code status(const Twine &path, file_status &result);
-
-/// @brief Is status available?
-///
-/// @param path Input path.
-/// @param result Set to true if status() != status_error.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code status_known(const Twine &path, bool &result);
-
-/// @brief Get file status as if by POSIX lstat().
-///
-/// Does not resolve symlinks.
-///
-/// @param path Input path.
-/// @param result Set to the file status.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code symlink_status(const Twine &path, file_status &result);
-
-/// @brief Get the temporary directory.
-///
-/// @param result Set to the temporary directory.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-/// @see unique_file
-error_code temp_directory_path(SmallVectorImpl<char> &result);
-
-/// @brief Generate a unique path and open it as a file.
-///
-/// Generates a unique path suitable for a temporary file and then opens it as a
-/// file. The name is based on \a model with '%' replaced by a random char in
-/// [0-9a-f].
-///
-/// This is an atomic operation. Either the file is created and opened, or the
-/// file system is left untouched.
-///
-/// clang-%%-%%-%%-%%-%%.s => <current-directory>/clang-a0-b1-c2-d3-e4.s
-///
-/// @param model Name to base unique path off of.
-/// @param result Set to the opened file.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-/// @see temp_directory_path
-error_code unique_file(const Twine &model, void* i_have_not_decided_the_ty_yet);
-
-/// @brief Canonicalize path.
-///
-/// Sets result to the file system's idea of what path is. The result is always
-/// absolute and has the same capitalization as the file system.
-///
-/// @param path Input path.
-/// @param result Set to the canonicalized version of \a path.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code canonicalize(const Twine &path, SmallVectorImpl<char> &result);
-
-/// @brief Are \a path's first bytes \a magic?
-///
-/// @param path Input path.
-/// @param magic Byte sequence to compare \a path's first len(magic) bytes to.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code has_magic(const Twine &path, const Twine &magic);
-
-/// @brief Get \a path's first \a len bytes.
-///
-/// @param path Input path.
-/// @param len Number of magic bytes to get.
-/// @param result Set to the first \a len bytes in the file pointed to by
-/// \a path.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code get_magic(const Twine &path, uint32_t len,
- SmallVectorImpl<char> &result);
-
-/// @brief Is file bitcode?
-///
-/// @param path Input path.
-/// @param result Set to true if \a path is a bitcode file, false if it is not,
-/// undefined otherwise.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code is_bitcode(const Twine &path, bool &result);
-
-/// @brief Is file a dynamic library?
-///
-/// @param path Input path.
-/// @param result Set to true if \a path is a dynamic library, false if it is
-/// not, undefined otherwise.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code is_dynamic_library(const Twine &path, bool &result);
-
-/// @brief Is an object file?
-///
-/// @param path Input path.
-/// @param result Set to true if \a path is an object file, false if it is not,
-/// undefined otherwise.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code is_object_file(const Twine &path, bool &result);
-
-/// @brief Can file be read?
-///
-/// @param path Input path.
-/// @param result Set to true if \a path is readable, false it it is not,
-/// undefined otherwise.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code can_read(const Twine &path, bool &result);
-
-/// @brief Can file be written?
-///
-/// @param path Input path.
-/// @param result Set to true if \a path is writeable, false it it is not,
-/// undefined otherwise.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code can_write(const Twine &path, bool &result);
-
-/// @brief Can file be executed?
-///
-/// @param path Input path.
-/// @param result Set to true if \a path is executable, false it it is not,
-/// undefined otherwise.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code can_execute(const Twine &path, bool &result);
-
-/// @brief Get library paths the system linker uses.
-///
-/// @param result Set to the list of system library paths.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code GetSystemLibraryPaths(SmallVectorImpl<std::string> &result);
-
-/// @brief Get bitcode library paths the system linker uses
-/// + LLVM_LIB_SEARCH_PATH + LLVM_LIBDIR.
-///
-/// @param result Set to the list of bitcode library paths.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code GetBitcodeLibraryPaths(SmallVectorImpl<std::string> &result);
-
-/// @brief Find a library.
-///
-/// Find the path to a library using its short name. Use the system
-/// dependent library paths to locate the library.
-///
-/// c => /usr/lib/libc.so
-///
-/// @param short_name Library name one would give to the system linker.
-/// @param result Set to the absolute path \a short_name represents.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code FindLibrary(const Twine &short_name, SmallVectorImpl<char> &result);
-
-/// @brief Get absolute path of main executable.
-///
-/// @param argv0 The program name as it was spelled on the command line.
-/// @param MainAddr Address of some symbol in the executable (not in a library).
-/// @param result Set to the absolute path of the current executable.
-/// @results errc::success if result has been successfully set, otherwise a
-/// platform specific error_code.
-error_code GetMainExecutable(const char *argv0, void *MainAddr,
- SmallVectorImpl<char> &result);
-
-/// @}
-/// @name Iterators
-/// @{
-
-/// directory_entry - A single entry in a directory. Caches the status either
-/// from the result of the iteration syscall, or the first time status or
-/// symlink_status is called.
-class directory_entry {
- std::string Path;
- mutable file_status Status;
- mutable file_status SymlinkStatus;
-
-public:
- explicit directory_entry(const Twine &path, file_status st = file_status(),
- file_status symlink_st = file_status());
-
- void assign(const Twine &path, file_status st = file_status(),
- file_status symlink_st = file_status());
- void replace_filename(const Twine &filename, file_status st = file_status(),
- file_status symlink_st = file_status());
-
- const SmallVectorImpl<char> &path() const;
- error_code status(file_status &result) const;
- error_code symlink_status(file_status &result) const;
-
- bool operator==(const directory_entry& rhs) const;
- bool operator!=(const directory_entry& rhs) const;
- bool operator< (const directory_entry& rhs) const;
- bool operator<=(const directory_entry& rhs) const;
- bool operator> (const directory_entry& rhs) const;
- bool operator>=(const directory_entry& rhs) const;
-};
-
-/// directory_iterator - Iterates through the entries in path. There is no
-/// operator++ because we need an error_code. If it's really needed we can make
-/// it call report_fatal_error on error.
-class directory_iterator {
- // implementation directory iterator status
-
-public:
- explicit directory_iterator(const Twine &path, error_code &ec);
- // No operator++ because we need error_code.
- directory_iterator &increment(error_code &ec);
-
- const directory_entry &operator*() const;
- const directory_entry *operator->() const;
-
- // Other members as required by
- // C++ Std, 24.1.1 Input iterators [input.iterators]
-};
-
-/// recursive_directory_iterator - Same as directory_iterator except for it
-/// recurses down into child directories.
-class recursive_directory_iterator {
- uint16_t Level;
- bool HasNoPushRequest;
- // implementation directory iterator status
-
-public:
- explicit recursive_directory_iterator(const Twine &path, error_code &ec);
- // No operator++ because we need error_code.
- directory_iterator &increment(error_code &ec);
-
- const directory_entry &operator*() const;
- const directory_entry *operator->() const;
-
- // observers
- /// Gets the current level. path is at level 0.
- int level() const;
- /// Returns true if no_push has been called for this directory_entry.
- bool no_push_request() const;
-
- // modifiers
- /// Goes up one level if Level > 0.
- void pop();
- /// Does not go down into the current directory_entry.
- void no_push();
-
- // Other members as required by
- // C++ Std, 24.1.1 Input iterators [input.iterators]
-};
-
-/// @}
-
-} // end namespace fs
-} // end namespace sys
-} // end namespace llvm
+++ /dev/null
-//===- llvm/System/Process.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 declares the llvm::sys::Process class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SYSTEM_PROCESS_H
-#define LLVM_SYSTEM_PROCESS_H
-
-#include "llvm/System/TimeValue.h"
-
-namespace llvm {
-namespace sys {
-
- /// This class provides an abstraction for getting information about the
- /// currently executing process.
- /// @since 1.4
- /// @brief An abstraction for operating system processes.
- class Process {
- /// @name Accessors
- /// @{
- public:
- /// This static function will return the operating system's virtual memory
- /// page size.
- /// @returns The number of bytes in a virtual memory page.
- /// @brief Get the virtual memory page size
- static unsigned GetPageSize();
-
- /// This static function will return the total amount of memory allocated
- /// by the process. This only counts the memory allocated via the malloc,
- /// calloc and realloc functions and includes any "free" holes in the
- /// allocated space.
- /// @brief Return process memory usage.
- static size_t GetMallocUsage();
-
- /// This static function will return the total memory usage of the
- /// process. This includes code, data, stack and mapped pages usage. Notei
- /// that the value returned here is not necessarily the Running Set Size,
- /// it is the total virtual memory usage, regardless of mapped state of
- /// that memory.
- static size_t GetTotalMemoryUsage();
-
- /// This static function will set \p user_time to the amount of CPU time
- /// spent in user (non-kernel) mode and \p sys_time to the amount of CPU
- /// time spent in system (kernel) mode. If the operating system does not
- /// support collection of these metrics, a zero TimeValue will be for both
- /// values.
- static void GetTimeUsage(
- TimeValue& elapsed,
- ///< Returns the TimeValue::now() giving current time
- TimeValue& user_time,
- ///< Returns the current amount of user time for the process
- TimeValue& sys_time
- ///< Returns the current amount of system time for the process
- );
-
- /// This static function will return the process' current user id number.
- /// Not all operating systems support this feature. Where it is not
- /// supported, the function should return 65536 as the value.
- static int GetCurrentUserId();
-
- /// This static function will return the process' current group id number.
- /// Not all operating systems support this feature. Where it is not
- /// supported, the function should return 65536 as the value.
- static int GetCurrentGroupId();
-
- /// This function makes the necessary calls to the operating system to
- /// prevent core files or any other kind of large memory dumps that can
- /// occur when a program fails.
- /// @brief Prevent core file generation.
- static void PreventCoreFiles();
-
- /// This function determines if the standard input is connected directly
- /// to a user's input (keyboard probably), rather than coming from a file
- /// or pipe.
- static bool StandardInIsUserInput();
-
- /// This function determines if the standard output is connected to a
- /// "tty" or "console" window. That is, the output would be displayed to
- /// the user rather than being put on a pipe or stored in a file.
- static bool StandardOutIsDisplayed();
-
- /// This function determines if the standard error is connected to a
- /// "tty" or "console" window. That is, the output would be displayed to
- /// the user rather than being put on a pipe or stored in a file.
- static bool StandardErrIsDisplayed();
-
- /// This function determines if the given file descriptor is connected to
- /// a "tty" or "console" window. That is, the output would be displayed to
- /// the user rather than being put on a pipe or stored in a file.
- static bool FileDescriptorIsDisplayed(int fd);
-
- /// This function determines the number of columns in the window
- /// if standard output is connected to a "tty" or "console"
- /// window. If standard output is not connected to a tty or
- /// console, or if the number of columns cannot be determined,
- /// this routine returns zero.
- static unsigned StandardOutColumns();
-
- /// This function determines the number of columns in the window
- /// if standard error is connected to a "tty" or "console"
- /// window. If standard error is not connected to a tty or
- /// console, or if the number of columns cannot be determined,
- /// this routine returns zero.
- static unsigned StandardErrColumns();
-
- /// This function determines whether the terminal connected to standard
- /// output supports colors. If standard output is not connected to a
- /// terminal, this function returns false.
- static bool StandardOutHasColors();
-
- /// This function determines whether the terminal connected to standard
- /// error supports colors. If standard error is not connected to a
- /// terminal, this function returns false.
- static bool StandardErrHasColors();
-
- /// Whether changing colors requires the output to be flushed.
- /// This is needed on systems that don't support escape sequences for
- /// changing colors.
- static bool ColorNeedsFlush();
-
- /// This function returns the colorcode escape sequences.
- /// If ColorNeedsFlush() is true then this function will change the colors
- /// and return an empty escape sequence. In that case it is the
- /// responsibility of the client to flush the output stream prior to
- /// calling this function.
- static const char *OutputColor(char c, bool bold, bool bg);
-
- /// Same as OutputColor, but only enables the bold attribute.
- static const char *OutputBold(bool bg);
-
- /// Resets the terminals colors, or returns an escape sequence to do so.
- static const char *ResetColor();
- /// @}
- };
-}
-}
-
-#endif
+++ /dev/null
-//===- llvm/System/Program.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 declares the llvm::sys::Program class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SYSTEM_PROGRAM_H
-#define LLVM_SYSTEM_PROGRAM_H
-
-#include "llvm/System/Path.h"
-
-namespace llvm {
-namespace sys {
-
- // TODO: Add operations to communicate with the process, redirect its I/O,
- // etc.
-
- /// This class provides an abstraction for programs that are executable by the
- /// operating system. It provides a platform generic way to find executable
- /// programs from the path and to execute them in various ways. The sys::Path
- /// class is used to specify the location of the Program.
- /// @since 1.4
- /// @brief An abstraction for finding and executing programs.
- class Program {
- /// Opaque handle for target specific data.
- void *Data_;
-
- // Noncopyable.
- Program(const Program& other);
- Program& operator=(const Program& other);
-
- /// @name Methods
- /// @{
- public:
-
- Program();
- ~Program();
-
- /// Return process ID of this program.
- unsigned GetPid() const;
-
- /// This function executes the program using the \p arguments provided. The
- /// invoked program will inherit the stdin, stdout, and stderr file
- /// descriptors, the environment and other configuration settings of the
- /// invoking program. If Path::executable() does not return true when this
- /// function is called then a std::string is thrown.
- /// @returns false in case of error, true otherwise.
- /// @see FindProgramByName
- /// @brief Executes the program with the given set of \p args.
- bool Execute
- ( const Path& path, ///< sys::Path object providing the path of the
- ///< program to be executed. It is presumed this is the result of
- ///< the FindProgramByName method.
- const char** args, ///< A vector of strings that are passed to the
- ///< program. The first element should be the name of the program.
- ///< The list *must* be terminated by a null char* entry.
- const char ** env = 0, ///< An optional vector of strings to use for
- ///< the program's environment. If not provided, the current program's
- ///< environment will be used.
- const sys::Path** redirects = 0, ///< An optional array of pointers to
- ///< Paths. If the array is null, no redirection is done. The array
- ///< should have a size of at least three. If the pointer in the array
- ///< are not null, then the inferior process's stdin(0), stdout(1),
- ///< and stderr(2) will be redirected to the corresponding Paths.
- ///< When an empty Path is passed in, the corresponding file
- ///< descriptor will be disconnected (ie, /dev/null'd) in a portable
- ///< way.
- unsigned memoryLimit = 0, ///< If non-zero, this specifies max. amount
- ///< of memory can be allocated by process. If memory usage will be
- ///< higher limit, the child is killed and this call returns. If zero
- ///< - no memory limit.
- std::string* ErrMsg = 0 ///< If non-zero, provides a pointer to a string
- ///< instance in which error messages will be returned. If the string
- ///< is non-empty upon return an error occurred while invoking the
- ///< program.
- );
-
- /// This function waits for the program to exit. This function will block
- /// the current program until the invoked program exits.
- /// @returns an integer result code indicating the status of the program.
- /// A zero or positive value indicates the result code of the program. A
- /// negative value is the signal number on which it terminated.
- /// @see Execute
- /// @brief Waits for the program to exit.
- int Wait
- ( const Path& path, ///< The path to the child process executable.
- unsigned secondsToWait, ///< If non-zero, this specifies the amount
- ///< of time to wait for the child process to exit. If the time
- ///< expires, the child is killed and this call returns. If zero,
- ///< this function will wait until the child finishes or forever if
- ///< it doesn't.
- std::string* ErrMsg ///< If non-zero, provides a pointer to a string
- ///< instance in which error messages will be returned. If the string
- ///< is non-empty upon return an error occurred while waiting.
- );
-
- /// This function terminates the program.
- /// @returns true if an error occured.
- /// @see Execute
- /// @brief Terminates the program.
- bool Kill
- ( std::string* ErrMsg = 0 ///< If non-zero, provides a pointer to a string
- ///< instance in which error messages will be returned. If the string
- ///< is non-empty upon return an error occurred while killing the
- ///< program.
- );
-
- /// This static constructor (factory) will attempt to locate a program in
- /// the operating system's file system using some pre-determined set of
- /// locations to search (e.g. the PATH on Unix). Paths with slashes are
- /// returned unmodified.
- /// @returns A Path object initialized to the path of the program or a
- /// Path object that is empty (invalid) if the program could not be found.
- /// @brief Construct a Program by finding it by name.
- static Path FindProgramByName(const std::string& name);
-
- // These methods change the specified standard stream (stdin,
- // stdout, or stderr) to binary mode. They return true if an error
- // occurred
- static bool ChangeStdinToBinary();
- static bool ChangeStdoutToBinary();
- static bool ChangeStderrToBinary();
-
- /// A convenience function equivalent to Program prg; prg.Execute(..);
- /// prg.Wait(..);
- /// @see Execute, Wait
- static int ExecuteAndWait(const Path& path,
- const char** args,
- const char ** env = 0,
- const sys::Path** redirects = 0,
- unsigned secondsToWait = 0,
- unsigned memoryLimit = 0,
- std::string* ErrMsg = 0);
-
- /// A convenience function equivalent to Program prg; prg.Execute(..);
- /// @see Execute
- static void ExecuteNoWait(const Path& path,
- const char** args,
- const char ** env = 0,
- const sys::Path** redirects = 0,
- unsigned memoryLimit = 0,
- std::string* ErrMsg = 0);
-
- /// @}
-
- };
-}
-}
-
-#endif
+++ /dev/null
-//===- RWMutex.h - Reader/Writer Mutual Exclusion Lock ----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares the llvm::sys::RWMutex class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SYSTEM_RWMUTEX_H
-#define LLVM_SYSTEM_RWMUTEX_H
-
-#include "llvm/System/Threading.h"
-#include <cassert>
-
-namespace llvm
-{
- namespace sys
- {
- /// @brief Platform agnostic RWMutex class.
- class RWMutexImpl
- {
- /// @name Constructors
- /// @{
- public:
-
- /// Initializes the lock but doesn't acquire it.
- /// @brief Default Constructor.
- explicit RWMutexImpl();
-
- /// Releases and removes the lock
- /// @brief Destructor
- ~RWMutexImpl();
-
- /// @}
- /// @name Methods
- /// @{
- public:
-
- /// Attempts to unconditionally acquire the lock in reader mode. If the
- /// lock is held by a writer, this method will wait until it can acquire
- /// the lock.
- /// @returns false if any kind of error occurs, true otherwise.
- /// @brief Unconditionally acquire the lock in reader mode.
- bool reader_acquire();
-
- /// Attempts to release the lock in reader mode.
- /// @returns false if any kind of error occurs, true otherwise.
- /// @brief Unconditionally release the lock in reader mode.
- bool reader_release();
-
- /// Attempts to unconditionally acquire the lock in reader mode. If the
- /// lock is held by any readers, this method will wait until it can
- /// acquire the lock.
- /// @returns false if any kind of error occurs, true otherwise.
- /// @brief Unconditionally acquire the lock in writer mode.
- bool writer_acquire();
-
- /// Attempts to release the lock in writer mode.
- /// @returns false if any kind of error occurs, true otherwise.
- /// @brief Unconditionally release the lock in write mode.
- bool writer_release();
-
- //@}
- /// @name Platform Dependent Data
- /// @{
- private:
- void* data_; ///< We don't know what the data will be
-
- /// @}
- /// @name Do Not Implement
- /// @{
- private:
- RWMutexImpl(const RWMutexImpl & original);
- void operator=(const RWMutexImpl &);
- /// @}
- };
-
- /// SmartMutex - An R/W mutex with a compile time constant parameter that
- /// indicates whether this mutex should become a no-op when we're not
- /// running in multithreaded mode.
- template<bool mt_only>
- class SmartRWMutex : public RWMutexImpl {
- unsigned readers, writers;
- public:
- explicit SmartRWMutex() : RWMutexImpl(), readers(0), writers(0) { }
-
- bool reader_acquire() {
- if (!mt_only || llvm_is_multithreaded())
- return RWMutexImpl::reader_acquire();
-
- // Single-threaded debugging code. This would be racy in multithreaded
- // mode, but provides not sanity checks in single threaded mode.
- ++readers;
- return true;
- }
-
- bool reader_release() {
- if (!mt_only || llvm_is_multithreaded())
- return RWMutexImpl::reader_release();
-
- // Single-threaded debugging code. This would be racy in multithreaded
- // mode, but provides not sanity checks in single threaded mode.
- assert(readers > 0 && "Reader lock not acquired before release!");
- --readers;
- return true;
- }
-
- bool writer_acquire() {
- if (!mt_only || llvm_is_multithreaded())
- return RWMutexImpl::writer_acquire();
-
- // Single-threaded debugging code. This would be racy in multithreaded
- // mode, but provides not sanity checks in single threaded mode.
- assert(writers == 0 && "Writer lock already acquired!");
- ++writers;
- return true;
- }
-
- bool writer_release() {
- if (!mt_only || llvm_is_multithreaded())
- return RWMutexImpl::writer_release();
-
- // Single-threaded debugging code. This would be racy in multithreaded
- // mode, but provides not sanity checks in single threaded mode.
- assert(writers == 1 && "Writer lock not acquired before release!");
- --writers;
- return true;
- }
-
- private:
- SmartRWMutex(const SmartRWMutex<mt_only> & original);
- void operator=(const SmartRWMutex<mt_only> &);
- };
- typedef SmartRWMutex<false> RWMutex;
-
- /// ScopedReader - RAII acquisition of a reader lock
- template<bool mt_only>
- struct SmartScopedReader {
- SmartRWMutex<mt_only>& mutex;
-
- explicit SmartScopedReader(SmartRWMutex<mt_only>& m) : mutex(m) {
- mutex.reader_acquire();
- }
-
- ~SmartScopedReader() {
- mutex.reader_release();
- }
- };
- typedef SmartScopedReader<false> ScopedReader;
-
- /// ScopedWriter - RAII acquisition of a writer lock
- template<bool mt_only>
- struct SmartScopedWriter {
- SmartRWMutex<mt_only>& mutex;
-
- explicit SmartScopedWriter(SmartRWMutex<mt_only>& m) : mutex(m) {
- mutex.writer_acquire();
- }
-
- ~SmartScopedWriter() {
- mutex.writer_release();
- }
- };
- typedef SmartScopedWriter<false> ScopedWriter;
- }
-}
-
-#endif
+++ /dev/null
-//===- llvm/System/Signals.h - Signal Handling support ----------*- 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 some helpful functions for dealing with the possibility of
-// unix signals occuring while your program is running.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SYSTEM_SIGNALS_H
-#define LLVM_SYSTEM_SIGNALS_H
-
-#include "llvm/System/Path.h"
-
-namespace llvm {
-namespace sys {
-
- /// This function runs all the registered interrupt handlers, including the
- /// removal of files registered by RemoveFileOnSignal.
- void RunInterruptHandlers();
-
- /// This function registers signal handlers to ensure that if a signal gets
- /// delivered that the named file is removed.
- /// @brief Remove a file if a fatal signal occurs.
- bool RemoveFileOnSignal(const Path &Filename, std::string* ErrMsg = 0);
-
- /// This function removes a file from the list of files to be removed on
- /// signal delivery.
- void DontRemoveFileOnSignal(const Path &Filename);
-
- /// When an error signal (such as SIBABRT or SIGSEGV) is delivered to the
- /// process, print a stack trace and then exit.
- /// @brief Print a stack trace if a fatal signal occurs.
- void PrintStackTraceOnErrorSignal();
-
- /// AddSignalHandler - Add a function to be called when an abort/kill signal
- /// is delivered to the process. The handler can have a cookie passed to it
- /// to identify what instance of the handler it is.
- void AddSignalHandler(void (*FnPtr)(void *), void *Cookie);
-
- /// This function registers a function to be called when the user "interrupts"
- /// the program (typically by pressing ctrl-c). When the user interrupts the
- /// program, the specified interrupt function is called instead of the program
- /// being killed, and the interrupt function automatically disabled. Note
- /// that interrupt functions are not allowed to call any non-reentrant
- /// functions. An null interrupt function pointer disables the current
- /// installed function. Note also that the handler may be executed on a
- /// different thread on some platforms.
- /// @brief Register a function to be called when ctrl-c is pressed.
- void SetInterruptFunction(void (*IF)());
-} // End sys namespace
-} // End llvm namespace
-
-#endif
+++ /dev/null
-/*===- llvm/System/Solaris.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 contains portability fixes for Solaris hosts.
- *
- *===----------------------------------------------------------------------===*/
-
-#ifndef LLVM_SYSTEM_SOLARIS_H
-#define LLVM_SYSTEM_SOLARIS_H
-
-#include <sys/types.h>
-#include <sys/regset.h>
-
-#undef CS
-#undef DS
-#undef ES
-#undef FS
-#undef GS
-#undef SS
-#undef EAX
-#undef ECX
-#undef EDX
-#undef EBX
-#undef ESP
-#undef EBP
-#undef ESI
-#undef EDI
-#undef EIP
-#undef UESP
-#undef EFL
-#undef ERR
-#undef TRAPNO
-
-#endif
+++ /dev/null
-//===- SwapByteOrder.h - Generic and optimized byte swaps -------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares generic and optimized functions to swap the byte order of
-// an integral type.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SYSTEM_SWAP_BYTE_ORDER_H
-#define LLVM_SYSTEM_SWAP_BYTE_ORDER_H
-
-#include "llvm/System/DataTypes.h"
-#include <cstddef>
-#include <limits>
-
-namespace llvm {
-namespace sys {
-
-/// SwapByteOrder_16 - This function returns a byte-swapped representation of
-/// the 16-bit argument.
-inline uint16_t SwapByteOrder_16(uint16_t value) {
-#if defined(_MSC_VER) && !defined(_DEBUG)
- // The DLL version of the runtime lacks these functions (bug!?), but in a
- // release build they're replaced with BSWAP instructions anyway.
- return _byteswap_ushort(value);
-#else
- uint16_t Hi = value << 8;
- uint16_t Lo = value >> 8;
- return Hi | Lo;
-#endif
-}
-
-/// SwapByteOrder_32 - This function returns a byte-swapped representation of
-/// the 32-bit argument.
-inline uint32_t SwapByteOrder_32(uint32_t value) {
-#if defined(__llvm__) || \
-(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && !defined(__ICC)
- return __builtin_bswap32(value);
-#elif defined(_MSC_VER) && !defined(_DEBUG)
- return _byteswap_ulong(value);
-#else
- uint32_t Byte0 = value & 0x000000FF;
- uint32_t Byte1 = value & 0x0000FF00;
- uint32_t Byte2 = value & 0x00FF0000;
- uint32_t Byte3 = value & 0xFF000000;
- return (Byte0 << 24) | (Byte1 << 8) | (Byte2 >> 8) | (Byte3 >> 24);
-#endif
-}
-
-/// SwapByteOrder_64 - This function returns a byte-swapped representation of
-/// the 64-bit argument.
-inline uint64_t SwapByteOrder_64(uint64_t value) {
-#if defined(__llvm__) || \
-(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && !defined(__ICC)
- return __builtin_bswap64(value);
-#elif defined(_MSC_VER) && !defined(_DEBUG)
- return _byteswap_uint64(value);
-#else
- uint64_t Hi = SwapByteOrder_32(uint32_t(value));
- uint32_t Lo = SwapByteOrder_32(uint32_t(value >> 32));
- return (Hi << 32) | Lo;
-#endif
-}
-
-inline unsigned char SwapByteOrder(unsigned char C) { return C; }
-inline signed char SwapByteOrder(signed char C) { return C; }
-inline char SwapByteOrder(char C) { return C; }
-
-inline unsigned short SwapByteOrder(unsigned short C) { return SwapByteOrder_16(C); }
-inline signed short SwapByteOrder( signed short C) { return SwapByteOrder_16(C); }
-
-inline unsigned int SwapByteOrder(unsigned int C) { return SwapByteOrder_32(C); }
-inline signed int SwapByteOrder( signed int C) { return SwapByteOrder_32(C); }
-
-#if __LONG_MAX__ == __INT_MAX__
-inline unsigned long SwapByteOrder(unsigned long C) { return SwapByteOrder_32(C); }
-inline signed long SwapByteOrder( signed long C) { return SwapByteOrder_32(C); }
-#elif __LONG_MAX__ == __LONG_LONG_MAX__
-inline unsigned long SwapByteOrder(unsigned long C) { return SwapByteOrder_64(C); }
-inline signed long SwapByteOrder( signed long C) { return SwapByteOrder_64(C); }
-#else
-#error "Unknown long size!"
-#endif
-
-inline unsigned long long SwapByteOrder(unsigned long long C) {
- return SwapByteOrder_64(C);
-}
-inline signed long long SwapByteOrder(signed long long C) {
- return SwapByteOrder_64(C);
-}
-
-} // end namespace sys
-} // end namespace llvm
-
-#endif
+++ /dev/null
-//===- llvm/System/ThreadLocal.h - Thread Local Data ------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares the llvm::sys::ThreadLocal class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SYSTEM_THREAD_LOCAL_H
-#define LLVM_SYSTEM_THREAD_LOCAL_H
-
-#include "llvm/System/Threading.h"
-#include <cassert>
-
-namespace llvm {
- namespace sys {
- // ThreadLocalImpl - Common base class of all ThreadLocal instantiations.
- // YOU SHOULD NEVER USE THIS DIRECTLY.
- class ThreadLocalImpl {
- void* data;
- public:
- ThreadLocalImpl();
- virtual ~ThreadLocalImpl();
- void setInstance(const void* d);
- const void* getInstance();
- void removeInstance();
- };
-
- /// ThreadLocal - A class used to abstract thread-local storage. It holds,
- /// for each thread, a pointer a single object of type T.
- template<class T>
- class ThreadLocal : public ThreadLocalImpl {
- public:
- ThreadLocal() : ThreadLocalImpl() { }
-
- /// get - Fetches a pointer to the object associated with the current
- /// thread. If no object has yet been associated, it returns NULL;
- T* get() { return static_cast<T*>(getInstance()); }
-
- // set - Associates a pointer to an object with the current thread.
- void set(T* d) { setInstance(d); }
-
- // erase - Removes the pointer associated with the current thread.
- void erase() { removeInstance(); }
- };
- }
-}
-
-#endif
+++ /dev/null
-//===-- llvm/System/Threading.h - Control multithreading mode --*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// TThis file defines llvm_start_multithreaded() and friends.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SYSTEM_THREADING_H
-#define LLVM_SYSTEM_THREADING_H
-
-namespace llvm {
- /// llvm_start_multithreaded - Allocate and initialize structures needed to
- /// make LLVM safe for multithreading. The return value indicates whether
- /// multithreaded initialization succeeded. LLVM will still be operational
- /// on "failed" return, and will still be safe for hosting threading
- /// applications in the JIT, but will not be safe for concurrent calls to the
- /// LLVM APIs.
- /// THIS MUST EXECUTE IN ISOLATION FROM ALL OTHER LLVM API CALLS.
- bool llvm_start_multithreaded();
-
- /// llvm_stop_multithreaded - Deallocate structures necessary to make LLVM
- /// safe for multithreading.
- /// THIS MUST EXECUTE IN ISOLATION FROM ALL OTHER LLVM API CALLS.
- void llvm_stop_multithreaded();
-
- /// llvm_is_multithreaded - Check whether LLVM is executing in thread-safe
- /// mode or not.
- bool llvm_is_multithreaded();
-
- /// acquire_global_lock - Acquire the global lock. This is a no-op if called
- /// before llvm_start_multithreaded().
- void llvm_acquire_global_lock();
-
- /// release_global_lock - Release the global lock. This is a no-op if called
- /// before llvm_start_multithreaded().
- void llvm_release_global_lock();
-
- /// llvm_execute_on_thread - Execute the given \arg UserFn on a separate
- /// thread, passing it the provided \arg UserData.
- ///
- /// This function does not guarantee that the code will actually be executed
- /// on a separate thread or honoring the requested stack size, but tries to do
- /// so where system support is available.
- ///
- /// \param UserFn - The callback to execute.
- /// \param UserData - An argument to pass to the callback function.
- /// \param RequestedStackSize - If non-zero, a requested size (in bytes) for
- /// the thread stack.
- void llvm_execute_on_thread(void (*UserFn)(void*), void *UserData,
- unsigned RequestedStackSize = 0);
-}
-
-#endif
+++ /dev/null
-//===-- TimeValue.h - Declare OS TimeValue Concept --------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This header file declares the operating system TimeValue concept.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/System/DataTypes.h"
-#include <string>
-
-#ifndef LLVM_SYSTEM_TIMEVALUE_H
-#define LLVM_SYSTEM_TIMEVALUE_H
-
-namespace llvm {
-namespace sys {
- /// This class is used where a precise fixed point in time is required. The
- /// range of TimeValue spans many hundreds of billions of years both past and
- /// present. The precision of TimeValue is to the nanosecond. However, the
- /// actual precision of its values will be determined by the resolution of
- /// the system clock. The TimeValue class is used in conjunction with several
- /// other lib/System interfaces to specify the time at which a call should
- /// timeout, etc.
- /// @since 1.4
- /// @brief Provides an abstraction for a fixed point in time.
- class TimeValue {
-
- /// @name Constants
- /// @{
- public:
-
- /// A constant TimeValue representing the smallest time
- /// value permissable by the class. MinTime is some point
- /// in the distant past, about 300 billion years BCE.
- /// @brief The smallest possible time value.
- static const TimeValue MinTime;
-
- /// A constant TimeValue representing the largest time
- /// value permissable by the class. MaxTime is some point
- /// in the distant future, about 300 billion years AD.
- /// @brief The largest possible time value.
- static const TimeValue MaxTime;
-
- /// A constant TimeValue representing the base time,
- /// or zero time of 00:00:00 (midnight) January 1st, 2000.
- /// @brief 00:00:00 Jan 1, 2000 UTC.
- static const TimeValue ZeroTime;
-
- /// A constant TimeValue for the Posix base time which is
- /// 00:00:00 (midnight) January 1st, 1970.
- /// @brief 00:00:00 Jan 1, 1970 UTC.
- static const TimeValue PosixZeroTime;
-
- /// A constant TimeValue for the Win32 base time which is
- /// 00:00:00 (midnight) January 1st, 1601.
- /// @brief 00:00:00 Jan 1, 1601 UTC.
- static const TimeValue Win32ZeroTime;
-
- /// @}
- /// @name Types
- /// @{
- public:
- typedef int64_t SecondsType; ///< Type used for representing seconds.
- typedef int32_t NanoSecondsType;///< Type used for representing nanoseconds.
-
- enum TimeConversions {
- NANOSECONDS_PER_SECOND = 1000000000, ///< One Billion
- MICROSECONDS_PER_SECOND = 1000000, ///< One Million
- MILLISECONDS_PER_SECOND = 1000, ///< One Thousand
- NANOSECONDS_PER_MICROSECOND = 1000, ///< One Thousand
- NANOSECONDS_PER_MILLISECOND = 1000000,///< One Million
- NANOSECONDS_PER_POSIX_TICK = 100, ///< Posix tick is 100 Hz (10ms)
- NANOSECONDS_PER_WIN32_TICK = 100 ///< Win32 tick is 100 Hz (10ms)
- };
-
- /// @}
- /// @name Constructors
- /// @{
- public:
- /// Caller provides the exact value in seconds and nanoseconds. The
- /// \p nanos argument defaults to zero for convenience.
- /// @brief Explicit constructor
- explicit TimeValue (SecondsType seconds, NanoSecondsType nanos = 0)
- : seconds_( seconds ), nanos_( nanos ) { this->normalize(); }
-
- /// Caller provides the exact value as a double in seconds with the
- /// fractional part representing nanoseconds.
- /// @brief Double Constructor.
- explicit TimeValue( double new_time )
- : seconds_( 0 ) , nanos_ ( 0 ) {
- SecondsType integer_part = static_cast<SecondsType>( new_time );
- seconds_ = integer_part;
- nanos_ = static_cast<NanoSecondsType>( (new_time -
- static_cast<double>(integer_part)) * NANOSECONDS_PER_SECOND );
- this->normalize();
- }
-
- /// This is a static constructor that returns a TimeValue that represents
- /// the current time.
- /// @brief Creates a TimeValue with the current time (UTC).
- static TimeValue now();
-
- /// @}
- /// @name Operators
- /// @{
- public:
- /// Add \p that to \p this.
- /// @returns this
- /// @brief Incrementing assignment operator.
- TimeValue& operator += (const TimeValue& that ) {
- this->seconds_ += that.seconds_ ;
- this->nanos_ += that.nanos_ ;
- this->normalize();
- return *this;
- }
-
- /// Subtract \p that from \p this.
- /// @returns this
- /// @brief Decrementing assignment operator.
- TimeValue& operator -= (const TimeValue &that ) {
- this->seconds_ -= that.seconds_ ;
- this->nanos_ -= that.nanos_ ;
- this->normalize();
- return *this;
- }
-
- /// Determine if \p this is less than \p that.
- /// @returns True iff *this < that.
- /// @brief True if this < that.
- int operator < (const TimeValue &that) const { return that > *this; }
-
- /// Determine if \p this is greather than \p that.
- /// @returns True iff *this > that.
- /// @brief True if this > that.
- int operator > (const TimeValue &that) const {
- if ( this->seconds_ > that.seconds_ ) {
- return 1;
- } else if ( this->seconds_ == that.seconds_ ) {
- if ( this->nanos_ > that.nanos_ ) return 1;
- }
- return 0;
- }
-
- /// Determine if \p this is less than or equal to \p that.
- /// @returns True iff *this <= that.
- /// @brief True if this <= that.
- int operator <= (const TimeValue &that) const { return that >= *this; }
-
- /// Determine if \p this is greater than or equal to \p that.
- /// @returns True iff *this >= that.
- /// @brief True if this >= that.
- int operator >= (const TimeValue &that) const {
- if ( this->seconds_ > that.seconds_ ) {
- return 1;
- } else if ( this->seconds_ == that.seconds_ ) {
- if ( this->nanos_ >= that.nanos_ ) return 1;
- }
- return 0;
- }
-
- /// Determines if two TimeValue objects represent the same moment in time.
- /// @brief True iff *this == that.
- /// @brief True if this == that.
- int operator == (const TimeValue &that) const {
- return (this->seconds_ == that.seconds_) &&
- (this->nanos_ == that.nanos_);
- }
-
- /// Determines if two TimeValue objects represent times that are not the
- /// same.
- /// @return True iff *this != that.
- /// @brief True if this != that.
- int operator != (const TimeValue &that) const { return !(*this == that); }
-
- /// Adds two TimeValue objects together.
- /// @returns The sum of the two operands as a new TimeValue
- /// @brief Addition operator.
- friend TimeValue operator + (const TimeValue &tv1, const TimeValue &tv2);
-
- /// Subtracts two TimeValue objects.
- /// @returns The difference of the two operands as a new TimeValue
- /// @brief Subtraction operator.
- friend TimeValue operator - (const TimeValue &tv1, const TimeValue &tv2);
-
- /// @}
- /// @name Accessors
- /// @{
- public:
-
- /// Returns only the seconds component of the TimeValue. The nanoseconds
- /// portion is ignored. No rounding is performed.
- /// @brief Retrieve the seconds component
- SecondsType seconds() const { return seconds_; }
-
- /// Returns only the nanoseconds component of the TimeValue. The seconds
- /// portion is ignored.
- /// @brief Retrieve the nanoseconds component.
- NanoSecondsType nanoseconds() const { return nanos_; }
-
- /// Returns only the fractional portion of the TimeValue rounded down to the
- /// nearest microsecond (divide by one thousand).
- /// @brief Retrieve the fractional part as microseconds;
- uint32_t microseconds() const {
- return nanos_ / NANOSECONDS_PER_MICROSECOND;
- }
-
- /// Returns only the fractional portion of the TimeValue rounded down to the
- /// nearest millisecond (divide by one million).
- /// @brief Retrieve the fractional part as milliseconds;
- uint32_t milliseconds() const {
- return nanos_ / NANOSECONDS_PER_MILLISECOND;
- }
-
- /// Returns the TimeValue as a number of microseconds. Note that the value
- /// returned can overflow because the range of a uint64_t is smaller than
- /// the range of a TimeValue. Nevertheless, this is useful on some operating
- /// systems and is therefore provided.
- /// @brief Convert to a number of microseconds (can overflow)
- uint64_t usec() const {
- return seconds_ * MICROSECONDS_PER_SECOND +
- ( nanos_ / NANOSECONDS_PER_MICROSECOND );
- }
-
- /// Returns the TimeValue as a number of milliseconds. Note that the value
- /// returned can overflow because the range of a uint64_t is smaller than
- /// the range of a TimeValue. Nevertheless, this is useful on some operating
- /// systems and is therefore provided.
- /// @brief Convert to a number of milliseconds (can overflow)
- uint64_t msec() const {
- return seconds_ * MILLISECONDS_PER_SECOND +
- ( nanos_ / NANOSECONDS_PER_MILLISECOND );
- }
-
- /// Converts the TimeValue into the corresponding number of "ticks" for
- /// Posix, correcting for the difference in Posix zero time.
- /// @brief Convert to unix time (100 nanoseconds since 12:00:00a Jan 1,1970)
- uint64_t toPosixTime() const {
- uint64_t result = seconds_ - PosixZeroTime.seconds_;
- result += nanos_ / NANOSECONDS_PER_POSIX_TICK;
- return result;
- }
-
- /// Converts the TimeValue into the corresponding number of seconds
- /// since the epoch (00:00:00 Jan 1,1970).
- uint64_t toEpochTime() const {
- return seconds_ - PosixZeroTime.seconds_;
- }
-
- /// Converts the TimeValue into the corresponding number of "ticks" for
- /// Win32 platforms, correcting for the difference in Win32 zero time.
- /// @brief Convert to windows time (seconds since 12:00:00a Jan 1, 1601)
- uint64_t toWin32Time() const {
- uint64_t result = seconds_ - Win32ZeroTime.seconds_;
- result += nanos_ / NANOSECONDS_PER_WIN32_TICK;
- return result;
- }
-
- /// Provides the seconds and nanoseconds as results in its arguments after
- /// correction for the Posix zero time.
- /// @brief Convert to timespec time (ala POSIX.1b)
- void getTimespecTime( uint64_t& seconds, uint32_t& nanos ) const {
- seconds = seconds_ - PosixZeroTime.seconds_;
- nanos = nanos_;
- }
-
- /// Provides conversion of the TimeValue into a readable time & date.
- /// @returns std::string containing the readable time value
- /// @brief Convert time to a string.
- std::string str() const;
-
- /// @}
- /// @name Mutators
- /// @{
- public:
- /// The seconds component of the TimeValue is set to \p sec without
- /// modifying the nanoseconds part. This is useful for whole second
- /// arithmetic.
- /// @brief Set the seconds component.
- void seconds (SecondsType sec ) {
- this->seconds_ = sec;
- this->normalize();
- }
-
- /// The nanoseconds component of the TimeValue is set to \p nanos without
- /// modifying the seconds part. This is useful for basic computations
- /// involving just the nanoseconds portion. Note that the TimeValue will be
- /// normalized after this call so that the fractional (nanoseconds) portion
- /// will have the smallest equivalent value.
- /// @brief Set the nanoseconds component using a number of nanoseconds.
- void nanoseconds ( NanoSecondsType nanos ) {
- this->nanos_ = nanos;
- this->normalize();
- }
-
- /// The seconds component remains unchanged.
- /// @brief Set the nanoseconds component using a number of microseconds.
- void microseconds ( int32_t micros ) {
- this->nanos_ = micros * NANOSECONDS_PER_MICROSECOND;
- this->normalize();
- }
-
- /// The seconds component remains unchanged.
- /// @brief Set the nanoseconds component using a number of milliseconds.
- void milliseconds ( int32_t millis ) {
- this->nanos_ = millis * NANOSECONDS_PER_MILLISECOND;
- this->normalize();
- }
-
- /// @brief Converts from microsecond format to TimeValue format
- void usec( int64_t microseconds ) {
- this->seconds_ = microseconds / MICROSECONDS_PER_SECOND;
- this->nanos_ = NanoSecondsType(microseconds % MICROSECONDS_PER_SECOND) *
- NANOSECONDS_PER_MICROSECOND;
- this->normalize();
- }
-
- /// @brief Converts from millisecond format to TimeValue format
- void msec( int64_t milliseconds ) {
- this->seconds_ = milliseconds / MILLISECONDS_PER_SECOND;
- this->nanos_ = NanoSecondsType(milliseconds % MILLISECONDS_PER_SECOND) *
- NANOSECONDS_PER_MILLISECOND;
- this->normalize();
- }
-
- /// Converts the \p seconds argument from PosixTime to the corresponding
- /// TimeValue and assigns that value to \p this.
- /// @brief Convert seconds form PosixTime to TimeValue
- void fromEpochTime( SecondsType seconds ) {
- seconds_ = seconds + PosixZeroTime.seconds_;
- nanos_ = 0;
- this->normalize();
- }
-
- /// Converts the \p win32Time argument from Windows FILETIME to the
- /// corresponding TimeValue and assigns that value to \p this.
- /// @brief Convert seconds form Windows FILETIME to TimeValue
- void fromWin32Time( uint64_t win32Time ) {
- this->seconds_ = win32Time / 10000000 + Win32ZeroTime.seconds_;
- this->nanos_ = NanoSecondsType(win32Time % 10000000) * 100;
- }
-
- /// @}
- /// @name Implementation
- /// @{
- private:
- /// This causes the values to be represented so that the fractional
- /// part is minimized, possibly incrementing the seconds part.
- /// @brief Normalize to canonical form.
- void normalize();
-
- /// @}
- /// @name Data
- /// @{
- private:
- /// Store the values as a <timeval>.
- SecondsType seconds_;///< Stores the seconds part of the TimeVal
- NanoSecondsType nanos_; ///< Stores the nanoseconds part of the TimeVal
- /// @}
-
- };
-
-inline TimeValue operator + (const TimeValue &tv1, const TimeValue &tv2) {
- TimeValue sum (tv1.seconds_ + tv2.seconds_, tv1.nanos_ + tv2.nanos_);
- sum.normalize ();
- return sum;
-}
-
-inline TimeValue operator - (const TimeValue &tv1, const TimeValue &tv2) {
- TimeValue difference (tv1.seconds_ - tv2.seconds_, tv1.nanos_ - tv2.nanos_ );
- difference.normalize ();
- return difference;
-}
-
-}
-}
-
-#endif
+++ /dev/null
-//===- llvm/System/Valgrind.h - Communication with Valgrind -----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Methods for communicating with a valgrind instance this program is running
-// under. These are all no-ops unless LLVM was configured on a system with the
-// valgrind headers installed and valgrind is controlling this process.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SYSTEM_VALGRIND_H
-#define LLVM_SYSTEM_VALGRIND_H
-
-#include <stddef.h>
-
-namespace llvm {
-namespace sys {
- // True if Valgrind is controlling this process.
- bool RunningOnValgrind();
-
- // Discard valgrind's translation of code in the range [Addr .. Addr + Len).
- // Otherwise valgrind may continue to execute the old version of the code.
- void ValgrindDiscardTranslations(const void *Addr, size_t Len);
-}
-}
-
-#endif
+++ /dev/null
-//===---------------------------- system_error ----------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This was lifted from libc++ and modified for C++03. This is called
-// system_error even though it does not define that class because that's what
-// it's called in C++0x. We don't define system_error because it is only used
-// for exception handling, which we don't use in LLVM.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SYSTEM_SYSTEM_ERROR_H
-#define LLVM_SYSTEM_SYSTEM_ERROR_H
-
-/*
- system_error synopsis
-
-namespace std
-{
-
-class error_category
-{
-public:
- virtual ~error_category();
-
- error_category(const error_category&) = delete;
- error_category& operator=(const error_category&) = delete;
-
- virtual const char* name() const = 0;
- virtual error_condition default_error_condition(int ev) const;
- virtual bool equivalent(int code, const error_condition& condition) const;
- virtual bool equivalent(const error_code& code, int condition) const;
- virtual std::string message(int ev) const = 0;
-
- bool operator==(const error_category& rhs) const;
- bool operator!=(const error_category& rhs) const;
- bool operator<(const error_category& rhs) const;
-};
-
-const error_category& generic_category();
-const error_category& system_category();
-
-template <class T> struct is_error_code_enum
- : public false_type {};
-
-template <class T> struct is_error_condition_enum
- : public false_type {};
-
-class error_code
-{
-public:
- // constructors:
- error_code();
- error_code(int val, const error_category& cat);
- template <class ErrorCodeEnum>
- error_code(ErrorCodeEnum e);
-
- // modifiers:
- void assign(int val, const error_category& cat);
- template <class ErrorCodeEnum>
- error_code& operator=(ErrorCodeEnum e);
- void clear();
-
- // observers:
- int value() const;
- const error_category& category() const;
- error_condition default_error_condition() const;
- std::string message() const;
- explicit operator bool() const;
-};
-
-// non-member functions:
-bool operator<(const error_code& lhs, const error_code& rhs);
-template <class charT, class traits>
- basic_ostream<charT,traits>&
- operator<<(basic_ostream<charT,traits>& os, const error_code& ec);
-
-class error_condition
-{
-public:
- // constructors:
- error_condition();
- error_condition(int val, const error_category& cat);
- template <class ErrorConditionEnum>
- error_condition(ErrorConditionEnum e);
-
- // modifiers:
- void assign(int val, const error_category& cat);
- template <class ErrorConditionEnum>
- error_condition& operator=(ErrorConditionEnum e);
- void clear();
-
- // observers:
- int value() const;
- const error_category& category() const;
- std::string message() const;
- explicit operator bool() const;
-};
-
-bool operator<(const error_condition& lhs, const error_condition& rhs);
-
-class system_error
- : public runtime_error
-{
-public:
- system_error(error_code ec, const std::string& what_arg);
- system_error(error_code ec, const char* what_arg);
- system_error(error_code ec);
- system_error(int ev, const error_category& ecat, const std::string& what_arg);
- system_error(int ev, const error_category& ecat, const char* what_arg);
- system_error(int ev, const error_category& ecat);
-
- const error_code& code() const throw();
- const char* what() const throw();
-};
-
-enum class errc
-{
- address_family_not_supported, // EAFNOSUPPORT
- address_in_use, // EADDRINUSE
- address_not_available, // EADDRNOTAVAIL
- already_connected, // EISCONN
- argument_list_too_long, // E2BIG
- argument_out_of_domain, // EDOM
- bad_address, // EFAULT
- bad_file_descriptor, // EBADF
- bad_message, // EBADMSG
- broken_pipe, // EPIPE
- connection_aborted, // ECONNABORTED
- connection_already_in_progress, // EALREADY
- connection_refused, // ECONNREFUSED
- connection_reset, // ECONNRESET
- cross_device_link, // EXDEV
- destination_address_required, // EDESTADDRREQ
- device_or_resource_busy, // EBUSY
- directory_not_empty, // ENOTEMPTY
- executable_format_error, // ENOEXEC
- file_exists, // EEXIST
- file_too_large, // EFBIG
- filename_too_long, // ENAMETOOLONG
- function_not_supported, // ENOSYS
- host_unreachable, // EHOSTUNREACH
- identifier_removed, // EIDRM
- illegal_byte_sequence, // EILSEQ
- inappropriate_io_control_operation, // ENOTTY
- interrupted, // EINTR
- invalid_argument, // EINVAL
- invalid_seek, // ESPIPE
- io_error, // EIO
- is_a_directory, // EISDIR
- message_size, // EMSGSIZE
- network_down, // ENETDOWN
- network_reset, // ENETRESET
- network_unreachable, // ENETUNREACH
- no_buffer_space, // ENOBUFS
- no_child_process, // ECHILD
- no_link, // ENOLINK
- no_lock_available, // ENOLCK
- no_message_available, // ENODATA
- no_message, // ENOMSG
- no_protocol_option, // ENOPROTOOPT
- no_space_on_device, // ENOSPC
- no_stream_resources, // ENOSR
- no_such_device_or_address, // ENXIO
- no_such_device, // ENODEV
- no_such_file_or_directory, // ENOENT
- no_such_process, // ESRCH
- not_a_directory, // ENOTDIR
- not_a_socket, // ENOTSOCK
- not_a_stream, // ENOSTR
- not_connected, // ENOTCONN
- not_enough_memory, // ENOMEM
- not_supported, // ENOTSUP
- operation_canceled, // ECANCELED
- operation_in_progress, // EINPROGRESS
- operation_not_permitted, // EPERM
- operation_not_supported, // EOPNOTSUPP
- operation_would_block, // EWOULDBLOCK
- owner_dead, // EOWNERDEAD
- permission_denied, // EACCES
- protocol_error, // EPROTO
- protocol_not_supported, // EPROTONOSUPPORT
- read_only_file_system, // EROFS
- resource_deadlock_would_occur, // EDEADLK
- resource_unavailable_try_again, // EAGAIN
- result_out_of_range, // ERANGE
- state_not_recoverable, // ENOTRECOVERABLE
- stream_timeout, // ETIME
- text_file_busy, // ETXTBSY
- timed_out, // ETIMEDOUT
- too_many_files_open_in_system, // ENFILE
- too_many_files_open, // EMFILE
- too_many_links, // EMLINK
- too_many_symbolic_link_levels, // ELOOP
- value_too_large, // EOVERFLOW
- wrong_protocol_type // EPROTOTYPE
-};
-
-template <> struct is_error_condition_enum<errc> : true_type { }
-
-error_code make_error_code(errc e);
-error_condition make_error_condition(errc e);
-
-// Comparison operators:
-bool operator==(const error_code& lhs, const error_code& rhs);
-bool operator==(const error_code& lhs, const error_condition& rhs);
-bool operator==(const error_condition& lhs, const error_code& rhs);
-bool operator==(const error_condition& lhs, const error_condition& rhs);
-bool operator!=(const error_code& lhs, const error_code& rhs);
-bool operator!=(const error_code& lhs, const error_condition& rhs);
-bool operator!=(const error_condition& lhs, const error_code& rhs);
-bool operator!=(const error_condition& lhs, const error_condition& rhs);
-
-template <> struct hash<std::error_code>;
-
-} // std
-
-*/
-
-#include "llvm/Config/config.h"
-#include "llvm/Support/type_traits.h"
-#include <cerrno>
-#include <string>
-
-// This must be here instead of a .inc file because it is used in the definition
-// of the enum values below.
-#ifdef LLVM_ON_WIN32
- // VS 2008 needs this for some of the defines below.
-# include <WinSock2.h>
-
- // The following numbers were taken from VS2010.
-# ifndef EAFNOSUPPORT
-# define EAFNOSUPPORT WSAEAFNOSUPPORT
-# endif
-# ifndef EADDRINUSE
-# define EADDRINUSE WSAEADDRINUSE
-# endif
-# ifndef EADDRNOTAVAIL
-# define EADDRNOTAVAIL WSAEADDRNOTAVAIL
-# endif
-# ifndef EISCONN
-# define EISCONN WSAEISCONN
-# endif
-# ifndef E2BIG
-# define E2BIG WSAE2BIG
-# endif
-# ifndef EDOM
-# define EDOM WSAEDOM
-# endif
-# ifndef EFAULT
-# define EFAULT WSAEFAULT
-# endif
-# ifndef EBADF
-# define EBADF WSAEBADF
-# endif
-# ifndef EBADMSG
-# define EBADMSG 104
-# endif
-# ifndef EPIPE
-# define EPIPE WSAEPIPE
-# endif
-# ifndef ECONNABORTED
-# define ECONNABORTED WSAECONNABORTED
-# endif
-# ifndef EALREADY
-# define EALREADY WSAEALREADY
-# endif
-# ifndef ECONNREFUSED
-# define ECONNREFUSED WSAECONNREFUSED
-# endif
-# ifndef ECONNRESET
-# define ECONNRESET WSAECONNRESET
-# endif
-# ifndef EXDEV
-# define EXDEV WSAEXDEV
-# endif
-# ifndef EDESTADDRREQ
-# define EDESTADDRREQ WSAEDESTADDRREQ
-# endif
-# ifndef EBUSY
-# define EBUSY WSAEBUSY
-# endif
-# ifndef ENOTEMPTY
-# define ENOTEMPTY WSAENOTEMPTY
-# endif
-# ifndef ENOEXEC
-# define ENOEXEC WSAENOEXEC
-# endif
-# ifndef EEXIST
-# define EEXIST WSAEEXIST
-# endif
-# ifndef EFBIG
-# define EFBIG WSAEFBIG
-# endif
-# ifndef ENAMETOOLONG
-# define ENAMETOOLONG WSAENAMETOOLONG
-# endif
-# ifndef ENOSYS
-# define ENOSYS WSAENOSYS
-# endif
-# ifndef EHOSTUNREACH
-# define EHOSTUNREACH WSAEHOSTUNREACH
-# endif
-# ifndef EIDRM
-# define EIDRM 111
-# endif
-# ifndef EILSEQ
-# define EILSEQ WSAEILSEQ
-# endif
-# ifndef ENOTTY
-# define ENOTTY WSAENOTTY
-# endif
-# ifndef EINTR
-# define EINTR WSAEINTR
-# endif
-# ifndef EINVAL
-# define EINVAL WSAEINVAL
-# endif
-# ifndef ESPIPE
-# define ESPIPE WSAESPIPE
-# endif
-# ifndef EIO
-# define EIO WSAEIO
-# endif
-# ifndef EISDIR
-# define EISDIR WSAEISDIR
-# endif
-# ifndef EMSGSIZE
-# define EMSGSIZE WSAEMSGSIZE
-# endif
-# ifndef ENETDOWN
-# define ENETDOWN WSAENETDOWN
-# endif
-# ifndef ENETRESET
-# define ENETRESET WSAENETRESET
-# endif
-# ifndef ENETUNREACH
-# define ENETUNREACH WSAENETUNREACH
-# endif
-# ifndef ENOBUFS
-# define ENOBUFS WSAENOBUFS
-# endif
-# ifndef ECHILD
-# define ECHILD WSAECHILD
-# endif
-# ifndef ENOLINK
-# define ENOLINK 121
-# endif
-# ifndef ENOLCK
-# define ENOLCK WSAENOLCK
-# endif
-# ifndef ENODATA
-# define ENODATA 120
-# endif
-# ifndef ENOMSG
-# define ENOMSG 122
-# endif
-# ifndef ENOPROTOOPT
-# define ENOPROTOOPT WSAENOPROTOOPT
-# endif
-# ifndef ENOSPC
-# define ENOSPC WSAENOSPC
-# endif
-# ifndef ENOSR
-# define ENOSR 124
-# endif
-# ifndef ENXIO
-# define ENXIO WSAENXIO
-# endif
-# ifndef ENODEV
-# define ENODEV WSAENODEV
-# endif
-# ifndef ENOENT
-# define ENOENT WSAENOENT
-# endif
-# ifndef ESRCH
-# define ESRCH WSAESRCH
-# endif
-# ifndef ENOTDIR
-# define ENOTDIR WSAENOTDIR
-# endif
-# ifndef ENOTSOCK
-# define ENOTSOCK WSAENOTSOCK
-# endif
-# ifndef ENOSTR
-# define ENOSTR 125
-# endif
-# ifndef ENOTCONN
-# define ENOTCONN WSAENOTCONN
-# endif
-# ifndef ENOMEM
-# define ENOMEM WSAENOMEM
-# endif
-# ifndef ENOTSUP
-# define ENOTSUP 129
-# endif
-# ifndef ECANCELED
-# define ECANCELED 105
-# endif
-# ifndef EINPROGRESS
-# define EINPROGRESS WSAEINPROGRESS
-# endif
-# ifndef EPERM
-# define EPERM WSAEPERM
-# endif
-# ifndef EOPNOTSUPP
-# define EOPNOTSUPP WSAEOPNOTSUPP
-# endif
-# ifndef EWOULDBLOCK
-# define EWOULDBLOCK WSAEWOULDBLOCK
-# endif
-# ifndef EOWNERDEAD
-# define EOWNERDEAD 133
-# endif
-# ifndef EACCES
-# define EACCES WSAEACCES
-# endif
-# ifndef EPROTO
-# define EPROTO 134
-# endif
-# ifndef EPROTONOSUPPORT
-# define EPROTONOSUPPORT WSAEPROTONOSUPPORT
-# endif
-# ifndef EROFS
-# define EROFS WSAEROFS
-# endif
-# ifndef EDEADLK
-# define EDEADLK WSAEDEADLK
-# endif
-# ifndef EAGAIN
-# define EAGAIN WSAEAGAIN
-# endif
-# ifndef ERANGE
-# define ERANGE WSAERANGE
-# endif
-# ifndef ENOTRECOVERABLE
-# define ENOTRECOVERABLE 127
-# endif
-# ifndef ETIME
-# define ETIME 137
-# endif
-# ifndef ETXTBSY
-# define ETXTBSY 139
-# endif
-# ifndef ETIMEDOUT
-# define ETIMEDOUT WSAETIMEDOUT
-# endif
-# ifndef ENFILE
-# define ENFILE WSAENFILE
-# endif
-# ifndef EMFILE
-# define EMFILE WSAEMFILE
-# endif
-# ifndef EMLINK
-# define EMLINK WSAEMLINK
-# endif
-# ifndef ELOOP
-# define ELOOP WSAELOOP
-# endif
-# ifndef EOVERFLOW
-# define EOVERFLOW 132
-# endif
-# ifndef EPROTOTYPE
-# define EPROTOTYPE WSAEPROTOTYPE
-# endif
-#endif
-
-namespace llvm {
-
-template <class T, T v>
-struct integral_constant {
- typedef T value_type;
- static const value_type value = v;
- typedef integral_constant<T,v> type;
- operator value_type() { return value; }
-};
-
-typedef integral_constant<bool, true> true_type;
-typedef integral_constant<bool, false> false_type;
-
-// is_error_code_enum
-
-template <class Tp> struct is_error_code_enum : public false_type {};
-
-// is_error_condition_enum
-
-template <class Tp> struct is_error_condition_enum : public false_type {};
-
-// Some error codes are not present on all platforms, so we provide equivalents
-// for them:
-
-//enum class errc
-struct errc {
-enum _ {
- success = 0,
- address_family_not_supported = EAFNOSUPPORT,
- address_in_use = EADDRINUSE,
- address_not_available = EADDRNOTAVAIL,
- already_connected = EISCONN,
- argument_list_too_long = E2BIG,
- argument_out_of_domain = EDOM,
- bad_address = EFAULT,
- bad_file_descriptor = EBADF,
-#ifdef EBADMSG
- bad_message = EBADMSG,
-#else
- bad_message = EINVAL,
-#endif
- broken_pipe = EPIPE,
- connection_aborted = ECONNABORTED,
- connection_already_in_progress = EALREADY,
- connection_refused = ECONNREFUSED,
- connection_reset = ECONNRESET,
- cross_device_link = EXDEV,
- destination_address_required = EDESTADDRREQ,
- device_or_resource_busy = EBUSY,
- directory_not_empty = ENOTEMPTY,
- executable_format_error = ENOEXEC,
- file_exists = EEXIST,
- file_too_large = EFBIG,
- filename_too_long = ENAMETOOLONG,
- function_not_supported = ENOSYS,
- host_unreachable = EHOSTUNREACH,
- identifier_removed = EIDRM,
- illegal_byte_sequence = EILSEQ,
- inappropriate_io_control_operation = ENOTTY,
- interrupted = EINTR,
- invalid_argument = EINVAL,
- invalid_seek = ESPIPE,
- io_error = EIO,
- is_a_directory = EISDIR,
- message_size = EMSGSIZE,
- network_down = ENETDOWN,
- network_reset = ENETRESET,
- network_unreachable = ENETUNREACH,
- no_buffer_space = ENOBUFS,
- no_child_process = ECHILD,
-#ifdef ENOLINK
- no_link = ENOLINK,
-#else
- no_link = EINVAL,
-#endif
- no_lock_available = ENOLCK,
-#ifdef ENODATA
- no_message_available = ENODATA,
-#else
- no_message_available = ENOMSG,
-#endif
- no_message = ENOMSG,
- no_protocol_option = ENOPROTOOPT,
- no_space_on_device = ENOSPC,
-#ifdef ENOSR
- no_stream_resources = ENOSR,
-#else
- no_stream_resources = ENOMEM,
-#endif
- no_such_device_or_address = ENXIO,
- no_such_device = ENODEV,
- no_such_file_or_directory = ENOENT,
- no_such_process = ESRCH,
- not_a_directory = ENOTDIR,
- not_a_socket = ENOTSOCK,
-#ifdef ENOSTR
- not_a_stream = ENOSTR,
-#else
- not_a_stream = EINVAL,
-#endif
- not_connected = ENOTCONN,
- not_enough_memory = ENOMEM,
- not_supported = ENOTSUP,
-#ifdef ECANCELED
- operation_canceled = ECANCELED,
-#else
- operation_canceled = EINVAL,
-#endif
- operation_in_progress = EINPROGRESS,
- operation_not_permitted = EPERM,
- operation_not_supported = EOPNOTSUPP,
- operation_would_block = EWOULDBLOCK,
-#ifdef EOWNERDEAD
- owner_dead = EOWNERDEAD,
-#else
- owner_dead = EINVAL,
-#endif
- permission_denied = EACCES,
-#ifdef EPROTO
- protocol_error = EPROTO,
-#else
- protocol_error = EINVAL,
-#endif
- protocol_not_supported = EPROTONOSUPPORT,
- read_only_file_system = EROFS,
- resource_deadlock_would_occur = EDEADLK,
- resource_unavailable_try_again = EAGAIN,
- result_out_of_range = ERANGE,
-#ifdef ENOTRECOVERABLE
- state_not_recoverable = ENOTRECOVERABLE,
-#else
- state_not_recoverable = EINVAL,
-#endif
-#ifdef ETIME
- stream_timeout = ETIME,
-#else
- stream_timeout = ETIMEDOUT,
-#endif
- text_file_busy = ETXTBSY,
- timed_out = ETIMEDOUT,
- too_many_files_open_in_system = ENFILE,
- too_many_files_open = EMFILE,
- too_many_links = EMLINK,
- too_many_symbolic_link_levels = ELOOP,
- value_too_large = EOVERFLOW,
- wrong_protocol_type = EPROTOTYPE
-};
-
- _ v_;
-
- errc(_ v) : v_(v) {}
- operator int() const {return v_;}
-};
-
-template <> struct is_error_condition_enum<errc> : true_type { };
-
-template <> struct is_error_condition_enum<errc::_> : true_type { };
-
-class error_condition;
-class error_code;
-
-// class error_category
-
-class _do_message;
-
-class error_category
-{
-public:
- virtual ~error_category();
-
-private:
- error_category();
- error_category(const error_category&);// = delete;
- error_category& operator=(const error_category&);// = delete;
-
-public:
- virtual const char* name() const = 0;
- virtual error_condition default_error_condition(int _ev) const;
- virtual bool equivalent(int _code, const error_condition& _condition) const;
- virtual bool equivalent(const error_code& _code, int _condition) const;
- virtual std::string message(int _ev) const = 0;
-
- bool operator==(const error_category& _rhs) const {return this == &_rhs;}
-
- bool operator!=(const error_category& _rhs) const {return !(*this == _rhs);}
-
- bool operator< (const error_category& _rhs) const {return this < &_rhs;}
-
- friend class _do_message;
-};
-
-class _do_message : public error_category
-{
-public:
- virtual std::string message(int ev) const;
-};
-
-const error_category& generic_category();
-const error_category& system_category();
-
-class error_condition
-{
- int _val_;
- const error_category* _cat_;
-public:
- error_condition() : _val_(0), _cat_(&generic_category()) {}
-
- error_condition(int _val, const error_category& _cat)
- : _val_(_val), _cat_(&_cat) {}
-
- template <class E>
- error_condition(E _e, typename enable_if_c<
- is_error_condition_enum<E>::value
- >::type* = 0)
- {*this = make_error_condition(_e);}
-
- void assign(int _val, const error_category& _cat) {
- _val_ = _val;
- _cat_ = &_cat;
- }
-
- template <class E>
- typename enable_if_c
- <
- is_error_condition_enum<E>::value,
- error_condition&
- >::type
- operator=(E _e)
- {*this = make_error_condition(_e); return *this;}
-
- void clear() {
- _val_ = 0;
- _cat_ = &generic_category();
- }
-
- int value() const {return _val_;}
-
- const error_category& category() const {return *_cat_;}
- std::string message() const;
-
- // explicit
- operator bool() const {return _val_ != 0;}
-};
-
-inline error_condition make_error_condition(errc _e) {
- return error_condition(static_cast<int>(_e), generic_category());
-}
-
-inline bool operator<(const error_condition& _x, const error_condition& _y) {
- return _x.category() < _y.category()
- || (_x.category() == _y.category() && _x.value() < _y.value());
-}
-
-// error_code
-
-class error_code {
- int _val_;
- const error_category* _cat_;
-public:
- error_code() : _val_(0), _cat_(&system_category()) {}
-
- error_code(int _val, const error_category& _cat)
- : _val_(_val), _cat_(&_cat) {}
-
- template <class E>
- error_code(E _e, typename enable_if_c<
- is_error_code_enum<E>::value
- >::type* = 0) {
- *this = make_error_code(_e);
- }
-
- void assign(int _val, const error_category& _cat) {
- _val_ = _val;
- _cat_ = &_cat;
- }
-
- template <class E>
- typename enable_if_c
- <
- is_error_code_enum<E>::value,
- error_code&
- >::type
- operator=(E _e)
- {*this = make_error_code(_e); return *this;}
-
- void clear() {
- _val_ = 0;
- _cat_ = &system_category();
- }
-
- int value() const {return _val_;}
-
- const error_category& category() const {return *_cat_;}
-
- error_condition default_error_condition() const
- {return _cat_->default_error_condition(_val_);}
-
- std::string message() const;
-
- // explicit
- operator bool() const {return _val_ != 0;}
-};
-
-inline error_code make_error_code(errc _e) {
- return error_code(static_cast<int>(_e), generic_category());
-}
-
-inline bool operator<(const error_code& _x, const error_code& _y) {
- return _x.category() < _y.category()
- || (_x.category() == _y.category() && _x.value() < _y.value());
-}
-
-inline bool operator==(const error_code& _x, const error_code& _y) {
- return _x.category() == _y.category() && _x.value() == _y.value();
-}
-
-inline bool operator==(const error_code& _x, const error_condition& _y) {
- return _x.category().equivalent(_x.value(), _y)
- || _y.category().equivalent(_x, _y.value());
-}
-
-inline bool operator==(const error_condition& _x, const error_code& _y) {
- return _y == _x;
-}
-
-inline bool operator==(const error_condition& _x, const error_condition& _y) {
- return _x.category() == _y.category() && _x.value() == _y.value();
-}
-
-inline bool operator!=(const error_code& _x, const error_code& _y) {
- return !(_x == _y);
-}
-
-inline bool operator!=(const error_code& _x, const error_condition& _y) {
- return !(_x == _y);
-}
-
-inline bool operator!=(const error_condition& _x, const error_code& _y) {
- return !(_x == _y);
-}
-
-inline bool operator!=(const error_condition& _x, const error_condition& _y) {
- return !(_x == _y);
-}
-
-// system_error
-
-} // end namespace llvm
-
-// This needs to stay here for KillTheDoctor.
-#ifdef LLVM_ON_WIN32
-// FIXME: These two headers really really really need to be removed from here.
-// Not only is it a violation of System, they define the stupid min and
-// max macros :(.
-#include <Windows.h>
-#include <WinError.h>
-
-namespace llvm {
-
-// To construct an error_code after an API error:
-//
-// error_code( ::GetLastError(), system_category() )
-struct windows_error {
-enum _ {
- success = 0,
- // These names and values are based on Windows winerror.h
- // This is not a complete list.
- invalid_function = ERROR_INVALID_FUNCTION,
- file_not_found = ERROR_FILE_NOT_FOUND,
- path_not_found = ERROR_PATH_NOT_FOUND,
- too_many_open_files = ERROR_TOO_MANY_OPEN_FILES,
- access_denied = ERROR_ACCESS_DENIED,
- invalid_handle = ERROR_INVALID_HANDLE,
- arena_trashed = ERROR_ARENA_TRASHED,
- not_enough_memory = ERROR_NOT_ENOUGH_MEMORY,
- invalid_block = ERROR_INVALID_BLOCK,
- bad_environment = ERROR_BAD_ENVIRONMENT,
- bad_format = ERROR_BAD_FORMAT,
- invalid_access = ERROR_INVALID_ACCESS,
- outofmemory = ERROR_OUTOFMEMORY,
- invalid_drive = ERROR_INVALID_DRIVE,
- current_directory = ERROR_CURRENT_DIRECTORY,
- not_same_device = ERROR_NOT_SAME_DEVICE,
- no_more_files = ERROR_NO_MORE_FILES,
- write_protect = ERROR_WRITE_PROTECT,
- bad_unit = ERROR_BAD_UNIT,
- not_ready = ERROR_NOT_READY,
- bad_command = ERROR_BAD_COMMAND,
- crc = ERROR_CRC,
- bad_length = ERROR_BAD_LENGTH,
- seek = ERROR_SEEK,
- not_dos_disk = ERROR_NOT_DOS_DISK,
- sector_not_found = ERROR_SECTOR_NOT_FOUND,
- out_of_paper = ERROR_OUT_OF_PAPER,
- write_fault = ERROR_WRITE_FAULT,
- read_fault = ERROR_READ_FAULT,
- gen_failure = ERROR_GEN_FAILURE,
- sharing_violation = ERROR_SHARING_VIOLATION,
- lock_violation = ERROR_LOCK_VIOLATION,
- wrong_disk = ERROR_WRONG_DISK,
- sharing_buffer_exceeded = ERROR_SHARING_BUFFER_EXCEEDED,
- handle_eof = ERROR_HANDLE_EOF,
- handle_disk_full = ERROR_HANDLE_DISK_FULL,
- rem_not_list = ERROR_REM_NOT_LIST,
- dup_name = ERROR_DUP_NAME,
- bad_net_path = ERROR_BAD_NETPATH,
- network_busy = ERROR_NETWORK_BUSY,
- file_exists = ERROR_FILE_EXISTS,
- cannot_make = ERROR_CANNOT_MAKE,
- broken_pipe = ERROR_BROKEN_PIPE,
- open_failed = ERROR_OPEN_FAILED,
- buffer_overflow = ERROR_BUFFER_OVERFLOW,
- disk_full = ERROR_DISK_FULL,
- lock_failed = ERROR_LOCK_FAILED,
- busy = ERROR_BUSY,
- cancel_violation = ERROR_CANCEL_VIOLATION,
- already_exists = ERROR_ALREADY_EXISTS
-};
- _ v_;
-
- windows_error(_ v) : v_(v) {}
- explicit windows_error(DWORD v) : v_(_(v)) {}
- operator int() const {return v_;}
-};
-
-
-template <> struct is_error_code_enum<windows_error> : true_type { };
-
-template <> struct is_error_code_enum<windows_error::_> : true_type { };
-
-inline error_code make_error_code(windows_error e) {
- return error_code(static_cast<int>(e), system_category());
-}
-
-} // end namespace llvm
-
-#endif // LLVM_ON_WINDOWS
-
-#endif
#include <vector>
#include <cstring>
#include "llvm/ADT/Triple.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
class raw_ostream;
#ifndef LLVM_TARGET_TARGETASMBACKEND_H
#define LLVM_TARGET_TARGETASMBACKEND_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
class MCDataFragment;
#include "llvm/Pass.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
#ifndef LLVM_TARGET_TARGETINSTRDESC_H
#define LLVM_TARGET_TARGETINSTRDESC_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
#include <cassert>
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
class Function;
#include "llvm/Type.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <map>
namespace llvm {
#include "llvm/Value.h"
#include "llvm/ADT/StringMap.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
template<typename ValueSubClass, typename ItemParentClass>
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/MathExtras.h"
-#include "llvm/System/FEnv.h"
+#include "llvm/Support/FEnv.h"
#include <cerrno>
#include <cmath>
using namespace llvm;
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/Module.h"
#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/System/Process.h"
+#include "llvm/Support/Process.h"
#include <memory>
#include <cstring>
using namespace llvm;
#define LIB_ARCHIVE_ARCHIVEINTERNALS_H
#include "llvm/Bitcode/Archive.h"
-#include "llvm/System/TimeValue.h"
+#include "llvm/Support/TimeValue.h"
#include "llvm/ADT/StringExtras.h"
#include <cstring>
#include "llvm/ADT/OwningPtr.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/System/Process.h"
-#include "llvm/System/Signals.h"
+#include "llvm/Support/Process.h"
+#include "llvm/Support/Signals.h"
#include <fstream>
#include <ostream>
#include <iomanip>
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Program.h"
+#include "llvm/Support/Program.h"
using namespace llvm;
/// These are manifest constants used by the bitcode writer. They do not need to
#include "llvm/Support/ValueHandle.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/Timer.h"
-#include "llvm/System/Path.h"
+#include "llvm/Support/Path.h"
using namespace llvm;
static cl::opt<bool> PrintDbgScope("print-dbgscope", cl::Hidden,
#include "llvm/CodeGen/BinaryObject.h"
#include "llvm/CodeGen/MachineRelocation.h"
#include "llvm/Support/ELF.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
class GlobalValue;
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Mutex.h"
+#include "llvm/Support/Mutex.h"
#include <map>
using namespace llvm;
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/DebugLoc.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Mutex.h"
+#include "llvm/Support/Mutex.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/Support/MutexGuard.h"
#include "llvm/Support/ValueHandle.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/DynamicLibrary.h"
-#include "llvm/System/Host.h"
+#include "llvm/Support/DynamicLibrary.h"
+#include "llvm/Support/Host.h"
#include "llvm/Target/TargetData.h"
#include <cmath>
#include <cstring>
#include "llvm/Module.h"
#include "llvm/Config/config.h" // Detect libffi
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/System/DynamicLibrary.h"
+#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Support/ManagedStatic.h"
-#include "llvm/System/Mutex.h"
+#include "llvm/Support/Mutex.h"
#include <csignal>
#include <cstdio>
#include <map>
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Support/CallSite.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/InstVisitor.h"
#include "llvm/Support/raw_ostream.h"
#include "JIT.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/System/DynamicLibrary.h"
+#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Config/config.h"
using namespace llvm;
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MutexGuard.h"
-#include "llvm/System/DynamicLibrary.h"
+#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Config/config.h"
using namespace llvm;
#include "llvm/Support/Compiler.h"
#include "llvm/Support/MutexGuard.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Mutex.h"
+#include "llvm/Support/Mutex.h"
#include <string>
#include <vector>
#define LLVM_EXECUTION_ENGINE_JIT_DEBUGREGISTERER_H
#include "llvm/ADT/DenseMap.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <string>
// This must be kept in sync with gdb/gdb/jit.h .
#include "llvm/Support/MutexGuard.h"
#include "llvm/Support/ValueHandle.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Disassembler.h"
-#include "llvm/System/Memory.h"
+#include "llvm/Support/Disassembler.h"
+#include "llvm/Support/Memory.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Memory.h"
+#include "llvm/Support/Memory.h"
#include <vector>
#include <cassert>
#include <climits>
#include "llvm/Support/Debug.h"
#include "llvm/Support/ValueHandle.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Errno.h"
+#include "llvm/Support/Errno.h"
#include "llvm/Config/config.h"
#include <stddef.h>
using namespace llvm;
#include "llvm/ADT/Triple.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Host.h"
+#include "llvm/Support/Host.h"
#include "llvm/Target/SubtargetFeature.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/ExecutionEngine/MCJIT.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/System/DynamicLibrary.h"
+#include "llvm/Support/DynamicLibrary.h"
using namespace llvm;
#include "llvm/ADT/Triple.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Host.h"
+#include "llvm/Support/Host.h"
#include "llvm/Target/SubtargetFeature.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/Linker.h"
#include "llvm/Module.h"
#include "llvm/Bitcode/ReaderWriter.h"
-#include "llvm/System/Path.h"
+#include "llvm/Support/Path.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MemoryBuffer.h"
using namespace llvm;
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Path.h"
+#include "llvm/Support/Path.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
#include "llvm/ADT/DenseMap.h"
using namespace llvm;
#include "llvm/Linker.h"
#include "llvm/Module.h"
#include "llvm/Bitcode/ReaderWriter.h"
-#include "llvm/System/Path.h"
+#include "llvm/Support/Path.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Config/config.h"
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <cctype>
#include <cstring>
using namespace llvm;
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Mutex.h"
+#include "llvm/Support/Mutex.h"
#include <map>
#include <set>
#ifndef LLVM_EDINST_H
#define LLVM_EDINST_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/ADT/SmallVector.h"
#include <string>
#include <vector>
#ifndef LLVM_EDOPERAND_H
#define LLVM_EDOPERAND_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
#define LLVM_EDTOKEN_H
#include "llvm/ADT/StringRef.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <string>
#include <vector>
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/System/TimeValue.h"
+#include "llvm/Support/TimeValue.h"
#include "../Target/X86/X86FixupKinds.h"
#include "llvm/Object/MachOObject.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/System/Host.h"
-#include "llvm/System/SwapByteOrder.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/SwapByteOrder.h"
using namespace llvm;
using namespace llvm::object;
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/System/Path.h"
+#include "llvm/Support/Path.h"
using namespace llvm;
using namespace object;
--- /dev/null
+//===- Alarm.cpp - Alarm Generation Support ---------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Alarm functionality
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Alarm.h"
+#include "llvm/Config/config.h"
+
+namespace llvm {
+using namespace sys;
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only TRULY operating system
+//=== independent code.
+//===----------------------------------------------------------------------===//
+
+}
+
+// Include the platform-specific parts of this class.
+#ifdef LLVM_ON_UNIX
+#include "Unix/Alarm.inc"
+#endif
+#ifdef LLVM_ON_WIN32
+#include "Windows/Alarm.inc"
+#endif
//===----------------------------------------------------------------------===//
#include "llvm/Support/Allocator.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/Support/Recycler.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Memory.h"
+#include "llvm/Support/Memory.h"
#include <cstring>
namespace llvm {
--- /dev/null
+//===-- Atomic.cpp - Atomic Operations --------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file implements atomic operations.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Atomic.h"
+#include "llvm/Config/config.h"
+
+using namespace llvm;
+
+#if defined(_MSC_VER)
+#include <windows.h>
+#undef MemoryFence
+#endif
+
+void sys::MemoryFence() {
+#if LLVM_MULTITHREADED==0
+ return;
+#else
+# if defined(__GNUC__)
+ __sync_synchronize();
+# elif defined(_MSC_VER)
+ MemoryBarrier();
+# else
+# error No memory fence implementation for your platform!
+# endif
+#endif
+}
+
+sys::cas_flag sys::CompareAndSwap(volatile sys::cas_flag* ptr,
+ sys::cas_flag new_value,
+ sys::cas_flag old_value) {
+#if LLVM_MULTITHREADED==0
+ sys::cas_flag result = *ptr;
+ if (result == old_value)
+ *ptr = new_value;
+ return result;
+#elif defined(__GNUC__)
+ return __sync_val_compare_and_swap(ptr, old_value, new_value);
+#elif defined(_MSC_VER)
+ return InterlockedCompareExchange(ptr, new_value, old_value);
+#else
+# error No compare-and-swap implementation for your platform!
+#endif
+}
+
+sys::cas_flag sys::AtomicIncrement(volatile sys::cas_flag* ptr) {
+#if LLVM_MULTITHREADED==0
+ ++(*ptr);
+ return *ptr;
+#elif defined(__GNUC__)
+ return __sync_add_and_fetch(ptr, 1);
+#elif defined(_MSC_VER)
+ return InterlockedIncrement(ptr);
+#else
+# error No atomic increment implementation for your platform!
+#endif
+}
+
+sys::cas_flag sys::AtomicDecrement(volatile sys::cas_flag* ptr) {
+#if LLVM_MULTITHREADED==0
+ --(*ptr);
+ return *ptr;
+#elif defined(__GNUC__)
+ return __sync_sub_and_fetch(ptr, 1);
+#elif defined(_MSC_VER)
+ return InterlockedDecrement(ptr);
+#else
+# error No atomic decrement implementation for your platform!
+#endif
+}
+
+sys::cas_flag sys::AtomicAdd(volatile sys::cas_flag* ptr, sys::cas_flag val) {
+#if LLVM_MULTITHREADED==0
+ *ptr += val;
+ return *ptr;
+#elif defined(__GNUC__)
+ return __sync_add_and_fetch(ptr, val);
+#elif defined(_MSC_VER)
+ return InterlockedExchangeAdd(ptr, val) + val;
+#else
+# error No atomic add implementation for your platform!
+#endif
+}
+
+sys::cas_flag sys::AtomicMul(volatile sys::cas_flag* ptr, sys::cas_flag val) {
+ sys::cas_flag original, result;
+ do {
+ original = *ptr;
+ result = original * val;
+ } while (sys::CompareAndSwap(ptr, result, original) != original);
+
+ return result;
+}
+
+sys::cas_flag sys::AtomicDiv(volatile sys::cas_flag* ptr, sys::cas_flag val) {
+ sys::cas_flag original, result;
+ do {
+ original = *ptr;
+ result = original / val;
+ } while (sys::CompareAndSwap(ptr, result, original) != original);
+
+ return result;
+}
## FIXME: This only requires RTTI because tblgen uses it. Fix that.
set(LLVM_REQUIRES_RTTI 1)
+if( MINGW )
+ set(LLVM_REQUIRES_EH 1)
+endif()
add_llvm_library(LLVMSupport
APFloat.cpp
regexec.c
regfree.c
regstrlcpy.c
+
+# System
+ Alarm.cpp
+ Atomic.cpp
+ Disassembler.cpp
+ DynamicLibrary.cpp
+ Errno.cpp
+ Host.cpp
+ IncludeFile.cpp
+ Memory.cpp
+ Mutex.cpp
+ Path.cpp
+ Process.cpp
+ Program.cpp
+ RWMutex.cpp
+ SearchForAddressOfSpecialSymbol.cpp
+ Signals.cpp
+ system_error.cpp
+ ThreadLocal.cpp
+ Threading.cpp
+ TimeValue.cpp
+ Valgrind.cpp
+ Unix/Alarm.inc
+ Unix/Host.inc
+ Unix/Memory.inc
+ Unix/Mutex.inc
+ Unix/Path.inc
+ Unix/Process.inc
+ Unix/Program.inc
+ Unix/RWMutex.inc
+ Unix/Signals.inc
+ Unix/system_error.inc
+ Unix/ThreadLocal.inc
+ Unix/TimeValue.inc
+ Windows/Alarm.inc
+ Windows/DynamicLibrary.inc
+ Windows/Host.inc
+ Windows/Memory.inc
+ Windows/Mutex.inc
+ Windows/Path.inc
+ Windows/Process.inc
+ Windows/Program.inc
+ Windows/RWMutex.inc
+ Windows/Signals.inc
+ Windows/system_error.inc
+ Windows/ThreadLocal.inc
+ Windows/TimeValue.inc
)
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetRegistry.h"
-#include "llvm/System/Host.h"
-#include "llvm/System/Path.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/Path.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/CrashRecoveryContext.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Config/config.h"
-#include "llvm/System/Mutex.h"
-#include "llvm/System/ThreadLocal.h"
+#include "llvm/Support/Mutex.h"
+#include "llvm/Support/ThreadLocal.h"
#include <setjmp.h>
#include <cstdio>
using namespace llvm;
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/circular_raw_ostream.h"
-#include "llvm/System/Signals.h"
+#include "llvm/Support/Signals.h"
using namespace llvm;
--- /dev/null
+//===- lib/System/Disassembler.cpp ------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the necessary glue to call external disassembler
+// libraries.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Config/config.h"
+#include "llvm/Support/Disassembler.h"
+
+#include <cassert>
+#include <iomanip>
+#include <string>
+#include <sstream>
+
+#if USE_UDIS86
+#include <udis86.h>
+#endif
+
+using namespace llvm;
+
+bool llvm::sys::hasDisassembler()
+{
+#if defined (__i386__) || defined (__amd64__) || defined (__x86_64__)
+ // We have option to enable udis86 library.
+# if USE_UDIS86
+ return true;
+#else
+ return false;
+#endif
+#else
+ return false;
+#endif
+}
+
+std::string llvm::sys::disassembleBuffer(uint8_t* start, size_t length,
+ uint64_t pc) {
+ std::stringstream res;
+
+#if (defined (__i386__) || defined (__amd64__) || defined (__x86_64__)) \
+ && USE_UDIS86
+ unsigned bits;
+# if defined(__i386__)
+ bits = 32;
+# else
+ bits = 64;
+# endif
+
+ ud_t ud_obj;
+
+ ud_init(&ud_obj);
+ ud_set_input_buffer(&ud_obj, start, length);
+ ud_set_mode(&ud_obj, bits);
+ ud_set_pc(&ud_obj, pc);
+ ud_set_syntax(&ud_obj, UD_SYN_ATT);
+
+ res << std::setbase(16)
+ << std::setw(bits/4);
+
+ while (ud_disassemble(&ud_obj)) {
+ res << ud_insn_off(&ud_obj) << ":\t" << ud_insn_asm(&ud_obj) << "\n";
+ }
+#else
+ res << "No disassembler available. See configure help for options.\n";
+#endif
+
+ return res.str();
+}
--- /dev/null
+//===-- DynamicLibrary.cpp - Runtime link/load libraries --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file implements the operating system DynamicLibrary concept.
+//
+// FIXME: This file leaks the ExplicitSymbols and OpenedHandles vector, and is
+// not thread safe!
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/DynamicLibrary.h"
+#include "llvm/Support/Mutex.h"
+#include "llvm/Config/config.h"
+#include <cstdio>
+#include <cstring>
+#include <map>
+#include <vector>
+
+// Collection of symbol name/value pairs to be searched prior to any libraries.
+static std::map<std::string, void*> *ExplicitSymbols = 0;
+
+namespace {
+
+struct ExplicitSymbolsDeleter {
+ ~ExplicitSymbolsDeleter() {
+ if (ExplicitSymbols)
+ delete ExplicitSymbols;
+ }
+};
+
+}
+
+static ExplicitSymbolsDeleter Dummy;
+
+void llvm::sys::DynamicLibrary::AddSymbol(const char* symbolName,
+ void *symbolValue) {
+ if (ExplicitSymbols == 0)
+ ExplicitSymbols = new std::map<std::string, void*>();
+ (*ExplicitSymbols)[symbolName] = symbolValue;
+}
+
+#ifdef LLVM_ON_WIN32
+
+#include "Windows/DynamicLibrary.inc"
+
+#else
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+using namespace llvm;
+using namespace llvm::sys;
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only TRULY operating system
+//=== independent code.
+//===----------------------------------------------------------------------===//
+
+static SmartMutex<true>* HandlesMutex;
+static std::vector<void *> *OpenedHandles = 0;
+
+static bool InitializeMutex() {
+ HandlesMutex = new SmartMutex<true>;
+ return HandlesMutex != 0;
+}
+
+static bool EnsureMutexInitialized() {
+ static bool result = InitializeMutex();
+ return result;
+}
+
+
+bool DynamicLibrary::LoadLibraryPermanently(const char *Filename,
+ std::string *ErrMsg) {
+ void *H = dlopen(Filename, RTLD_LAZY|RTLD_GLOBAL);
+ if (H == 0) {
+ if (ErrMsg) *ErrMsg = dlerror();
+ return true;
+ }
+#ifdef __CYGWIN__
+ // Cygwin searches symbols only in the main
+ // with the handle of dlopen(NULL, RTLD_GLOBAL).
+ if (Filename == NULL)
+ H = RTLD_DEFAULT;
+#endif
+ EnsureMutexInitialized();
+ SmartScopedLock<true> Lock(*HandlesMutex);
+ if (OpenedHandles == 0)
+ OpenedHandles = new std::vector<void *>();
+ OpenedHandles->push_back(H);
+ return false;
+}
+#else
+
+using namespace llvm;
+using namespace llvm::sys;
+
+bool DynamicLibrary::LoadLibraryPermanently(const char *Filename,
+ std::string *ErrMsg) {
+ if (ErrMsg) *ErrMsg = "dlopen() not supported on this platform";
+ return true;
+}
+#endif
+
+namespace llvm {
+void *SearchForAddressOfSpecialSymbol(const char* symbolName);
+}
+
+void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) {
+ // First check symbols added via AddSymbol().
+ if (ExplicitSymbols) {
+ std::map<std::string, void *>::iterator I =
+ ExplicitSymbols->find(symbolName);
+ std::map<std::string, void *>::iterator E = ExplicitSymbols->end();
+
+ if (I != E)
+ return I->second;
+ }
+
+#if HAVE_DLFCN_H
+ // Now search the libraries.
+ EnsureMutexInitialized();
+ SmartScopedLock<true> Lock(*HandlesMutex);
+ if (OpenedHandles) {
+ for (std::vector<void *>::iterator I = OpenedHandles->begin(),
+ E = OpenedHandles->end(); I != E; ++I) {
+ //lt_ptr ptr = lt_dlsym(*I, symbolName);
+ void *ptr = dlsym(*I, symbolName);
+ if (ptr) {
+ return ptr;
+ }
+ }
+ }
+#endif
+
+ if (void *Result = llvm::SearchForAddressOfSpecialSymbol(symbolName))
+ return Result;
+
+// This macro returns the address of a well-known, explicit symbol
+#define EXPLICIT_SYMBOL(SYM) \
+ if (!strcmp(symbolName, #SYM)) return &SYM
+
+// On linux we have a weird situation. The stderr/out/in symbols are both
+// macros and global variables because of standards requirements. So, we
+// boldly use the EXPLICIT_SYMBOL macro without checking for a #define first.
+#if defined(__linux__)
+ {
+ EXPLICIT_SYMBOL(stderr);
+ EXPLICIT_SYMBOL(stdout);
+ EXPLICIT_SYMBOL(stdin);
+ }
+#else
+ // For everything else, we want to check to make sure the symbol isn't defined
+ // as a macro before using EXPLICIT_SYMBOL.
+ {
+#ifndef stdin
+ EXPLICIT_SYMBOL(stdin);
+#endif
+#ifndef stdout
+ EXPLICIT_SYMBOL(stdout);
+#endif
+#ifndef stderr
+ EXPLICIT_SYMBOL(stderr);
+#endif
+ }
+#endif
+#undef EXPLICIT_SYMBOL
+
+ return 0;
+}
+
+#endif // LLVM_ON_WIN32
--- /dev/null
+//===- Errno.cpp - errno support --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the errno wrappers.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Errno.h"
+#include "llvm/Config/config.h" // Get autoconf configuration settings
+
+#if HAVE_STRING_H
+#include <string.h>
+
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only TRULY operating system
+//=== independent code.
+//===----------------------------------------------------------------------===//
+
+namespace llvm {
+namespace sys {
+
+#if HAVE_ERRNO_H
+std::string StrError() {
+ return StrError(errno);
+}
+#endif // HAVE_ERRNO_H
+
+std::string StrError(int errnum) {
+ const int MaxErrStrLen = 2000;
+ char buffer[MaxErrStrLen];
+ buffer[0] = '\0';
+ char* str = buffer;
+#ifdef HAVE_STRERROR_R
+ // strerror_r is thread-safe.
+ if (errnum)
+# if defined(__GLIBC__) && defined(_GNU_SOURCE)
+ // glibc defines its own incompatible version of strerror_r
+ // which may not use the buffer supplied.
+ str = strerror_r(errnum,buffer,MaxErrStrLen-1);
+# else
+ strerror_r(errnum,buffer,MaxErrStrLen-1);
+# endif
+#elif defined(HAVE_STRERROR_S) // Windows.
+ if (errnum)
+ strerror_s(buffer, errnum);
+#elif defined(HAVE_STRERROR)
+ // Copy the thread un-safe result of strerror into
+ // the buffer as fast as possible to minimize impact
+ // of collision of strerror in multiple threads.
+ if (errnum)
+ strncpy(buffer,strerror(errnum),MaxErrStrLen-1);
+ buffer[MaxErrStrLen-1] = '\0';
+#else
+ // Strange that this system doesn't even have strerror
+ // but, oh well, just use a generic message
+ sprintf(buffer, "Error #%d", errnum);
+#endif
+ return str;
+}
+
+} // namespace sys
+} // namespace llvm
+
+#endif // HAVE_STRING_H
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Signals.h"
-#include "llvm/System/Threading.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/Threading.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Config/config.h"
#include <cassert>
#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Path.h"
+#include "llvm/Support/Path.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallString.h"
#include <cstdlib>
#include "llvm/Support/Allocator.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
-#include "llvm/System/Host.h"
+#include "llvm/Support/Host.h"
#include <cassert>
#include <cstring>
using namespace llvm;
//===----------------------------------------------------------------------===//
#include "llvm/Support/GraphWriter.h"
-#include "llvm/System/Path.h"
-#include "llvm/System/Program.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Program.h"
#include "llvm/Config/config.h"
using namespace llvm;
--- /dev/null
+//===-- Host.cpp - Implement OS Host Concept --------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file implements the operating system Host concept.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Host.h"
+#include "llvm/Config/config.h"
+#include <string.h>
+
+// Include the platform-specific parts of this class.
+#ifdef LLVM_ON_UNIX
+#include "Unix/Host.inc"
+#endif
+#ifdef LLVM_ON_WIN32
+#include "Windows/Host.inc"
+#endif
+#ifdef _MSC_VER
+#include <intrin.h>
+#endif
+
+//===----------------------------------------------------------------------===//
+//
+// Implementations of the CPU detection routines
+//
+//===----------------------------------------------------------------------===//
+
+using namespace llvm;
+
+#if defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)\
+ || defined(__x86_64__) || defined(_M_AMD64) || defined (_M_X64)
+
+/// GetX86CpuIDAndInfo - Execute the specified cpuid and return the 4 values in the
+/// specified arguments. If we can't run cpuid on the host, return true.
+static bool GetX86CpuIDAndInfo(unsigned value, unsigned *rEAX,
+ unsigned *rEBX, unsigned *rECX, unsigned *rEDX) {
+#if defined(__x86_64__) || defined(_M_AMD64) || defined (_M_X64)
+ #if defined(__GNUC__)
+ // gcc doesn't know cpuid would clobber ebx/rbx. Preseve it manually.
+ asm ("movq\t%%rbx, %%rsi\n\t"
+ "cpuid\n\t"
+ "xchgq\t%%rbx, %%rsi\n\t"
+ : "=a" (*rEAX),
+ "=S" (*rEBX),
+ "=c" (*rECX),
+ "=d" (*rEDX)
+ : "a" (value));
+ return false;
+ #elif defined(_MSC_VER)
+ int registers[4];
+ __cpuid(registers, value);
+ *rEAX = registers[0];
+ *rEBX = registers[1];
+ *rECX = registers[2];
+ *rEDX = registers[3];
+ return false;
+ #endif
+#elif defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)
+ #if defined(__GNUC__)
+ asm ("movl\t%%ebx, %%esi\n\t"
+ "cpuid\n\t"
+ "xchgl\t%%ebx, %%esi\n\t"
+ : "=a" (*rEAX),
+ "=S" (*rEBX),
+ "=c" (*rECX),
+ "=d" (*rEDX)
+ : "a" (value));
+ return false;
+ #elif defined(_MSC_VER)
+ __asm {
+ mov eax,value
+ cpuid
+ mov esi,rEAX
+ mov dword ptr [esi],eax
+ mov esi,rEBX
+ mov dword ptr [esi],ebx
+ mov esi,rECX
+ mov dword ptr [esi],ecx
+ mov esi,rEDX
+ mov dword ptr [esi],edx
+ }
+ return false;
+ #endif
+#endif
+ return true;
+}
+
+static void DetectX86FamilyModel(unsigned EAX, unsigned &Family,
+ unsigned &Model) {
+ Family = (EAX >> 8) & 0xf; // Bits 8 - 11
+ Model = (EAX >> 4) & 0xf; // Bits 4 - 7
+ if (Family == 6 || Family == 0xf) {
+ if (Family == 0xf)
+ // Examine extended family ID if family ID is F.
+ Family += (EAX >> 20) & 0xff; // Bits 20 - 27
+ // Examine extended model ID if family ID is 6 or F.
+ Model += ((EAX >> 16) & 0xf) << 4; // Bits 16 - 19
+ }
+}
+
+std::string sys::getHostCPUName() {
+ unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
+ if (GetX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX))
+ return "generic";
+ unsigned Family = 0;
+ unsigned Model = 0;
+ DetectX86FamilyModel(EAX, Family, Model);
+
+ bool HasSSE3 = (ECX & 0x1);
+ GetX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
+ bool Em64T = (EDX >> 29) & 0x1;
+
+ union {
+ unsigned u[3];
+ char c[12];
+ } text;
+
+ GetX86CpuIDAndInfo(0, &EAX, text.u+0, text.u+2, text.u+1);
+ if (memcmp(text.c, "GenuineIntel", 12) == 0) {
+ switch (Family) {
+ case 3:
+ return "i386";
+ case 4:
+ switch (Model) {
+ case 0: // Intel486 DX processors
+ case 1: // Intel486 DX processors
+ case 2: // Intel486 SX processors
+ case 3: // Intel487 processors, IntelDX2 OverDrive processors,
+ // IntelDX2 processors
+ case 4: // Intel486 SL processor
+ case 5: // IntelSX2 processors
+ case 7: // Write-Back Enhanced IntelDX2 processors
+ case 8: // IntelDX4 OverDrive processors, IntelDX4 processors
+ default: return "i486";
+ }
+ case 5:
+ switch (Model) {
+ case 1: // Pentium OverDrive processor for Pentium processor (60, 66),
+ // Pentium processors (60, 66)
+ case 2: // Pentium OverDrive processor for Pentium processor (75, 90,
+ // 100, 120, 133), Pentium processors (75, 90, 100, 120, 133,
+ // 150, 166, 200)
+ case 3: // Pentium OverDrive processors for Intel486 processor-based
+ // systems
+ return "pentium";
+
+ case 4: // Pentium OverDrive processor with MMX technology for Pentium
+ // processor (75, 90, 100, 120, 133), Pentium processor with
+ // MMX technology (166, 200)
+ return "pentium-mmx";
+
+ default: return "pentium";
+ }
+ case 6:
+ switch (Model) {
+ case 1: // Pentium Pro processor
+ return "pentiumpro";
+
+ case 3: // Intel Pentium II OverDrive processor, Pentium II processor,
+ // model 03
+ case 5: // Pentium II processor, model 05, Pentium II Xeon processor,
+ // model 05, and Intel Celeron processor, model 05
+ case 6: // Celeron processor, model 06
+ return "pentium2";
+
+ case 7: // Pentium III processor, model 07, and Pentium III Xeon
+ // processor, model 07
+ case 8: // Pentium III processor, model 08, Pentium III Xeon processor,
+ // model 08, and Celeron processor, model 08
+ case 10: // Pentium III Xeon processor, model 0Ah
+ case 11: // Pentium III processor, model 0Bh
+ return "pentium3";
+
+ case 9: // Intel Pentium M processor, Intel Celeron M processor model 09.
+ case 13: // Intel Pentium M processor, Intel Celeron M processor, model
+ // 0Dh. All processors are manufactured using the 90 nm process.
+ return "pentium-m";
+
+ case 14: // Intel Core Duo processor, Intel Core Solo processor, model
+ // 0Eh. All processors are manufactured using the 65 nm process.
+ return "yonah";
+
+ case 15: // Intel Core 2 Duo processor, Intel Core 2 Duo mobile
+ // processor, Intel Core 2 Quad processor, Intel Core 2 Quad
+ // mobile processor, Intel Core 2 Extreme processor, Intel
+ // Pentium Dual-Core processor, Intel Xeon processor, model
+ // 0Fh. All processors are manufactured using the 65 nm process.
+ case 22: // Intel Celeron processor model 16h. All processors are
+ // manufactured using the 65 nm process
+ return "core2";
+
+ case 21: // Intel EP80579 Integrated Processor and Intel EP80579
+ // Integrated Processor with Intel QuickAssist Technology
+ return "i686"; // FIXME: ???
+
+ case 23: // Intel Core 2 Extreme processor, Intel Xeon processor, model
+ // 17h. All processors are manufactured using the 45 nm process.
+ //
+ // 45nm: Penryn , Wolfdale, Yorkfield (XE)
+ return "penryn";
+
+ case 26: // Intel Core i7 processor and Intel Xeon processor. All
+ // processors are manufactured using the 45 nm process.
+ case 29: // Intel Xeon processor MP. All processors are manufactured using
+ // the 45 nm process.
+ case 30: // Intel(R) Core(TM) i7 CPU 870 @ 2.93GHz.
+ // As found in a Summer 2010 model iMac.
+ case 37: // Intel Core i7, laptop version.
+ return "corei7";
+
+ case 28: // Intel Atom processor. All processors are manufactured using
+ // the 45 nm process
+ return "atom";
+
+ default: return "i686";
+ }
+ case 15: {
+ switch (Model) {
+ case 0: // Pentium 4 processor, Intel Xeon processor. All processors are
+ // model 00h and manufactured using the 0.18 micron process.
+ case 1: // Pentium 4 processor, Intel Xeon processor, Intel Xeon
+ // processor MP, and Intel Celeron processor. All processors are
+ // model 01h and manufactured using the 0.18 micron process.
+ case 2: // Pentium 4 processor, Mobile Intel Pentium 4 processor - M,
+ // Intel Xeon processor, Intel Xeon processor MP, Intel Celeron
+ // processor, and Mobile Intel Celeron processor. All processors
+ // are model 02h and manufactured using the 0.13 micron process.
+ return (Em64T) ? "x86-64" : "pentium4";
+
+ case 3: // Pentium 4 processor, Intel Xeon processor, Intel Celeron D
+ // processor. All processors are model 03h and manufactured using
+ // the 90 nm process.
+ case 4: // Pentium 4 processor, Pentium 4 processor Extreme Edition,
+ // Pentium D processor, Intel Xeon processor, Intel Xeon
+ // processor MP, Intel Celeron D processor. All processors are
+ // model 04h and manufactured using the 90 nm process.
+ case 6: // Pentium 4 processor, Pentium D processor, Pentium processor
+ // Extreme Edition, Intel Xeon processor, Intel Xeon processor
+ // MP, Intel Celeron D processor. All processors are model 06h
+ // and manufactured using the 65 nm process.
+ return (Em64T) ? "nocona" : "prescott";
+
+ default:
+ return (Em64T) ? "x86-64" : "pentium4";
+ }
+ }
+
+ default:
+ return "generic";
+ }
+ } else if (memcmp(text.c, "AuthenticAMD", 12) == 0) {
+ // FIXME: this poorly matches the generated SubtargetFeatureKV table. There
+ // appears to be no way to generate the wide variety of AMD-specific targets
+ // from the information returned from CPUID.
+ switch (Family) {
+ case 4:
+ return "i486";
+ case 5:
+ switch (Model) {
+ case 6:
+ case 7: return "k6";
+ case 8: return "k6-2";
+ case 9:
+ case 13: return "k6-3";
+ default: return "pentium";
+ }
+ case 6:
+ switch (Model) {
+ case 4: return "athlon-tbird";
+ case 6:
+ case 7:
+ case 8: return "athlon-mp";
+ case 10: return "athlon-xp";
+ default: return "athlon";
+ }
+ case 15:
+ if (HasSSE3)
+ return "k8-sse3";
+ switch (Model) {
+ case 1: return "opteron";
+ case 5: return "athlon-fx"; // also opteron
+ default: return "athlon64";
+ }
+ case 16:
+ return "amdfam10";
+ default:
+ return "generic";
+ }
+ }
+ return "generic";
+}
+#else
+std::string sys::getHostCPUName() {
+ return "generic";
+}
+#endif
+
+bool sys::getHostCPUFeatures(StringMap<bool> &Features){
+ return false;
+}
--- /dev/null
+//===- lib/System/IncludeFile.cpp - Ensure Linking Of Implementation -----===//
+//
+// 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 IncludeFile constructor.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/IncludeFile.h"
+
+using namespace llvm;
+
+// This constructor is used to ensure linking of other modules. See the
+// llvm/System/IncludeFile.h header for details.
+IncludeFile::IncludeFile(const void*) {}
## FIXME: This only requires RTTI because tblgen uses it. Fix that.
REQUIRES_RTTI = 1
+EXTRA_DIST = Unix Win32 README.txt
+
include $(LEVEL)/Makefile.common
+
+CompileCommonOpts := $(filter-out -pedantic,$(CompileCommonOpts))
+CompileCommonOpts := $(filter-out -Wno-long-long,$(CompileCommonOpts))
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Config/config.h"
-#include "llvm/System/Atomic.h"
+#include "llvm/Support/Atomic.h"
#include <cassert>
using namespace llvm;
--- /dev/null
+//===- Memory.cpp - Memory Handling Support ---------------------*- 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 some helpful functions for allocating memory and dealing
+// with memory mapped files
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Memory.h"
+#include "llvm/Support/Valgrind.h"
+#include "llvm/Config/config.h"
+
+namespace llvm {
+using namespace sys;
+}
+
+// Include the platform-specific parts of this class.
+#ifdef LLVM_ON_UNIX
+#include "Unix/Memory.inc"
+#endif
+#ifdef LLVM_ON_WIN32
+#include "Windows/Memory.inc"
+#endif
+
+extern "C" void sys_icache_invalidate(const void *Addr, size_t len);
+
+/// InvalidateInstructionCache - Before the JIT can run a block of code
+/// that has been emitted it must invalidate the instruction cache on some
+/// platforms.
+void llvm::sys::Memory::InvalidateInstructionCache(const void *Addr,
+ size_t Len) {
+
+// icache invalidation for PPC and ARM.
+#if defined(__APPLE__)
+
+# if (defined(__POWERPC__) || defined (__ppc__) || \
+ defined(_POWER) || defined(_ARCH_PPC)) || defined(__arm__)
+ sys_icache_invalidate(Addr, Len);
+# endif
+
+#else
+
+# if (defined(__POWERPC__) || defined (__ppc__) || \
+ defined(_POWER) || defined(_ARCH_PPC)) && defined(__GNUC__)
+ const size_t LineSize = 32;
+
+ const intptr_t Mask = ~(LineSize - 1);
+ const intptr_t StartLine = ((intptr_t) Addr) & Mask;
+ const intptr_t EndLine = ((intptr_t) Addr + Len + LineSize - 1) & Mask;
+
+ for (intptr_t Line = StartLine; Line < EndLine; Line += LineSize)
+ asm volatile("dcbf 0, %0" : : "r"(Line));
+ asm volatile("sync");
+
+ for (intptr_t Line = StartLine; Line < EndLine; Line += LineSize)
+ asm volatile("icbi 0, %0" : : "r"(Line));
+ asm volatile("isync");
+# elif defined(__arm__) && defined(__GNUC__)
+ // FIXME: Can we safely always call this for __GNUC__ everywhere?
+ char *Start = (char*) Addr;
+ char *End = Start + Len;
+ __clear_cache(Start, End);
+# endif
+
+#endif // end apple
+
+ ValgrindDiscardTranslations(Addr, Len);
+}
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/MathExtras.h"
-#include "llvm/System/Errno.h"
-#include "llvm/System/Path.h"
-#include "llvm/System/Process.h"
-#include "llvm/System/Program.h"
+#include "llvm/Support/Errno.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Process.h"
+#include "llvm/Support/Program.h"
#include <cassert>
#include <cstdio>
#include <cstring>
if (ErrStr) *ErrStr = sys::StrError();
return 0;
}
-
+
return getOpenFile(FD, Filename, ErrStr, FileSize);
}
-
+
MemoryBuffer *MemoryBuffer::getOpenFile(int FD, const char *Filename,
std::string *ErrStr, int64_t FileSize) {
FileCloser FC(FD); // Close FD on return.
-
+
// If we don't know the file size, use fstat to find out. fstat on an open
// file descriptor is cheaper than stat on a random path.
if (FileSize == -1) {
}
FileSize = FileInfo.st_size;
}
-
-
+
+
// If the file is large, try to use mmap to read it in. We don't use mmap
// for small files, because this can severely fragment our address space. Also
// don't try to map files that are exactly a multiple of the system page size,
--- /dev/null
+//===- Mutex.cpp - Mutual Exclusion Lock ------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the llvm::sys::Mutex class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Config/config.h"
+#include "llvm/Support/Mutex.h"
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only TRULY operating system
+//=== independent code.
+//===----------------------------------------------------------------------===//
+
+#if !defined(ENABLE_THREADS) || ENABLE_THREADS == 0
+// Define all methods as no-ops if threading is explicitly disabled
+namespace llvm {
+using namespace sys;
+MutexImpl::MutexImpl( bool recursive) { }
+MutexImpl::~MutexImpl() { }
+bool MutexImpl::acquire() { return true; }
+bool MutexImpl::release() { return true; }
+bool MutexImpl::tryacquire() { return true; }
+}
+#else
+
+#if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_MUTEX_LOCK)
+
+#include <cassert>
+#include <pthread.h>
+#include <stdlib.h>
+
+namespace llvm {
+using namespace sys;
+
+
+// This variable is useful for situations where the pthread library has been
+// compiled with weak linkage for its interface symbols. This allows the
+// threading support to be turned off by simply not linking against -lpthread.
+// In that situation, the value of pthread_mutex_init will be 0 and
+// consequently pthread_enabled will be false. In such situations, all the
+// pthread operations become no-ops and the functions all return false. If
+// pthread_mutex_init does have an address, then mutex support is enabled.
+// Note: all LLVM tools will link against -lpthread if its available since it
+// is configured into the LIBS variable.
+// Note: this line of code generates a warning if pthread_mutex_init is not
+// declared with weak linkage. It's safe to ignore the warning.
+static const bool pthread_enabled = true;
+
+// Construct a Mutex using pthread calls
+MutexImpl::MutexImpl( bool recursive)
+ : data_(0)
+{
+ if (pthread_enabled)
+ {
+ // Declare the pthread_mutex data structures
+ pthread_mutex_t* mutex =
+ static_cast<pthread_mutex_t*>(malloc(sizeof(pthread_mutex_t)));
+ pthread_mutexattr_t attr;
+
+ // Initialize the mutex attributes
+ int errorcode = pthread_mutexattr_init(&attr);
+ assert(errorcode == 0);
+
+ // Initialize the mutex as a recursive mutex, if requested, or normal
+ // otherwise.
+ int kind = ( recursive ? PTHREAD_MUTEX_RECURSIVE : PTHREAD_MUTEX_NORMAL );
+ errorcode = pthread_mutexattr_settype(&attr, kind);
+ assert(errorcode == 0);
+
+#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__DragonFly__)
+ // Make it a process local mutex
+ errorcode = pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_PRIVATE);
+#endif
+
+ // Initialize the mutex
+ errorcode = pthread_mutex_init(mutex, &attr);
+ assert(errorcode == 0);
+
+ // Destroy the attributes
+ errorcode = pthread_mutexattr_destroy(&attr);
+ assert(errorcode == 0);
+
+ // Assign the data member
+ data_ = mutex;
+ }
+}
+
+// Destruct a Mutex
+MutexImpl::~MutexImpl()
+{
+ if (pthread_enabled)
+ {
+ pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_);
+ assert(mutex != 0);
+ pthread_mutex_destroy(mutex);
+ free(mutex);
+ }
+}
+
+bool
+MutexImpl::acquire()
+{
+ if (pthread_enabled)
+ {
+ pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_);
+ assert(mutex != 0);
+
+ int errorcode = pthread_mutex_lock(mutex);
+ return errorcode == 0;
+ } else return false;
+}
+
+bool
+MutexImpl::release()
+{
+ if (pthread_enabled)
+ {
+ pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_);
+ assert(mutex != 0);
+
+ int errorcode = pthread_mutex_unlock(mutex);
+ return errorcode == 0;
+ } else return false;
+}
+
+bool
+MutexImpl::tryacquire()
+{
+ if (pthread_enabled)
+ {
+ pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_);
+ assert(mutex != 0);
+
+ int errorcode = pthread_mutex_trylock(mutex);
+ return errorcode == 0;
+ } else return false;
+}
+
+}
+
+#elif defined(LLVM_ON_UNIX)
+#include "Unix/Mutex.inc"
+#elif defined( LLVM_ON_WIN32)
+#include "Windows/Mutex.inc"
+#else
+#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in System/Mutex.cpp
+#endif
+#endif
--- /dev/null
+//===-- Path.cpp - Implement OS Path Concept --------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file implements the operating system Path concept.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Path.h"
+#include "llvm/Config/config.h"
+#include <cassert>
+#include <cstring>
+#include <ostream>
+using namespace llvm;
+using namespace sys;
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only TRULY operating system
+//=== independent code.
+//===----------------------------------------------------------------------===//
+
+bool Path::operator==(const Path &that) const {
+ return path == that.path;
+}
+
+bool Path::operator<(const Path& that) const {
+ return path < that.path;
+}
+
+Path
+Path::GetLLVMConfigDir() {
+ Path result;
+#ifdef LLVM_ETCDIR
+ if (result.set(LLVM_ETCDIR))
+ return result;
+#endif
+ return GetLLVMDefaultConfigDir();
+}
+
+LLVMFileType
+sys::IdentifyFileType(const char *magic, unsigned length) {
+ assert(magic && "Invalid magic number string");
+ assert(length >=4 && "Invalid magic number length");
+ switch ((unsigned char)magic[0]) {
+ case 0xDE: // 0x0B17C0DE = BC wraper
+ if (magic[1] == (char)0xC0 && magic[2] == (char)0x17 &&
+ magic[3] == (char)0x0B)
+ return Bitcode_FileType;
+ break;
+ case 'B':
+ if (magic[1] == 'C' && magic[2] == (char)0xC0 && magic[3] == (char)0xDE)
+ return Bitcode_FileType;
+ break;
+ case '!':
+ if (length >= 8)
+ if (memcmp(magic,"!<arch>\n",8) == 0)
+ return Archive_FileType;
+ break;
+
+ case '\177':
+ if (magic[1] == 'E' && magic[2] == 'L' && magic[3] == 'F') {
+ if (length >= 18 && magic[17] == 0)
+ switch (magic[16]) {
+ default: break;
+ case 1: return ELF_Relocatable_FileType;
+ case 2: return ELF_Executable_FileType;
+ case 3: return ELF_SharedObject_FileType;
+ case 4: return ELF_Core_FileType;
+ }
+ }
+ break;
+
+ case 0xCA:
+ if (magic[1] == char(0xFE) && magic[2] == char(0xBA) &&
+ magic[3] == char(0xBE)) {
+ // This is complicated by an overlap with Java class files.
+ // See the Mach-O section in /usr/share/file/magic for details.
+ if (length >= 8 && magic[7] < 43)
+ // FIXME: Universal Binary of any type.
+ return Mach_O_DynamicallyLinkedSharedLib_FileType;
+ }
+ break;
+
+ case 0xFE:
+ case 0xCE: {
+ uint16_t type = 0;
+ if (magic[0] == char(0xFE) && magic[1] == char(0xED) &&
+ magic[2] == char(0xFA) && magic[3] == char(0xCE)) {
+ /* Native endian */
+ if (length >= 16) type = magic[14] << 8 | magic[15];
+ } else if (magic[0] == char(0xCE) && magic[1] == char(0xFA) &&
+ magic[2] == char(0xED) && magic[3] == char(0xFE)) {
+ /* Reverse endian */
+ if (length >= 14) type = magic[13] << 8 | magic[12];
+ }
+ switch (type) {
+ default: break;
+ case 1: return Mach_O_Object_FileType;
+ case 2: return Mach_O_Executable_FileType;
+ case 3: return Mach_O_FixedVirtualMemorySharedLib_FileType;
+ case 4: return Mach_O_Core_FileType;
+ case 5: return Mach_O_PreloadExecutable_FileType;
+ case 6: return Mach_O_DynamicallyLinkedSharedLib_FileType;
+ case 7: return Mach_O_DynamicLinker_FileType;
+ case 8: return Mach_O_Bundle_FileType;
+ case 9: return Mach_O_DynamicallyLinkedSharedLibStub_FileType;
+ case 10: break; // FIXME: MH_DSYM companion file with only debug.
+ }
+ break;
+ }
+ case 0xF0: // PowerPC Windows
+ case 0x83: // Alpha 32-bit
+ case 0x84: // Alpha 64-bit
+ case 0x66: // MPS R4000 Windows
+ case 0x50: // mc68K
+ case 0x4c: // 80386 Windows
+ if (magic[1] == 0x01)
+ return COFF_FileType;
+
+ case 0x90: // PA-RISC Windows
+ case 0x68: // mc68K Windows
+ if (magic[1] == 0x02)
+ return COFF_FileType;
+ break;
+ case 0x64: // x86-64 Windows.
+ if (magic[1] == char(0x86))
+ return COFF_FileType;
+ break;
+
+ default:
+ break;
+ }
+ return Unknown_FileType;
+}
+
+bool
+Path::isArchive() const {
+ return hasMagicNumber("!<arch>\012");
+}
+
+bool
+Path::isDynamicLibrary() const {
+ std::string Magic;
+ if (getMagicNumber(Magic, 64))
+ switch (IdentifyFileType(Magic.c_str(),
+ static_cast<unsigned>(Magic.length()))) {
+ default: return false;
+ case Mach_O_FixedVirtualMemorySharedLib_FileType:
+ case Mach_O_DynamicallyLinkedSharedLib_FileType:
+ case Mach_O_DynamicallyLinkedSharedLibStub_FileType:
+ case ELF_SharedObject_FileType:
+ case COFF_FileType: return true;
+ }
+
+ return false;
+}
+
+bool
+Path::isObjectFile() const {
+ std::string Magic;
+ if (getMagicNumber(Magic, 64))
+ if (IdentifyFileType(Magic.c_str(),
+ static_cast<unsigned>(Magic.length()))
+ != Unknown_FileType) {
+ // Everything in LLVMFileType is currently an object file.
+ return true;
+ }
+
+ return false;
+}
+
+Path
+Path::FindLibrary(std::string& name) {
+ std::vector<sys::Path> LibPaths;
+ GetSystemLibraryPaths(LibPaths);
+ for (unsigned i = 0; i < LibPaths.size(); ++i) {
+ sys::Path FullPath(LibPaths[i]);
+ FullPath.appendComponent("lib" + name + LTDL_SHLIB_EXT);
+ if (FullPath.isDynamicLibrary())
+ return FullPath;
+ FullPath.eraseSuffix();
+ FullPath.appendSuffix("a");
+ if (FullPath.isArchive())
+ return FullPath;
+ }
+ return sys::Path();
+}
+
+StringRef Path::GetDLLSuffix() {
+ return &(LTDL_SHLIB_EXT[1]);
+}
+
+bool
+Path::appendSuffix(StringRef suffix) {
+ if (!suffix.empty()) {
+ std::string save(path);
+ path.append(".");
+ path.append(suffix);
+ if (!isValid()) {
+ path = save;
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool
+Path::isBitcodeFile() const {
+ std::string actualMagic;
+ if (!getMagicNumber(actualMagic, 4))
+ return false;
+ LLVMFileType FT =
+ IdentifyFileType(actualMagic.c_str(),
+ static_cast<unsigned>(actualMagic.length()));
+ return FT == Bitcode_FileType;
+}
+
+bool Path::hasMagicNumber(StringRef Magic) const {
+ std::string actualMagic;
+ if (getMagicNumber(actualMagic, static_cast<unsigned>(Magic.size())))
+ return Magic == actualMagic;
+ return false;
+}
+
+static void getPathList(const char*path, std::vector<Path>& Paths) {
+ const char* at = path;
+ const char* delim = strchr(at, PathSeparator);
+ Path tmpPath;
+ while (delim != 0) {
+ std::string tmp(at, size_t(delim-at));
+ if (tmpPath.set(tmp))
+ if (tmpPath.canRead())
+ Paths.push_back(tmpPath);
+ at = delim + 1;
+ delim = strchr(at, PathSeparator);
+ }
+
+ if (*at != 0)
+ if (tmpPath.set(std::string(at)))
+ if (tmpPath.canRead())
+ Paths.push_back(tmpPath);
+}
+
+static StringRef getDirnameCharSep(StringRef path, const char *Sep) {
+ assert(Sep[0] != '\0' && Sep[1] == '\0' &&
+ "Sep must be a 1-character string literal.");
+ if (path.empty())
+ return ".";
+
+ // If the path is all slashes, return a single slash.
+ // Otherwise, remove all trailing slashes.
+
+ signed pos = static_cast<signed>(path.size()) - 1;
+
+ while (pos >= 0 && path[pos] == Sep[0])
+ --pos;
+
+ if (pos < 0)
+ return path[0] == Sep[0] ? Sep : ".";
+
+ // Any slashes left?
+ signed i = 0;
+
+ while (i < pos && path[i] != Sep[0])
+ ++i;
+
+ if (i == pos) // No slashes? Return "."
+ return ".";
+
+ // There is at least one slash left. Remove all trailing non-slashes.
+ while (pos >= 0 && path[pos] != Sep[0])
+ --pos;
+
+ // Remove any trailing slashes.
+ while (pos >= 0 && path[pos] == Sep[0])
+ --pos;
+
+ if (pos < 0)
+ return path[0] == Sep[0] ? Sep : ".";
+
+ return path.substr(0, pos+1);
+}
+
+// Include the truly platform-specific parts of this class.
+#if defined(LLVM_ON_UNIX)
+#include "Unix/Path.inc"
+#endif
+#if defined(LLVM_ON_WIN32)
+#include "Windows/Path.inc"
+#endif
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/DynamicLibrary.h"
-#include "llvm/System/Mutex.h"
+#include "llvm/Support/DynamicLibrary.h"
+#include "llvm/Support/Mutex.h"
#include <vector>
using namespace llvm;
#include "llvm/Config/config.h" // Get autoconf configuration settings
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Signals.h"
-#include "llvm/System/ThreadLocal.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/ThreadLocal.h"
#include "llvm/ADT/SmallString.h"
#ifdef HAVE_CRASHREPORTERCLIENT_H
--- /dev/null
+//===-- Process.cpp - Implement OS Process Concept --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file implements the operating system Process concept.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Process.h"
+#include "llvm/Config/config.h"
+
+namespace llvm {
+using namespace sys;
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only TRULY operating system
+//=== independent code.
+//===----------------------------------------------------------------------===//
+
+}
+
+// Include the platform-specific parts of this class.
+#ifdef LLVM_ON_UNIX
+#include "Unix/Process.inc"
+#endif
+#ifdef LLVM_ON_WIN32
+#include "Windows/Process.inc"
+#endif
--- /dev/null
+//===-- Program.cpp - Implement OS Program Concept --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file implements the operating system Program concept.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Program.h"
+#include "llvm/Config/config.h"
+using namespace llvm;
+using namespace sys;
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only TRULY operating system
+//=== independent code.
+//===----------------------------------------------------------------------===//
+
+int
+Program::ExecuteAndWait(const Path& path,
+ const char** args,
+ const char** envp,
+ const Path** redirects,
+ unsigned secondsToWait,
+ unsigned memoryLimit,
+ std::string* ErrMsg) {
+ Program prg;
+ if (prg.Execute(path, args, envp, redirects, memoryLimit, ErrMsg))
+ return prg.Wait(path, secondsToWait, ErrMsg);
+ else
+ return -1;
+}
+
+void
+Program::ExecuteNoWait(const Path& path,
+ const char** args,
+ const char** envp,
+ const Path** redirects,
+ unsigned memoryLimit,
+ std::string* ErrMsg) {
+ Program prg;
+ prg.Execute(path, args, envp, redirects, memoryLimit, ErrMsg);
+}
+
+// Include the platform-specific parts of this class.
+#ifdef LLVM_ON_UNIX
+#include "Unix/Program.inc"
+#endif
+#ifdef LLVM_ON_WIN32
+#include "Windows/Program.inc"
+#endif
--- /dev/null
+Design Of lib/System
+====================
+
+The software in this directory is designed to completely shield LLVM from any
+and all operating system specific functionality. It is not intended to be a
+complete operating system wrapper (such as ACE), but only to provide the
+functionality necessary to support LLVM.
+
+The software located here, of necessity, has very specific and stringent design
+rules. Violation of these rules means that cracks in the shield could form and
+the primary goal of the library is defeated. By consistently using this library,
+LLVM becomes more easily ported to new platforms since the only thing requiring
+porting is this library.
+
+Complete documentation for the library can be found in the file:
+ llvm/docs/SystemLibrary.html
+or at this URL:
+ http://llvm.org/docs/SystemLibrary.html
+
+While we recommend that you read the more detailed documentation, for the
+impatient, here's a high level summary of the library's requirements.
+
+ 1. No system header files are to be exposed through the interface.
+ 2. Std C++ and Std C header files are okay to be exposed through the interface.
+ 3. No exposed system-specific functions.
+ 4. No exposed system-specific data.
+ 5. Data in lib/System classes must use only simple C++ intrinsic types.
+ 6. Errors are handled by returning "true" and setting an optional std::string
+ 7. Library must not throw any exceptions, period.
+ 8. Interface functions must not have throw() specifications.
+ 9. No duplicate function impementations are permitted within an operating
+ system class.
+
+To accomplish these requirements, the library has numerous design criteria that
+must be satisfied. Here's a high level summary of the library's design criteria:
+
+ 1. No unused functionality (only what LLVM needs)
+ 2. High-Level Interfaces
+ 3. Use Opaque Classes
+ 4. Common Implementations
+ 5. Multiple Implementations
+ 6. Minimize Memory Allocation
+ 7. No Virtual Methods
--- /dev/null
+//===- RWMutex.cpp - Reader/Writer Mutual Exclusion Lock --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the llvm::sys::RWMutex class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Config/config.h"
+#include "llvm/Support/RWMutex.h"
+#include <cstring>
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only TRULY operating system
+//=== independent code.
+//===----------------------------------------------------------------------===//
+
+#if !defined(ENABLE_THREADS) || ENABLE_THREADS == 0
+// Define all methods as no-ops if threading is explicitly disabled
+namespace llvm {
+using namespace sys;
+RWMutexImpl::RWMutexImpl() { }
+RWMutexImpl::~RWMutexImpl() { }
+bool RWMutexImpl::reader_acquire() { return true; }
+bool RWMutexImpl::reader_release() { return true; }
+bool RWMutexImpl::writer_acquire() { return true; }
+bool RWMutexImpl::writer_release() { return true; }
+}
+#else
+
+#if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_RWLOCK_INIT)
+
+#include <cassert>
+#include <pthread.h>
+#include <stdlib.h>
+
+namespace llvm {
+using namespace sys;
+
+
+// This variable is useful for situations where the pthread library has been
+// compiled with weak linkage for its interface symbols. This allows the
+// threading support to be turned off by simply not linking against -lpthread.
+// In that situation, the value of pthread_mutex_init will be 0 and
+// consequently pthread_enabled will be false. In such situations, all the
+// pthread operations become no-ops and the functions all return false. If
+// pthread_rwlock_init does have an address, then rwlock support is enabled.
+// Note: all LLVM tools will link against -lpthread if its available since it
+// is configured into the LIBS variable.
+// Note: this line of code generates a warning if pthread_rwlock_init is not
+// declared with weak linkage. It's safe to ignore the warning.
+static const bool pthread_enabled = true;
+
+// Construct a RWMutex using pthread calls
+RWMutexImpl::RWMutexImpl()
+ : data_(0)
+{
+ if (pthread_enabled)
+ {
+ // Declare the pthread_rwlock data structures
+ pthread_rwlock_t* rwlock =
+ static_cast<pthread_rwlock_t*>(malloc(sizeof(pthread_rwlock_t)));
+
+#ifdef __APPLE__
+ // Workaround a bug/mis-feature in Darwin's pthread_rwlock_init.
+ bzero(rwlock, sizeof(pthread_rwlock_t));
+#endif
+
+ // Initialize the rwlock
+ int errorcode = pthread_rwlock_init(rwlock, NULL);
+ (void)errorcode;
+ assert(errorcode == 0);
+
+ // Assign the data member
+ data_ = rwlock;
+ }
+}
+
+// Destruct a RWMutex
+RWMutexImpl::~RWMutexImpl()
+{
+ if (pthread_enabled)
+ {
+ pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
+ assert(rwlock != 0);
+ pthread_rwlock_destroy(rwlock);
+ free(rwlock);
+ }
+}
+
+bool
+RWMutexImpl::reader_acquire()
+{
+ if (pthread_enabled)
+ {
+ pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
+ assert(rwlock != 0);
+
+ int errorcode = pthread_rwlock_rdlock(rwlock);
+ return errorcode == 0;
+ } else return false;
+}
+
+bool
+RWMutexImpl::reader_release()
+{
+ if (pthread_enabled)
+ {
+ pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
+ assert(rwlock != 0);
+
+ int errorcode = pthread_rwlock_unlock(rwlock);
+ return errorcode == 0;
+ } else return false;
+}
+
+bool
+RWMutexImpl::writer_acquire()
+{
+ if (pthread_enabled)
+ {
+ pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
+ assert(rwlock != 0);
+
+ int errorcode = pthread_rwlock_wrlock(rwlock);
+ return errorcode == 0;
+ } else return false;
+}
+
+bool
+RWMutexImpl::writer_release()
+{
+ if (pthread_enabled)
+ {
+ pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
+ assert(rwlock != 0);
+
+ int errorcode = pthread_rwlock_unlock(rwlock);
+ return errorcode == 0;
+ } else return false;
+}
+
+}
+
+#elif defined(LLVM_ON_UNIX)
+#include "Unix/RWMutex.inc"
+#elif defined( LLVM_ON_WIN32)
+#include "Windows/RWMutex.inc"
+#else
+#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in System/Mutex.cpp
+#endif
+#endif
--- /dev/null
+//===- SearchForAddressOfSpecialSymbol.cpp - Function addresses -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file pulls the addresses of certain symbols out of the linker. It must
+// include as few header files as possible because it declares the symbols as
+// void*, which would conflict with the actual symbol type if any header
+// declared it.
+//
+//===----------------------------------------------------------------------===//
+
+#include <string.h>
+
+// Must declare the symbols in the global namespace.
+static void *DoSearch(const char* symbolName) {
+#define EXPLICIT_SYMBOL(SYM) \
+ extern void *SYM; if (!strcmp(symbolName, #SYM)) return &SYM
+
+ // If this is darwin, it has some funky issues, try to solve them here. Some
+ // important symbols are marked 'private external' which doesn't allow
+ // SearchForAddressOfSymbol to find them. As such, we special case them here,
+ // there is only a small handful of them.
+
+#ifdef __APPLE__
+ {
+ EXPLICIT_SYMBOL(__ashldi3);
+ EXPLICIT_SYMBOL(__ashrdi3);
+ EXPLICIT_SYMBOL(__cmpdi2);
+ EXPLICIT_SYMBOL(__divdi3);
+ EXPLICIT_SYMBOL(__fixdfdi);
+ EXPLICIT_SYMBOL(__fixsfdi);
+ EXPLICIT_SYMBOL(__fixunsdfdi);
+ EXPLICIT_SYMBOL(__fixunssfdi);
+ EXPLICIT_SYMBOL(__floatdidf);
+ EXPLICIT_SYMBOL(__floatdisf);
+ EXPLICIT_SYMBOL(__lshrdi3);
+ EXPLICIT_SYMBOL(__moddi3);
+ EXPLICIT_SYMBOL(__udivdi3);
+ EXPLICIT_SYMBOL(__umoddi3);
+
+ // __eprintf is sometimes used for assert() handling on x86.
+#ifdef __i386__
+ EXPLICIT_SYMBOL(__eprintf);
+#endif
+ }
+#endif
+
+#ifdef __CYGWIN__
+ {
+ EXPLICIT_SYMBOL(_alloca);
+ EXPLICIT_SYMBOL(__main);
+ }
+#endif
+
+#undef EXPLICIT_SYMBOL
+ return 0;
+}
+
+namespace llvm {
+void *SearchForAddressOfSpecialSymbol(const char* symbolName) {
+ return DoSearch(symbolName);
+}
+} // namespace llvm
--- /dev/null
+//===- Signals.cpp - Signal Handling support --------------------*- 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 some helpful functions for dealing with the possibility of
+// Unix signals occuring while your program is running.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Signals.h"
+#include "llvm/Config/config.h"
+
+namespace llvm {
+using namespace sys;
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only TRULY operating system
+//=== independent code.
+//===----------------------------------------------------------------------===//
+
+}
+
+// Include the platform-specific parts of this class.
+#ifdef LLVM_ON_UNIX
+#include "Unix/Signals.inc"
+#endif
+#ifdef LLVM_ON_WIN32
+#include "Windows/Signals.inc"
+#endif
#include "llvm/Support/Debug.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Mutex.h"
+#include "llvm/Support/Mutex.h"
#include "llvm/ADT/StringExtras.h"
#include <algorithm>
#include <cstring>
//===----------------------------------------------------------------------===//
#include "llvm/Support/SystemUtils.h"
-#include "llvm/System/Process.h"
-#include "llvm/System/Program.h"
+#include "llvm/Support/Process.h"
+#include "llvm/Support/Program.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
//===----------------------------------------------------------------------===//
#include "llvm/Target/TargetRegistry.h"
-#include "llvm/System/Host.h"
+#include "llvm/Support/Host.h"
#include <cassert>
using namespace llvm;
--- /dev/null
+//===- ThreadLocal.cpp - Thread Local Data ----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the llvm::sys::ThreadLocal class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Config/config.h"
+#include "llvm/Support/ThreadLocal.h"
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only TRULY operating system
+//=== independent code.
+//===----------------------------------------------------------------------===//
+
+#if !defined(ENABLE_THREADS) || ENABLE_THREADS == 0
+// Define all methods as no-ops if threading is explicitly disabled
+namespace llvm {
+using namespace sys;
+ThreadLocalImpl::ThreadLocalImpl() { }
+ThreadLocalImpl::~ThreadLocalImpl() { }
+void ThreadLocalImpl::setInstance(const void* d) { data = const_cast<void*>(d);}
+const void* ThreadLocalImpl::getInstance() { return data; }
+void ThreadLocalImpl::removeInstance() { data = 0; }
+}
+#else
+
+#if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_GETSPECIFIC)
+
+#include <cassert>
+#include <pthread.h>
+#include <stdlib.h>
+
+namespace llvm {
+using namespace sys;
+
+ThreadLocalImpl::ThreadLocalImpl() : data(0) {
+ pthread_key_t* key = new pthread_key_t;
+ int errorcode = pthread_key_create(key, NULL);
+ assert(errorcode == 0);
+ (void) errorcode;
+ data = (void*)key;
+}
+
+ThreadLocalImpl::~ThreadLocalImpl() {
+ pthread_key_t* key = static_cast<pthread_key_t*>(data);
+ int errorcode = pthread_key_delete(*key);
+ assert(errorcode == 0);
+ (void) errorcode;
+ delete key;
+}
+
+void ThreadLocalImpl::setInstance(const void* d) {
+ pthread_key_t* key = static_cast<pthread_key_t*>(data);
+ int errorcode = pthread_setspecific(*key, d);
+ assert(errorcode == 0);
+ (void) errorcode;
+}
+
+const void* ThreadLocalImpl::getInstance() {
+ pthread_key_t* key = static_cast<pthread_key_t*>(data);
+ return pthread_getspecific(*key);
+}
+
+void ThreadLocalImpl::removeInstance() {
+ setInstance(0);
+}
+
+}
+
+#elif defined(LLVM_ON_UNIX)
+#include "Unix/ThreadLocal.inc"
+#elif defined( LLVM_ON_WIN32)
+#include "Windows/ThreadLocal.inc"
+#else
+#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in System/ThreadLocal.cpp
+#endif
+#endif
--- /dev/null
+//===-- llvm/System/Threading.cpp- Control multithreading mode --*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements llvm_start_multithreaded() and friends.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Threading.h"
+#include "llvm/Support/Atomic.h"
+#include "llvm/Support/Mutex.h"
+#include "llvm/Config/config.h"
+#include <cassert>
+
+using namespace llvm;
+
+static bool multithreaded_mode = false;
+
+static sys::Mutex* global_lock = 0;
+
+bool llvm::llvm_start_multithreaded() {
+#ifdef LLVM_MULTITHREADED
+ assert(!multithreaded_mode && "Already multithreaded!");
+ multithreaded_mode = true;
+ global_lock = new sys::Mutex(true);
+
+ // We fence here to ensure that all initialization is complete BEFORE we
+ // return from llvm_start_multithreaded().
+ sys::MemoryFence();
+ return true;
+#else
+ return false;
+#endif
+}
+
+void llvm::llvm_stop_multithreaded() {
+#ifdef LLVM_MULTITHREADED
+ assert(multithreaded_mode && "Not currently multithreaded!");
+
+ // We fence here to insure that all threaded operations are complete BEFORE we
+ // return from llvm_stop_multithreaded().
+ sys::MemoryFence();
+
+ multithreaded_mode = false;
+ delete global_lock;
+#endif
+}
+
+bool llvm::llvm_is_multithreaded() {
+ return multithreaded_mode;
+}
+
+void llvm::llvm_acquire_global_lock() {
+ if (multithreaded_mode) global_lock->acquire();
+}
+
+void llvm::llvm_release_global_lock() {
+ if (multithreaded_mode) global_lock->release();
+}
+
+#if defined(LLVM_MULTITHREADED) && defined(HAVE_PTHREAD_H)
+#include <pthread.h>
+
+struct ThreadInfo {
+ void (*UserFn)(void *);
+ void *UserData;
+};
+static void *ExecuteOnThread_Dispatch(void *Arg) {
+ ThreadInfo *TI = reinterpret_cast<ThreadInfo*>(Arg);
+ TI->UserFn(TI->UserData);
+ return 0;
+}
+
+void llvm::llvm_execute_on_thread(void (*Fn)(void*), void *UserData,
+ unsigned RequestedStackSize) {
+ ThreadInfo Info = { Fn, UserData };
+ pthread_attr_t Attr;
+ pthread_t Thread;
+
+ // Construct the attributes object.
+ if (::pthread_attr_init(&Attr) != 0)
+ return;
+
+ // Set the requested stack size, if given.
+ if (RequestedStackSize != 0) {
+ if (::pthread_attr_setstacksize(&Attr, RequestedStackSize) != 0)
+ goto error;
+ }
+
+ // Construct and execute the thread.
+ if (::pthread_create(&Thread, &Attr, ExecuteOnThread_Dispatch, &Info) != 0)
+ goto error;
+
+ // Wait for the thread and clean up.
+ ::pthread_join(Thread, 0);
+
+ error:
+ ::pthread_attr_destroy(&Attr);
+}
+
+#else
+
+// No non-pthread implementation, currently.
+
+void llvm::llvm_execute_on_thread(void (*Fn)(void*), void *UserData,
+ unsigned RequestedStackSize) {
+ (void) RequestedStackSize;
+ Fn(UserData);
+}
+
+#endif
--- /dev/null
+//===-- TimeValue.cpp - Implement OS TimeValue Concept ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the operating system TimeValue concept.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/TimeValue.h"
+#include "llvm/Config/config.h"
+
+namespace llvm {
+using namespace sys;
+
+const TimeValue TimeValue::MinTime = TimeValue ( INT64_MIN,0 );
+const TimeValue TimeValue::MaxTime = TimeValue ( INT64_MAX,0 );
+const TimeValue TimeValue::ZeroTime = TimeValue ( 0,0 );
+const TimeValue TimeValue::PosixZeroTime = TimeValue ( -946684800,0 );
+const TimeValue TimeValue::Win32ZeroTime = TimeValue ( -12591158400ULL,0 );
+
+void
+TimeValue::normalize( void ) {
+ if ( nanos_ >= NANOSECONDS_PER_SECOND ) {
+ do {
+ seconds_++;
+ nanos_ -= NANOSECONDS_PER_SECOND;
+ } while ( nanos_ >= NANOSECONDS_PER_SECOND );
+ } else if (nanos_ <= -NANOSECONDS_PER_SECOND ) {
+ do {
+ seconds_--;
+ nanos_ += NANOSECONDS_PER_SECOND;
+ } while (nanos_ <= -NANOSECONDS_PER_SECOND);
+ }
+
+ if (seconds_ >= 1 && nanos_ < 0) {
+ seconds_--;
+ nanos_ += NANOSECONDS_PER_SECOND;
+ } else if (seconds_ < 0 && nanos_ > 0) {
+ seconds_++;
+ nanos_ -= NANOSECONDS_PER_SECOND;
+ }
+}
+
+}
+
+/// Include the platform specific portion of TimeValue class
+#ifdef LLVM_ON_UNIX
+#include "Unix/TimeValue.inc"
+#endif
+#ifdef LLVM_ON_WIN32
+#include "Windows/TimeValue.inc"
+#endif
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Format.h"
-#include "llvm/System/Mutex.h"
-#include "llvm/System/Process.h"
+#include "llvm/Support/Mutex.h"
+#include "llvm/Support/Process.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringMap.h"
using namespace llvm;
//===----------------------------------------------------------------------===//
#include "llvm/Support/ToolOutputFile.h"
-#include "llvm/System/Signals.h"
+#include "llvm/Support/Signals.h"
using namespace llvm;
tool_output_file::CleanupInstaller::CleanupInstaller(const char *filename)
--- /dev/null
+//===-- Alarm.inc - Implement Unix Alarm Support ----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the UNIX Alarm support.
+//
+//===----------------------------------------------------------------------===//
+
+#include <signal.h>
+#include <unistd.h>
+#include <cassert>
+using namespace llvm;
+
+/// AlarmCancelled - This flag is set by the SIGINT signal handler if the
+/// user presses CTRL-C.
+static volatile bool AlarmCancelled = false;
+
+/// AlarmTriggered - This flag is set by the SIGALRM signal handler if the
+/// alarm was triggered.
+static volatile bool AlarmTriggered = false;
+
+/// NestedSOI - Sanity check. Alarms cannot be nested or run in parallel.
+/// This ensures that they never do.
+static bool NestedSOI = false;
+
+static RETSIGTYPE SigIntHandler(int Sig) {
+ AlarmCancelled = true;
+ signal(SIGINT, SigIntHandler);
+}
+
+static RETSIGTYPE SigAlarmHandler(int Sig) {
+ AlarmTriggered = true;
+}
+
+static void (*OldSigIntHandler) (int);
+
+void sys::SetupAlarm(unsigned seconds) {
+ assert(!NestedSOI && "sys::SetupAlarm calls cannot be nested!");
+ NestedSOI = true;
+ AlarmCancelled = false;
+ AlarmTriggered = false;
+ ::signal(SIGALRM, SigAlarmHandler);
+ OldSigIntHandler = ::signal(SIGINT, SigIntHandler);
+ ::alarm(seconds);
+}
+
+void sys::TerminateAlarm() {
+ assert(NestedSOI && "sys::TerminateAlarm called without sys::SetupAlarm!");
+ ::alarm(0);
+ ::signal(SIGALRM, SIG_DFL);
+ ::signal(SIGINT, OldSigIntHandler);
+ AlarmCancelled = false;
+ AlarmTriggered = false;
+ NestedSOI = false;
+}
+
+int sys::AlarmStatus() {
+ if (AlarmCancelled)
+ return -1;
+ if (AlarmTriggered)
+ return 1;
+ return 0;
+}
+
+void sys::Sleep(unsigned n) {
+ ::sleep(n);
+}
--- /dev/null
+ //===- llvm/System/Unix/Host.inc -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the UNIX Host support.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic UNIX code that
+//=== is guaranteed to work on *all* UNIX variants.
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Config/config.h"
+#include "llvm/ADT/StringRef.h"
+#include "Unix.h"
+#include <sys/utsname.h>
+#include <string>
+
+using namespace llvm;
+
+static std::string getOSVersion() {
+ struct utsname info;
+
+ if (uname(&info))
+ return "";
+
+ return info.release;
+}
+
+std::string sys::getHostTriple() {
+ // FIXME: Derive directly instead of relying on the autoconf generated
+ // variable.
+
+ StringRef HostTripleString(LLVM_HOSTTRIPLE);
+ std::pair<StringRef, StringRef> ArchSplit = HostTripleString.split('-');
+
+ // Normalize the arch, since the host triple may not actually match the host.
+ std::string Arch = ArchSplit.first;
+
+ // It would be nice to do this in terms of llvm::Triple, but that is in
+ // Support which is layered above us.
+#if defined(__x86_64__)
+ Arch = "x86_64";
+#elif defined(__i386__)
+ Arch = "i386";
+#elif defined(__ppc64__)
+ Arch = "powerpc64";
+#elif defined(__ppc__)
+ Arch = "powerpc";
+#elif defined(__arm__)
+
+ // FIXME: We need to pick the right ARM triple (which involves querying the
+ // chip). However, for now this is most important for LLVM arch selection, so
+ // we only need to make sure to distinguish ARM and Thumb.
+# if defined(__thumb__)
+ Arch = "thumb";
+# else
+ Arch = "arm";
+# endif
+
+#else
+
+ // FIXME: When enough auto-detection is in place, this should just
+ // #error. Then at least the arch selection is done, and we only need the OS
+ // etc selection to kill off the use of LLVM_HOSTTRIPLE.
+
+#endif
+
+ std::string Triple(Arch);
+ Triple += '-';
+ Triple += ArchSplit.second;
+
+ // Force i<N>86 to i386.
+ if (Triple[0] == 'i' && isdigit(Triple[1]) &&
+ Triple[2] == '8' && Triple[3] == '6')
+ Triple[1] = '3';
+
+ // On darwin, we want to update the version to match that of the
+ // host.
+ std::string::size_type DarwinDashIdx = Triple.find("-darwin");
+ if (DarwinDashIdx != std::string::npos) {
+ Triple.resize(DarwinDashIdx + strlen("-darwin"));
+
+ // Only add the major part of the os version.
+ std::string Version = getOSVersion();
+ Triple += Version.substr(0, Version.find('.'));
+ }
+
+ return Triple;
+}
--- /dev/null
+//===- Unix/Memory.cpp - Generic UNIX System Configuration ------*- 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 some functions for various memory management utilities.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Unix.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Process.h"
+
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+
+#ifdef __APPLE__
+#include <mach/mach.h>
+#endif
+
+/// AllocateRWX - Allocate a slab of memory with read/write/execute
+/// permissions. This is typically used for JIT applications where we want
+/// to emit code to the memory then jump to it. Getting this type of memory
+/// is very OS specific.
+///
+llvm::sys::MemoryBlock
+llvm::sys::Memory::AllocateRWX(size_t NumBytes, const MemoryBlock* NearBlock,
+ std::string *ErrMsg) {
+ if (NumBytes == 0) return MemoryBlock();
+
+ size_t pageSize = Process::GetPageSize();
+ size_t NumPages = (NumBytes+pageSize-1)/pageSize;
+
+ int fd = -1;
+#ifdef NEED_DEV_ZERO_FOR_MMAP
+ static int zero_fd = open("/dev/zero", O_RDWR);
+ if (zero_fd == -1) {
+ MakeErrMsg(ErrMsg, "Can't open /dev/zero device");
+ return MemoryBlock();
+ }
+ fd = zero_fd;
+#endif
+
+ int flags = MAP_PRIVATE |
+#ifdef HAVE_MMAP_ANONYMOUS
+ MAP_ANONYMOUS
+#else
+ MAP_ANON
+#endif
+ ;
+
+ void* start = NearBlock ? (unsigned char*)NearBlock->base() +
+ NearBlock->size() : 0;
+
+#if defined(__APPLE__) && defined(__arm__)
+ void *pa = ::mmap(start, pageSize*NumPages, PROT_READ|PROT_EXEC,
+ flags, fd, 0);
+#else
+ void *pa = ::mmap(start, pageSize*NumPages, PROT_READ|PROT_WRITE|PROT_EXEC,
+ flags, fd, 0);
+#endif
+ if (pa == MAP_FAILED) {
+ if (NearBlock) //Try again without a near hint
+ return AllocateRWX(NumBytes, 0);
+
+ MakeErrMsg(ErrMsg, "Can't allocate RWX Memory");
+ return MemoryBlock();
+ }
+
+#if defined(__APPLE__) && defined(__arm__)
+ kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)pa,
+ (vm_size_t)(pageSize*NumPages), 0,
+ VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_COPY);
+ if (KERN_SUCCESS != kr) {
+ MakeErrMsg(ErrMsg, "vm_protect max RX failed");
+ return sys::MemoryBlock();
+ }
+
+ kr = vm_protect(mach_task_self(), (vm_address_t)pa,
+ (vm_size_t)(pageSize*NumPages), 0,
+ VM_PROT_READ | VM_PROT_WRITE);
+ if (KERN_SUCCESS != kr) {
+ MakeErrMsg(ErrMsg, "vm_protect RW failed");
+ return sys::MemoryBlock();
+ }
+#endif
+
+ MemoryBlock result;
+ result.Address = pa;
+ result.Size = NumPages*pageSize;
+
+ return result;
+}
+
+bool llvm::sys::Memory::ReleaseRWX(MemoryBlock &M, std::string *ErrMsg) {
+ if (M.Address == 0 || M.Size == 0) return false;
+ if (0 != ::munmap(M.Address, M.Size))
+ return MakeErrMsg(ErrMsg, "Can't release RWX Memory");
+ return false;
+}
+
+bool llvm::sys::Memory::setWritable (MemoryBlock &M, std::string *ErrMsg) {
+#if defined(__APPLE__) && defined(__arm__)
+ if (M.Address == 0 || M.Size == 0) return false;
+ sys::Memory::InvalidateInstructionCache(M.Address, M.Size);
+ kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)M.Address,
+ (vm_size_t)M.Size, 0, VM_PROT_READ | VM_PROT_WRITE);
+ return KERN_SUCCESS == kr;
+#else
+ return true;
+#endif
+}
+
+bool llvm::sys::Memory::setExecutable (MemoryBlock &M, std::string *ErrMsg) {
+#if defined(__APPLE__) && defined(__arm__)
+ if (M.Address == 0 || M.Size == 0) return false;
+ sys::Memory::InvalidateInstructionCache(M.Address, M.Size);
+ kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)M.Address,
+ (vm_size_t)M.Size, 0, VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_COPY);
+ return KERN_SUCCESS == kr;
+#else
+ return false;
+#endif
+}
+
+bool llvm::sys::Memory::setRangeWritable(const void *Addr, size_t Size) {
+#if defined(__APPLE__) && defined(__arm__)
+ kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)Addr,
+ (vm_size_t)Size, 0,
+ VM_PROT_READ | VM_PROT_WRITE);
+ return KERN_SUCCESS == kr;
+#else
+ return true;
+#endif
+}
+
+bool llvm::sys::Memory::setRangeExecutable(const void *Addr, size_t Size) {
+#if defined(__APPLE__) && defined(__arm__)
+ kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)Addr,
+ (vm_size_t)Size, 0,
+ VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_COPY);
+ return KERN_SUCCESS == kr;
+#else
+ return true;
+#endif
+}
--- /dev/null
+//===- llvm/System/Unix/Mutex.inc - Unix Mutex Implementation ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Unix specific (non-pthread) Mutex class.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic UNIX code that
+//=== is guaranteed to work on *all* UNIX variants.
+//===----------------------------------------------------------------------===//
+
+namespace llvm
+{
+using namespace sys;
+
+MutexImpl::MutexImpl( bool recursive)
+{
+}
+
+MutexImpl::~MutexImpl()
+{
+}
+
+bool
+MutexImpl::release()
+{
+ return true;
+}
+
+bool
+MutexImpl::tryacquire( void )
+{
+ return true;
+}
+
+}
--- /dev/null
+//===- llvm/System/Unix/Path.cpp - Unix Path Implementation -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Unix specific portion of the Path class.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic UNIX code that
+//=== is guaranteed to work on *all* UNIX variants.
+//===----------------------------------------------------------------------===//
+
+#include "Unix.h"
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UTIME_H
+#include <utime.h>
+#endif
+#if HAVE_TIME_H
+#include <time.h>
+#endif
+#if HAVE_DIRENT_H
+# include <dirent.h>
+# define NAMLEN(dirent) strlen((dirent)->d_name)
+#else
+# define dirent direct
+# define NAMLEN(dirent) (dirent)->d_namlen
+# if HAVE_SYS_NDIR_H
+# include <sys/ndir.h>
+# endif
+# if HAVE_SYS_DIR_H
+# include <sys/dir.h>
+# endif
+# if HAVE_NDIR_H
+# include <ndir.h>
+# endif
+#endif
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#ifdef __APPLE__
+#include <mach-o/dyld.h>
+#endif
+
+// Put in a hack for Cygwin which falsely reports that the mkdtemp function
+// is available when it is not.
+#ifdef __CYGWIN__
+# undef HAVE_MKDTEMP
+#endif
+
+namespace {
+inline bool lastIsSlash(const std::string& path) {
+ return !path.empty() && path[path.length() - 1] == '/';
+}
+
+}
+
+namespace llvm {
+using namespace sys;
+
+const char sys::PathSeparator = ':';
+
+StringRef Path::GetEXESuffix() {
+ return StringRef();
+}
+
+Path::Path(StringRef p)
+ : path(p) {}
+
+Path::Path(const char *StrStart, unsigned StrLen)
+ : path(StrStart, StrLen) {}
+
+Path&
+Path::operator=(StringRef that) {
+ path.assign(that.data(), that.size());
+ return *this;
+}
+
+bool
+Path::isValid() const {
+ // Empty paths are considered invalid here.
+ // This code doesn't check MAXPATHLEN because there's no need. Nothing in
+ // LLVM manipulates Paths with fixed-sizes arrays, and if the OS can't
+ // handle names longer than some limit, it'll report this on demand using
+ // ENAMETOLONG.
+ return !path.empty();
+}
+
+bool
+Path::isAbsolute(const char *NameStart, unsigned NameLen) {
+ assert(NameStart);
+ if (NameLen == 0)
+ return false;
+ return NameStart[0] == '/';
+}
+
+bool
+Path::isAbsolute() const {
+ if (path.empty())
+ return false;
+ return path[0] == '/';
+}
+
+void Path::makeAbsolute() {
+ if (isAbsolute())
+ return;
+
+ Path CWD = Path::GetCurrentDirectory();
+ assert(CWD.isAbsolute() && "GetCurrentDirectory returned relative path!");
+
+ CWD.appendComponent(path);
+
+ path = CWD.str();
+}
+
+Path
+Path::GetRootDirectory() {
+ Path result;
+ result.set("/");
+ return result;
+}
+
+Path
+Path::GetTemporaryDirectory(std::string *ErrMsg) {
+#if defined(HAVE_MKDTEMP)
+ // The best way is with mkdtemp but that's not available on many systems,
+ // Linux and FreeBSD have it. Others probably won't.
+ char pathname[] = "/tmp/llvm_XXXXXX";
+ if (0 == mkdtemp(pathname)) {
+ MakeErrMsg(ErrMsg,
+ std::string(pathname) + ": can't create temporary directory");
+ return Path();
+ }
+ return Path(pathname);
+#elif defined(HAVE_MKSTEMP)
+ // If no mkdtemp is available, mkstemp can be used to create a temporary file
+ // which is then removed and created as a directory. We prefer this over
+ // mktemp because of mktemp's inherent security and threading risks. We still
+ // have a slight race condition from the time the temporary file is created to
+ // the time it is re-created as a directoy.
+ char pathname[] = "/tmp/llvm_XXXXXX";
+ int fd = 0;
+ if (-1 == (fd = mkstemp(pathname))) {
+ MakeErrMsg(ErrMsg,
+ std::string(pathname) + ": can't create temporary directory");
+ return Path();
+ }
+ ::close(fd);
+ ::unlink(pathname); // start race condition, ignore errors
+ if (-1 == ::mkdir(pathname, S_IRWXU)) { // end race condition
+ MakeErrMsg(ErrMsg,
+ std::string(pathname) + ": can't create temporary directory");
+ return Path();
+ }
+ return Path(pathname);
+#elif defined(HAVE_MKTEMP)
+ // If a system doesn't have mkdtemp(3) or mkstemp(3) but it does have
+ // mktemp(3) then we'll assume that system (e.g. AIX) has a reasonable
+ // implementation of mktemp(3) and doesn't follow BSD 4.3's lead of replacing
+ // the XXXXXX with the pid of the process and a letter. That leads to only
+ // twenty six temporary files that can be generated.
+ char pathname[] = "/tmp/llvm_XXXXXX";
+ char *TmpName = ::mktemp(pathname);
+ if (TmpName == 0) {
+ MakeErrMsg(ErrMsg,
+ std::string(TmpName) + ": can't create unique directory name");
+ return Path();
+ }
+ if (-1 == ::mkdir(TmpName, S_IRWXU)) {
+ MakeErrMsg(ErrMsg,
+ std::string(TmpName) + ": can't create temporary directory");
+ return Path();
+ }
+ return Path(TmpName);
+#else
+ // This is the worst case implementation. tempnam(3) leaks memory unless its
+ // on an SVID2 (or later) system. On BSD 4.3 it leaks. tmpnam(3) has thread
+ // issues. The mktemp(3) function doesn't have enough variability in the
+ // temporary name generated. So, we provide our own implementation that
+ // increments an integer from a random number seeded by the current time. This
+ // should be sufficiently unique that we don't have many collisions between
+ // processes. Generally LLVM processes don't run very long and don't use very
+ // many temporary files so this shouldn't be a big issue for LLVM.
+ static time_t num = ::time(0);
+ char pathname[MAXPATHLEN];
+ do {
+ num++;
+ sprintf(pathname, "/tmp/llvm_%010u", unsigned(num));
+ } while ( 0 == access(pathname, F_OK ) );
+ if (-1 == ::mkdir(pathname, S_IRWXU)) {
+ MakeErrMsg(ErrMsg,
+ std::string(pathname) + ": can't create temporary directory");
+ return Path();
+ }
+ return Path(pathname);
+#endif
+}
+
+void
+Path::GetSystemLibraryPaths(std::vector<sys::Path>& Paths) {
+#ifdef LTDL_SHLIBPATH_VAR
+ char* env_var = getenv(LTDL_SHLIBPATH_VAR);
+ if (env_var != 0) {
+ getPathList(env_var,Paths);
+ }
+#endif
+ // FIXME: Should this look at LD_LIBRARY_PATH too?
+ Paths.push_back(sys::Path("/usr/local/lib/"));
+ Paths.push_back(sys::Path("/usr/X11R6/lib/"));
+ Paths.push_back(sys::Path("/usr/lib/"));
+ Paths.push_back(sys::Path("/lib/"));
+}
+
+void
+Path::GetBitcodeLibraryPaths(std::vector<sys::Path>& Paths) {
+ char * env_var = getenv("LLVM_LIB_SEARCH_PATH");
+ if (env_var != 0) {
+ getPathList(env_var,Paths);
+ }
+#ifdef LLVM_LIBDIR
+ {
+ Path tmpPath;
+ if (tmpPath.set(LLVM_LIBDIR))
+ if (tmpPath.canRead())
+ Paths.push_back(tmpPath);
+ }
+#endif
+ GetSystemLibraryPaths(Paths);
+}
+
+Path
+Path::GetLLVMDefaultConfigDir() {
+ return Path("/etc/llvm/");
+}
+
+Path
+Path::GetUserHomeDirectory() {
+ const char* home = getenv("HOME");
+ if (home) {
+ Path result;
+ if (result.set(home))
+ return result;
+ }
+ return GetRootDirectory();
+}
+
+Path
+Path::GetCurrentDirectory() {
+ char pathname[MAXPATHLEN];
+ if (!getcwd(pathname,MAXPATHLEN)) {
+ assert (false && "Could not query current working directory.");
+ return Path();
+ }
+
+ return Path(pathname);
+}
+
+#if defined(__FreeBSD__) || defined (__NetBSD__) || defined(__minix)
+static int
+test_dir(char buf[PATH_MAX], char ret[PATH_MAX],
+ const char *dir, const char *bin)
+{
+ struct stat sb;
+
+ snprintf(buf, PATH_MAX, "%s/%s", dir, bin);
+ if (realpath(buf, ret) == NULL)
+ return (1);
+ if (stat(buf, &sb) != 0)
+ return (1);
+
+ return (0);
+}
+
+static char *
+getprogpath(char ret[PATH_MAX], const char *bin)
+{
+ char *pv, *s, *t, buf[PATH_MAX];
+
+ /* First approach: absolute path. */
+ if (bin[0] == '/') {
+ if (test_dir(buf, ret, "/", bin) == 0)
+ return (ret);
+ return (NULL);
+ }
+
+ /* Second approach: relative path. */
+ if (strchr(bin, '/') != NULL) {
+ if (getcwd(buf, PATH_MAX) == NULL)
+ return (NULL);
+ if (test_dir(buf, ret, buf, bin) == 0)
+ return (ret);
+ return (NULL);
+ }
+
+ /* Third approach: $PATH */
+ if ((pv = getenv("PATH")) == NULL)
+ return (NULL);
+ s = pv = strdup(pv);
+ if (pv == NULL)
+ return (NULL);
+ while ((t = strsep(&s, ":")) != NULL) {
+ if (test_dir(buf, ret, t, bin) == 0) {
+ free(pv);
+ return (ret);
+ }
+ }
+ free(pv);
+ return (NULL);
+}
+#endif // __FreeBSD__ || __NetBSD__
+
+/// GetMainExecutable - Return the path to the main executable, given the
+/// value of argv[0] from program startup.
+Path Path::GetMainExecutable(const char *argv0, void *MainAddr) {
+#if defined(__APPLE__)
+ // On OS X the executable path is saved to the stack by dyld. Reading it
+ // from there is much faster than calling dladdr, especially for large
+ // binaries with symbols.
+ char exe_path[MAXPATHLEN];
+ uint32_t size = sizeof(exe_path);
+ if (_NSGetExecutablePath(exe_path, &size) == 0) {
+ char link_path[MAXPATHLEN];
+ if (realpath(exe_path, link_path))
+ return Path(link_path);
+ }
+#elif defined(__FreeBSD__) || defined (__NetBSD__) || defined(__minix)
+ char exe_path[PATH_MAX];
+
+ if (getprogpath(exe_path, argv0) != NULL)
+ return Path(exe_path);
+#elif defined(__linux__) || defined(__CYGWIN__)
+ char exe_path[MAXPATHLEN];
+ ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path));
+ if (len >= 0)
+ return Path(StringRef(exe_path, len));
+#elif defined(HAVE_DLFCN_H)
+ // Use dladdr to get executable path if available.
+ Dl_info DLInfo;
+ int err = dladdr(MainAddr, &DLInfo);
+ if (err == 0)
+ return Path();
+
+ // If the filename is a symlink, we need to resolve and return the location of
+ // the actual executable.
+ char link_path[MAXPATHLEN];
+ if (realpath(DLInfo.dli_fname, link_path))
+ return Path(link_path);
+#else
+#error GetMainExecutable is not implemented on this host yet.
+#endif
+ return Path();
+}
+
+
+StringRef Path::getDirname() const {
+ return getDirnameCharSep(path, "/");
+}
+
+StringRef
+Path::getBasename() const {
+ // Find the last slash
+ std::string::size_type slash = path.rfind('/');
+ if (slash == std::string::npos)
+ slash = 0;
+ else
+ slash++;
+
+ std::string::size_type dot = path.rfind('.');
+ if (dot == std::string::npos || dot < slash)
+ return StringRef(path).substr(slash);
+ else
+ return StringRef(path).substr(slash, dot - slash);
+}
+
+StringRef
+Path::getSuffix() const {
+ // Find the last slash
+ std::string::size_type slash = path.rfind('/');
+ if (slash == std::string::npos)
+ slash = 0;
+ else
+ slash++;
+
+ std::string::size_type dot = path.rfind('.');
+ if (dot == std::string::npos || dot < slash)
+ return StringRef();
+ else
+ return StringRef(path).substr(dot + 1);
+}
+
+bool Path::getMagicNumber(std::string &Magic, unsigned len) const {
+ assert(len < 1024 && "Request for magic string too long");
+ char Buf[1025];
+ int fd = ::open(path.c_str(), O_RDONLY);
+ if (fd < 0)
+ return false;
+ ssize_t bytes_read = ::read(fd, Buf, len);
+ ::close(fd);
+ if (ssize_t(len) != bytes_read)
+ return false;
+ Magic.assign(Buf, len);
+ return true;
+}
+
+bool
+Path::exists() const {
+ return 0 == access(path.c_str(), F_OK );
+}
+
+bool
+Path::isDirectory() const {
+ struct stat buf;
+ if (0 != stat(path.c_str(), &buf))
+ return false;
+ return ((buf.st_mode & S_IFMT) == S_IFDIR) ? true : false;
+}
+
+bool
+Path::isSymLink() const {
+ struct stat buf;
+ if (0 != lstat(path.c_str(), &buf))
+ return false;
+ return S_ISLNK(buf.st_mode);
+}
+
+
+bool
+Path::canRead() const {
+ return 0 == access(path.c_str(), R_OK);
+}
+
+bool
+Path::canWrite() const {
+ return 0 == access(path.c_str(), W_OK);
+}
+
+bool
+Path::isRegularFile() const {
+ // Get the status so we can determine if it's a file or directory
+ struct stat buf;
+
+ if (0 != stat(path.c_str(), &buf))
+ return false;
+
+ if (S_ISREG(buf.st_mode))
+ return true;
+
+ return false;
+}
+
+bool
+Path::canExecute() const {
+ if (0 != access(path.c_str(), R_OK | X_OK ))
+ return false;
+ struct stat buf;
+ if (0 != stat(path.c_str(), &buf))
+ return false;
+ if (!S_ISREG(buf.st_mode))
+ return false;
+ return true;
+}
+
+StringRef
+Path::getLast() const {
+ // Find the last slash
+ size_t pos = path.rfind('/');
+
+ // Handle the corner cases
+ if (pos == std::string::npos)
+ return path;
+
+ // If the last character is a slash
+ if (pos == path.length()-1) {
+ // Find the second to last slash
+ size_t pos2 = path.rfind('/', pos-1);
+ if (pos2 == std::string::npos)
+ return StringRef(path).substr(0,pos);
+ else
+ return StringRef(path).substr(pos2+1,pos-pos2-1);
+ }
+ // Return everything after the last slash
+ return StringRef(path).substr(pos+1);
+}
+
+const FileStatus *
+PathWithStatus::getFileStatus(bool update, std::string *ErrStr) const {
+ if (!fsIsValid || update) {
+ struct stat buf;
+ if (0 != stat(path.c_str(), &buf)) {
+ MakeErrMsg(ErrStr, path + ": can't get status of file");
+ return 0;
+ }
+ status.fileSize = buf.st_size;
+ status.modTime.fromEpochTime(buf.st_mtime);
+ status.mode = buf.st_mode;
+ status.user = buf.st_uid;
+ status.group = buf.st_gid;
+ status.uniqueID = uint64_t(buf.st_ino);
+ status.isDir = S_ISDIR(buf.st_mode);
+ status.isFile = S_ISREG(buf.st_mode);
+ fsIsValid = true;
+ }
+ return &status;
+}
+
+static bool AddPermissionBits(const Path &File, int bits) {
+ // Get the umask value from the operating system. We want to use it
+ // when changing the file's permissions. Since calling umask() sets
+ // the umask and returns its old value, we must call it a second
+ // time to reset it to the user's preference.
+ int mask = umask(0777); // The arg. to umask is arbitrary.
+ umask(mask); // Restore the umask.
+
+ // Get the file's current mode.
+ struct stat buf;
+ if (0 != stat(File.c_str(), &buf))
+ return false;
+ // Change the file to have whichever permissions bits from 'bits'
+ // that the umask would not disable.
+ if ((chmod(File.c_str(), (buf.st_mode | (bits & ~mask)))) == -1)
+ return false;
+ return true;
+}
+
+bool Path::makeReadableOnDisk(std::string* ErrMsg) {
+ if (!AddPermissionBits(*this, 0444))
+ return MakeErrMsg(ErrMsg, path + ": can't make file readable");
+ return false;
+}
+
+bool Path::makeWriteableOnDisk(std::string* ErrMsg) {
+ if (!AddPermissionBits(*this, 0222))
+ return MakeErrMsg(ErrMsg, path + ": can't make file writable");
+ return false;
+}
+
+bool Path::makeExecutableOnDisk(std::string* ErrMsg) {
+ if (!AddPermissionBits(*this, 0111))
+ return MakeErrMsg(ErrMsg, path + ": can't make file executable");
+ return false;
+}
+
+bool
+Path::getDirectoryContents(std::set<Path>& result, std::string* ErrMsg) const {
+ DIR* direntries = ::opendir(path.c_str());
+ if (direntries == 0)
+ return MakeErrMsg(ErrMsg, path + ": can't open directory");
+
+ std::string dirPath = path;
+ if (!lastIsSlash(dirPath))
+ dirPath += '/';
+
+ result.clear();
+ struct dirent* de = ::readdir(direntries);
+ for ( ; de != 0; de = ::readdir(direntries)) {
+ if (de->d_name[0] != '.') {
+ Path aPath(dirPath + (const char*)de->d_name);
+ struct stat st;
+ if (0 != lstat(aPath.path.c_str(), &st)) {
+ if (S_ISLNK(st.st_mode))
+ continue; // dangling symlink -- ignore
+ return MakeErrMsg(ErrMsg,
+ aPath.path + ": can't determine file object type");
+ }
+ result.insert(aPath);
+ }
+ }
+
+ closedir(direntries);
+ return false;
+}
+
+bool
+Path::set(StringRef a_path) {
+ if (a_path.empty())
+ return false;
+ path = a_path;
+ return true;
+}
+
+bool
+Path::appendComponent(StringRef name) {
+ if (name.empty())
+ return false;
+ if (!lastIsSlash(path))
+ path += '/';
+ path += name;
+ return true;
+}
+
+bool
+Path::eraseComponent() {
+ size_t slashpos = path.rfind('/',path.size());
+ if (slashpos == 0 || slashpos == std::string::npos) {
+ path.erase();
+ return true;
+ }
+ if (slashpos == path.size() - 1)
+ slashpos = path.rfind('/',slashpos-1);
+ if (slashpos == std::string::npos) {
+ path.erase();
+ return true;
+ }
+ path.erase(slashpos);
+ return true;
+}
+
+bool
+Path::eraseSuffix() {
+ size_t dotpos = path.rfind('.',path.size());
+ size_t slashpos = path.rfind('/',path.size());
+ if (dotpos != std::string::npos) {
+ if (slashpos == std::string::npos || dotpos > slashpos+1) {
+ path.erase(dotpos, path.size()-dotpos);
+ return true;
+ }
+ }
+ return false;
+}
+
+static bool createDirectoryHelper(char* beg, char* end, bool create_parents) {
+
+ if (access(beg, R_OK | W_OK) == 0)
+ return false;
+
+ if (create_parents) {
+
+ char* c = end;
+
+ for (; c != beg; --c)
+ if (*c == '/') {
+
+ // Recurse to handling the parent directory.
+ *c = '\0';
+ bool x = createDirectoryHelper(beg, c, create_parents);
+ *c = '/';
+
+ // Return if we encountered an error.
+ if (x)
+ return true;
+
+ break;
+ }
+ }
+
+ return mkdir(beg, S_IRWXU | S_IRWXG) != 0;
+}
+
+bool
+Path::createDirectoryOnDisk( bool create_parents, std::string* ErrMsg ) {
+ // Get a writeable copy of the path name
+ std::string pathname(path);
+
+ // Null-terminate the last component
+ size_t lastchar = path.length() - 1 ;
+
+ if (pathname[lastchar] != '/')
+ ++lastchar;
+
+ pathname[lastchar] = '\0';
+
+ if (createDirectoryHelper(&pathname[0], &pathname[lastchar], create_parents))
+ return MakeErrMsg(ErrMsg, pathname + ": can't create directory");
+
+ return false;
+}
+
+bool
+Path::createFileOnDisk(std::string* ErrMsg) {
+ // Create the file
+ int fd = ::creat(path.c_str(), S_IRUSR | S_IWUSR);
+ if (fd < 0)
+ return MakeErrMsg(ErrMsg, path + ": can't create file");
+ ::close(fd);
+ return false;
+}
+
+bool
+Path::createTemporaryFileOnDisk(bool reuse_current, std::string* ErrMsg) {
+ // Make this into a unique file name
+ if (makeUnique( reuse_current, ErrMsg ))
+ return true;
+
+ // create the file
+ int fd = ::open(path.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0666);
+ if (fd < 0)
+ return MakeErrMsg(ErrMsg, path + ": can't create temporary file");
+ ::close(fd);
+ return false;
+}
+
+bool
+Path::eraseFromDisk(bool remove_contents, std::string *ErrStr) const {
+ // Get the status so we can determine if it's a file or directory.
+ struct stat buf;
+ if (0 != stat(path.c_str(), &buf)) {
+ MakeErrMsg(ErrStr, path + ": can't get status of file");
+ return true;
+ }
+
+ // Note: this check catches strange situations. In all cases, LLVM should
+ // only be involved in the creation and deletion of regular files. This
+ // check ensures that what we're trying to erase is a regular file. It
+ // effectively prevents LLVM from erasing things like /dev/null, any block
+ // special file, or other things that aren't "regular" files.
+ if (S_ISREG(buf.st_mode)) {
+ if (unlink(path.c_str()) != 0)
+ return MakeErrMsg(ErrStr, path + ": can't destroy file");
+ return false;
+ }
+
+ if (!S_ISDIR(buf.st_mode)) {
+ if (ErrStr) *ErrStr = "not a file or directory";
+ return true;
+ }
+
+ if (remove_contents) {
+ // Recursively descend the directory to remove its contents.
+ std::string cmd = "/bin/rm -rf " + path;
+ if (system(cmd.c_str()) != 0) {
+ MakeErrMsg(ErrStr, path + ": failed to recursively remove directory.");
+ return true;
+ }
+ return false;
+ }
+
+ // Otherwise, try to just remove the one directory.
+ std::string pathname(path);
+ size_t lastchar = path.length() - 1;
+ if (pathname[lastchar] == '/')
+ pathname[lastchar] = '\0';
+ else
+ pathname[lastchar+1] = '\0';
+
+ if (rmdir(pathname.c_str()) != 0)
+ return MakeErrMsg(ErrStr, pathname + ": can't erase directory");
+ return false;
+}
+
+bool
+Path::renamePathOnDisk(const Path& newName, std::string* ErrMsg) {
+ if (0 != ::rename(path.c_str(), newName.c_str()))
+ return MakeErrMsg(ErrMsg, std::string("can't rename '") + path + "' as '" +
+ newName.str() + "'");
+ return false;
+}
+
+bool
+Path::setStatusInfoOnDisk(const FileStatus &si, std::string *ErrStr) const {
+ struct utimbuf utb;
+ utb.actime = si.modTime.toPosixTime();
+ utb.modtime = utb.actime;
+ if (0 != ::utime(path.c_str(),&utb))
+ return MakeErrMsg(ErrStr, path + ": can't set file modification time");
+ if (0 != ::chmod(path.c_str(),si.mode))
+ return MakeErrMsg(ErrStr, path + ": can't set mode");
+ return false;
+}
+
+bool
+sys::CopyFile(const sys::Path &Dest, const sys::Path &Src, std::string* ErrMsg){
+ int inFile = -1;
+ int outFile = -1;
+ inFile = ::open(Src.c_str(), O_RDONLY);
+ if (inFile == -1)
+ return MakeErrMsg(ErrMsg, Src.str() +
+ ": can't open source file to copy");
+
+ outFile = ::open(Dest.c_str(), O_WRONLY|O_CREAT, 0666);
+ if (outFile == -1) {
+ ::close(inFile);
+ return MakeErrMsg(ErrMsg, Dest.str() +
+ ": can't create destination file for copy");
+ }
+
+ char Buffer[16*1024];
+ while (ssize_t Amt = ::read(inFile, Buffer, 16*1024)) {
+ if (Amt == -1) {
+ if (errno != EINTR && errno != EAGAIN) {
+ ::close(inFile);
+ ::close(outFile);
+ return MakeErrMsg(ErrMsg, Src.str()+": can't read source file");
+ }
+ } else {
+ char *BufPtr = Buffer;
+ while (Amt) {
+ ssize_t AmtWritten = ::write(outFile, BufPtr, Amt);
+ if (AmtWritten == -1) {
+ if (errno != EINTR && errno != EAGAIN) {
+ ::close(inFile);
+ ::close(outFile);
+ return MakeErrMsg(ErrMsg, Dest.str() +
+ ": can't write destination file");
+ }
+ } else {
+ Amt -= AmtWritten;
+ BufPtr += AmtWritten;
+ }
+ }
+ }
+ }
+ ::close(inFile);
+ ::close(outFile);
+ return false;
+}
+
+bool
+Path::makeUnique(bool reuse_current, std::string* ErrMsg) {
+ if (reuse_current && !exists())
+ return false; // File doesn't exist already, just use it!
+
+ // Append an XXXXXX pattern to the end of the file for use with mkstemp,
+ // mktemp or our own implementation.
+ // This uses std::vector instead of SmallVector to avoid a dependence on
+ // libSupport. And performance isn't critical here.
+ std::vector<char> Buf;
+ Buf.resize(path.size()+8);
+ char *FNBuffer = &Buf[0];
+ path.copy(FNBuffer,path.size());
+ if (isDirectory())
+ strcpy(FNBuffer+path.size(), "/XXXXXX");
+ else
+ strcpy(FNBuffer+path.size(), "-XXXXXX");
+
+#if defined(HAVE_MKSTEMP)
+ int TempFD;
+ if ((TempFD = mkstemp(FNBuffer)) == -1)
+ return MakeErrMsg(ErrMsg, path + ": can't make unique filename");
+
+ // We don't need to hold the temp file descriptor... we will trust that no one
+ // will overwrite/delete the file before we can open it again.
+ close(TempFD);
+
+ // Save the name
+ path = FNBuffer;
+#elif defined(HAVE_MKTEMP)
+ // If we don't have mkstemp, use the old and obsolete mktemp function.
+ if (mktemp(FNBuffer) == 0)
+ return MakeErrMsg(ErrMsg, path + ": can't make unique filename");
+
+ // Save the name
+ path = FNBuffer;
+#else
+ // Okay, looks like we have to do it all by our lonesome.
+ static unsigned FCounter = 0;
+ // Try to initialize with unique value.
+ if (FCounter == 0) FCounter = ((unsigned)getpid() & 0xFFFF) << 8;
+ char* pos = strstr(FNBuffer, "XXXXXX");
+ do {
+ if (++FCounter > 0xFFFFFF) {
+ return MakeErrMsg(ErrMsg,
+ path + ": can't make unique filename: too many files");
+ }
+ sprintf(pos, "%06X", FCounter);
+ path = FNBuffer;
+ } while (exists());
+ // POSSIBLE SECURITY BUG: An attacker can easily guess the name and exploit
+ // LLVM.
+#endif
+ return false;
+}
+
+const char *Path::MapInFilePages(int FD, uint64_t FileSize) {
+ int Flags = MAP_PRIVATE;
+#ifdef MAP_FILE
+ Flags |= MAP_FILE;
+#endif
+ void *BasePtr = ::mmap(0, FileSize, PROT_READ, Flags, FD, 0);
+ if (BasePtr == MAP_FAILED)
+ return 0;
+ return (const char*)BasePtr;
+}
+
+void Path::UnMapFilePages(const char *BasePtr, uint64_t FileSize) {
+ ::munmap((void*)BasePtr, FileSize);
+}
+
+} // end llvm namespace
--- /dev/null
+//===- Unix/Process.cpp - Unix Process Implementation --------- -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides the generic Unix implementation of the Process class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Unix.h"
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+// DragonFly BSD has deprecated <malloc.h> for <stdlib.h> instead,
+// Unix.h includes this for us already.
+#if defined(HAVE_MALLOC_H) && !defined(__DragonFly__)
+#include <malloc.h>
+#endif
+#ifdef HAVE_MALLOC_MALLOC_H
+#include <malloc/malloc.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif
+#ifdef HAVE_TERMIOS_H
+# include <termios.h>
+#endif
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic UNIX code that
+//=== is guaranteed to work on *all* UNIX variants.
+//===----------------------------------------------------------------------===//
+
+using namespace llvm;
+using namespace sys;
+
+unsigned
+Process::GetPageSize()
+{
+#if defined(__CYGWIN__)
+ // On Cygwin, getpagesize() returns 64k but the page size for the purposes of
+ // memory protection and mmap() is 4k.
+ // See http://www.cygwin.com/ml/cygwin/2009-01/threads.html#00492
+ const int page_size = 0x1000;
+#elif defined(HAVE_GETPAGESIZE)
+ const int page_size = ::getpagesize();
+#elif defined(HAVE_SYSCONF)
+ long page_size = ::sysconf(_SC_PAGE_SIZE);
+#else
+#warning Cannot get the page size on this machine
+#endif
+ return static_cast<unsigned>(page_size);
+}
+
+size_t Process::GetMallocUsage() {
+#if defined(HAVE_MALLINFO)
+ struct mallinfo mi;
+ mi = ::mallinfo();
+ return mi.uordblks;
+#elif defined(HAVE_MALLOC_ZONE_STATISTICS) && defined(HAVE_MALLOC_MALLOC_H)
+ malloc_statistics_t Stats;
+ malloc_zone_statistics(malloc_default_zone(), &Stats);
+ return Stats.size_in_use; // darwin
+#elif defined(HAVE_SBRK)
+ // Note this is only an approximation and more closely resembles
+ // the value returned by mallinfo in the arena field.
+ static char *StartOfMemory = reinterpret_cast<char*>(::sbrk(0));
+ char *EndOfMemory = (char*)sbrk(0);
+ if (EndOfMemory != ((char*)-1) && StartOfMemory != ((char*)-1))
+ return EndOfMemory - StartOfMemory;
+ else
+ return 0;
+#else
+#warning Cannot get malloc info on this platform
+ return 0;
+#endif
+}
+
+size_t
+Process::GetTotalMemoryUsage()
+{
+#if defined(HAVE_MALLINFO)
+ struct mallinfo mi = ::mallinfo();
+ return mi.uordblks + mi.hblkhd;
+#elif defined(HAVE_MALLOC_ZONE_STATISTICS) && defined(HAVE_MALLOC_MALLOC_H)
+ malloc_statistics_t Stats;
+ malloc_zone_statistics(malloc_default_zone(), &Stats);
+ return Stats.size_allocated; // darwin
+#elif defined(HAVE_GETRUSAGE) && !defined(__HAIKU__)
+ struct rusage usage;
+ ::getrusage(RUSAGE_SELF, &usage);
+ return usage.ru_maxrss;
+#else
+#warning Cannot get total memory size on this platform
+ return 0;
+#endif
+}
+
+void
+Process::GetTimeUsage(TimeValue& elapsed, TimeValue& user_time,
+ TimeValue& sys_time)
+{
+ elapsed = TimeValue::now();
+#if defined(HAVE_GETRUSAGE)
+ struct rusage usage;
+ ::getrusage(RUSAGE_SELF, &usage);
+ user_time = TimeValue(
+ static_cast<TimeValue::SecondsType>( usage.ru_utime.tv_sec ),
+ static_cast<TimeValue::NanoSecondsType>( usage.ru_utime.tv_usec *
+ TimeValue::NANOSECONDS_PER_MICROSECOND ) );
+ sys_time = TimeValue(
+ static_cast<TimeValue::SecondsType>( usage.ru_stime.tv_sec ),
+ static_cast<TimeValue::NanoSecondsType>( usage.ru_stime.tv_usec *
+ TimeValue::NANOSECONDS_PER_MICROSECOND ) );
+#else
+#warning Cannot get usage times on this platform
+ user_time.seconds(0);
+ user_time.microseconds(0);
+ sys_time.seconds(0);
+ sys_time.microseconds(0);
+#endif
+}
+
+int Process::GetCurrentUserId() {
+ return getuid();
+}
+
+int Process::GetCurrentGroupId() {
+ return getgid();
+}
+
+#ifdef HAVE_MACH_MACH_H
+#include <mach/mach.h>
+#endif
+
+// Some LLVM programs such as bugpoint produce core files as a normal part of
+// their operation. To prevent the disk from filling up, this function
+// does what's necessary to prevent their generation.
+void Process::PreventCoreFiles() {
+#if HAVE_SETRLIMIT
+ struct rlimit rlim;
+ rlim.rlim_cur = rlim.rlim_max = 0;
+ setrlimit(RLIMIT_CORE, &rlim);
+#endif
+
+#ifdef HAVE_MACH_MACH_H
+ // Disable crash reporting on Mac OS X 10.0-10.4
+
+ // get information about the original set of exception ports for the task
+ mach_msg_type_number_t Count = 0;
+ exception_mask_t OriginalMasks[EXC_TYPES_COUNT];
+ exception_port_t OriginalPorts[EXC_TYPES_COUNT];
+ exception_behavior_t OriginalBehaviors[EXC_TYPES_COUNT];
+ thread_state_flavor_t OriginalFlavors[EXC_TYPES_COUNT];
+ kern_return_t err =
+ task_get_exception_ports(mach_task_self(), EXC_MASK_ALL, OriginalMasks,
+ &Count, OriginalPorts, OriginalBehaviors,
+ OriginalFlavors);
+ if (err == KERN_SUCCESS) {
+ // replace each with MACH_PORT_NULL.
+ for (unsigned i = 0; i != Count; ++i)
+ task_set_exception_ports(mach_task_self(), OriginalMasks[i],
+ MACH_PORT_NULL, OriginalBehaviors[i],
+ OriginalFlavors[i]);
+ }
+
+ // Disable crash reporting on Mac OS X 10.5
+ signal(SIGABRT, _exit);
+ signal(SIGILL, _exit);
+ signal(SIGFPE, _exit);
+ signal(SIGSEGV, _exit);
+ signal(SIGBUS, _exit);
+#endif
+}
+
+bool Process::StandardInIsUserInput() {
+ return FileDescriptorIsDisplayed(STDIN_FILENO);
+}
+
+bool Process::StandardOutIsDisplayed() {
+ return FileDescriptorIsDisplayed(STDOUT_FILENO);
+}
+
+bool Process::StandardErrIsDisplayed() {
+ return FileDescriptorIsDisplayed(STDERR_FILENO);
+}
+
+bool Process::FileDescriptorIsDisplayed(int fd) {
+#if HAVE_ISATTY
+ return isatty(fd);
+#else
+ // If we don't have isatty, just return false.
+ return false;
+#endif
+}
+
+static unsigned getColumns(int FileID) {
+ // If COLUMNS is defined in the environment, wrap to that many columns.
+ if (const char *ColumnsStr = std::getenv("COLUMNS")) {
+ int Columns = std::atoi(ColumnsStr);
+ if (Columns > 0)
+ return Columns;
+ }
+
+ unsigned Columns = 0;
+
+#if defined(HAVE_SYS_IOCTL_H) && defined(HAVE_TERMIOS_H)
+ // Try to determine the width of the terminal.
+ struct winsize ws;
+ if (ioctl(FileID, TIOCGWINSZ, &ws) == 0)
+ Columns = ws.ws_col;
+#endif
+
+ return Columns;
+}
+
+unsigned Process::StandardOutColumns() {
+ if (!StandardOutIsDisplayed())
+ return 0;
+
+ return getColumns(1);
+}
+
+unsigned Process::StandardErrColumns() {
+ if (!StandardErrIsDisplayed())
+ return 0;
+
+ return getColumns(2);
+}
+
+static bool terminalHasColors() {
+ if (const char *term = std::getenv("TERM")) {
+ // Most modern terminals support ANSI escape sequences for colors.
+ // We could check terminfo, or have a list of known terms that support
+ // colors, but that would be overkill.
+ // The user can always ask for no colors by setting TERM to dumb, or
+ // using a commandline flag.
+ return strcmp(term, "dumb") != 0;
+ }
+ return false;
+}
+
+bool Process::StandardOutHasColors() {
+ if (!StandardOutIsDisplayed())
+ return false;
+ return terminalHasColors();
+}
+
+bool Process::StandardErrHasColors() {
+ if (!StandardErrIsDisplayed())
+ return false;
+ return terminalHasColors();
+}
+
+bool Process::ColorNeedsFlush() {
+ // No, we use ANSI escape sequences.
+ return false;
+}
+
+#define COLOR(FGBG, CODE, BOLD) "\033[0;" BOLD FGBG CODE "m"
+
+#define ALLCOLORS(FGBG,BOLD) {\
+ COLOR(FGBG, "0", BOLD),\
+ COLOR(FGBG, "1", BOLD),\
+ COLOR(FGBG, "2", BOLD),\
+ COLOR(FGBG, "3", BOLD),\
+ COLOR(FGBG, "4", BOLD),\
+ COLOR(FGBG, "5", BOLD),\
+ COLOR(FGBG, "6", BOLD),\
+ COLOR(FGBG, "7", BOLD)\
+ }
+
+static const char colorcodes[2][2][8][10] = {
+ { ALLCOLORS("3",""), ALLCOLORS("3","1;") },
+ { ALLCOLORS("4",""), ALLCOLORS("4","1;") }
+};
+
+const char *Process::OutputColor(char code, bool bold, bool bg) {
+ return colorcodes[bg?1:0][bold?1:0][code&7];
+}
+
+const char *Process::OutputBold(bool bg) {
+ return "\033[1m";
+}
+
+const char *Process::ResetColor() {
+ return "\033[0m";
+}
--- /dev/null
+//===- llvm/System/Unix/Program.cpp -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Unix specific portion of the Program class.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic UNIX code that
+//=== is guaranteed to work on *all* UNIX variants.
+//===----------------------------------------------------------------------===//
+
+#include <llvm/Config/config.h>
+#include "Unix.h"
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+#if HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+#if HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_POSIX_SPAWN
+#include <spawn.h>
+#if !defined(__APPLE__)
+ extern char **environ;
+#else
+#include <crt_externs.h> // _NSGetEnviron
+#endif
+#endif
+
+namespace llvm {
+using namespace sys;
+
+Program::Program() : Data_(0) {}
+
+Program::~Program() {}
+
+unsigned Program::GetPid() const {
+ uint64_t pid = reinterpret_cast<uint64_t>(Data_);
+ return static_cast<unsigned>(pid);
+}
+
+// This function just uses the PATH environment variable to find the program.
+Path
+Program::FindProgramByName(const std::string& progName) {
+
+ // Check some degenerate cases
+ if (progName.length() == 0) // no program
+ return Path();
+ Path temp;
+ if (!temp.set(progName)) // invalid name
+ return Path();
+ // Use the given path verbatim if it contains any slashes; this matches
+ // the behavior of sh(1) and friends.
+ if (progName.find('/') != std::string::npos)
+ return temp;
+
+ // At this point, the file name is valid and does not contain slashes. Search
+ // for it through the directories specified in the PATH environment variable.
+
+ // Get the path. If its empty, we can't do anything to find it.
+ const char *PathStr = getenv("PATH");
+ if (PathStr == 0)
+ return Path();
+
+ // Now we have a colon separated list of directories to search; try them.
+ size_t PathLen = strlen(PathStr);
+ while (PathLen) {
+ // Find the first colon...
+ const char *Colon = std::find(PathStr, PathStr+PathLen, ':');
+
+ // Check to see if this first directory contains the executable...
+ Path FilePath;
+ if (FilePath.set(std::string(PathStr,Colon))) {
+ FilePath.appendComponent(progName);
+ if (FilePath.canExecute())
+ return FilePath; // Found the executable!
+ }
+
+ // Nope it wasn't in this directory, check the next path in the list!
+ PathLen -= Colon-PathStr;
+ PathStr = Colon;
+
+ // Advance past duplicate colons
+ while (*PathStr == ':') {
+ PathStr++;
+ PathLen--;
+ }
+ }
+ return Path();
+}
+
+static bool RedirectIO(const Path *Path, int FD, std::string* ErrMsg) {
+ if (Path == 0) // Noop
+ return false;
+ const char *File;
+ if (Path->isEmpty())
+ // Redirect empty paths to /dev/null
+ File = "/dev/null";
+ else
+ File = Path->c_str();
+
+ // Open the file
+ int InFD = open(File, FD == 0 ? O_RDONLY : O_WRONLY|O_CREAT, 0666);
+ if (InFD == -1) {
+ MakeErrMsg(ErrMsg, "Cannot open file '" + std::string(File) + "' for "
+ + (FD == 0 ? "input" : "output"));
+ return true;
+ }
+
+ // Install it as the requested FD
+ if (dup2(InFD, FD) == -1) {
+ MakeErrMsg(ErrMsg, "Cannot dup2");
+ close(InFD);
+ return true;
+ }
+ close(InFD); // Close the original FD
+ return false;
+}
+
+#ifdef HAVE_POSIX_SPAWN
+static bool RedirectIO_PS(const Path *Path, int FD, std::string *ErrMsg,
+ posix_spawn_file_actions_t &FileActions) {
+ if (Path == 0) // Noop
+ return false;
+ const char *File;
+ if (Path->isEmpty())
+ // Redirect empty paths to /dev/null
+ File = "/dev/null";
+ else
+ File = Path->c_str();
+
+ if (int Err = posix_spawn_file_actions_addopen(&FileActions, FD,
+ File, FD == 0 ? O_RDONLY : O_WRONLY|O_CREAT, 0666))
+ return MakeErrMsg(ErrMsg, "Cannot dup2", Err);
+ return false;
+}
+#endif
+
+static void TimeOutHandler(int Sig) {
+}
+
+static void SetMemoryLimits (unsigned size)
+{
+#if HAVE_SYS_RESOURCE_H && HAVE_GETRLIMIT && HAVE_SETRLIMIT
+ struct rlimit r;
+ __typeof__ (r.rlim_cur) limit = (__typeof__ (r.rlim_cur)) (size) * 1048576;
+
+ // Heap size
+ getrlimit (RLIMIT_DATA, &r);
+ r.rlim_cur = limit;
+ setrlimit (RLIMIT_DATA, &r);
+#ifdef RLIMIT_RSS
+ // Resident set size.
+ getrlimit (RLIMIT_RSS, &r);
+ r.rlim_cur = limit;
+ setrlimit (RLIMIT_RSS, &r);
+#endif
+#ifdef RLIMIT_AS // e.g. NetBSD doesn't have it.
+ // Virtual memory.
+ getrlimit (RLIMIT_AS, &r);
+ r.rlim_cur = limit;
+ setrlimit (RLIMIT_AS, &r);
+#endif
+#endif
+}
+
+bool
+Program::Execute(const Path &path, const char **args, const char **envp,
+ const Path **redirects, unsigned memoryLimit,
+ std::string *ErrMsg) {
+ // If this OS has posix_spawn and there is no memory limit being implied, use
+ // posix_spawn. It is more efficient than fork/exec.
+#ifdef HAVE_POSIX_SPAWN
+ if (memoryLimit == 0) {
+ posix_spawn_file_actions_t FileActions;
+ posix_spawn_file_actions_init(&FileActions);
+
+ if (redirects) {
+ // Redirect stdin/stdout.
+ if (RedirectIO_PS(redirects[0], 0, ErrMsg, FileActions) ||
+ RedirectIO_PS(redirects[1], 1, ErrMsg, FileActions))
+ return false;
+ if (redirects[1] == 0 || redirects[2] == 0 ||
+ *redirects[1] != *redirects[2]) {
+ // Just redirect stderr
+ if (RedirectIO_PS(redirects[2], 2, ErrMsg, FileActions)) return false;
+ } else {
+ // If stdout and stderr should go to the same place, redirect stderr
+ // to the FD already open for stdout.
+ if (int Err = posix_spawn_file_actions_adddup2(&FileActions, 1, 2))
+ return !MakeErrMsg(ErrMsg, "Can't redirect stderr to stdout", Err);
+ }
+ }
+
+ if (!envp)
+#if !defined(__APPLE__)
+ envp = const_cast<const char **>(environ);
+#else
+ // environ is missing in dylibs.
+ envp = const_cast<const char **>(*_NSGetEnviron());
+#endif
+
+ // Explicitly initialized to prevent what appears to be a valgrind false
+ // positive.
+ pid_t PID = 0;
+ int Err = posix_spawn(&PID, path.c_str(), &FileActions, /*attrp*/0,
+ const_cast<char **>(args), const_cast<char **>(envp));
+
+ posix_spawn_file_actions_destroy(&FileActions);
+
+ if (Err)
+ return !MakeErrMsg(ErrMsg, "posix_spawn failed", Err);
+
+ Data_ = reinterpret_cast<void*>(PID);
+ return true;
+ }
+#endif
+
+ // Create a child process.
+ int child = fork();
+ switch (child) {
+ // An error occured: Return to the caller.
+ case -1:
+ MakeErrMsg(ErrMsg, "Couldn't fork");
+ return false;
+
+ // Child process: Execute the program.
+ case 0: {
+ // Redirect file descriptors...
+ if (redirects) {
+ // Redirect stdin
+ if (RedirectIO(redirects[0], 0, ErrMsg)) { return false; }
+ // Redirect stdout
+ if (RedirectIO(redirects[1], 1, ErrMsg)) { return false; }
+ if (redirects[1] && redirects[2] &&
+ *(redirects[1]) == *(redirects[2])) {
+ // If stdout and stderr should go to the same place, redirect stderr
+ // to the FD already open for stdout.
+ if (-1 == dup2(1,2)) {
+ MakeErrMsg(ErrMsg, "Can't redirect stderr to stdout");
+ return false;
+ }
+ } else {
+ // Just redirect stderr
+ if (RedirectIO(redirects[2], 2, ErrMsg)) { return false; }
+ }
+ }
+
+ // Set memory limits
+ if (memoryLimit!=0) {
+ SetMemoryLimits(memoryLimit);
+ }
+
+ // Execute!
+ if (envp != 0)
+ execve(path.c_str(),
+ const_cast<char **>(args),
+ const_cast<char **>(envp));
+ else
+ execv(path.c_str(),
+ const_cast<char **>(args));
+ // If the execve() failed, we should exit. Follow Unix protocol and
+ // return 127 if the executable was not found, and 126 otherwise.
+ // Use _exit rather than exit so that atexit functions and static
+ // object destructors cloned from the parent process aren't
+ // redundantly run, and so that any data buffered in stdio buffers
+ // cloned from the parent aren't redundantly written out.
+ _exit(errno == ENOENT ? 127 : 126);
+ }
+
+ // Parent process: Break out of the switch to do our processing.
+ default:
+ break;
+ }
+
+ Data_ = reinterpret_cast<void*>(child);
+
+ return true;
+}
+
+int
+Program::Wait(const sys::Path &path,
+ unsigned secondsToWait,
+ std::string* ErrMsg)
+{
+#ifdef HAVE_SYS_WAIT_H
+ struct sigaction Act, Old;
+
+ if (Data_ == 0) {
+ MakeErrMsg(ErrMsg, "Process not started!");
+ return -1;
+ }
+
+ // Install a timeout handler. The handler itself does nothing, but the simple
+ // fact of having a handler at all causes the wait below to return with EINTR,
+ // unlike if we used SIG_IGN.
+ if (secondsToWait) {
+ memset(&Act, 0, sizeof(Act));
+ Act.sa_handler = TimeOutHandler;
+ sigemptyset(&Act.sa_mask);
+ sigaction(SIGALRM, &Act, &Old);
+ alarm(secondsToWait);
+ }
+
+ // Parent process: Wait for the child process to terminate.
+ int status;
+ uint64_t pid = reinterpret_cast<uint64_t>(Data_);
+ pid_t child = static_cast<pid_t>(pid);
+ while (waitpid(pid, &status, 0) != child)
+ if (secondsToWait && errno == EINTR) {
+ // Kill the child.
+ kill(child, SIGKILL);
+
+ // Turn off the alarm and restore the signal handler
+ alarm(0);
+ sigaction(SIGALRM, &Old, 0);
+
+ // Wait for child to die
+ if (wait(&status) != child)
+ MakeErrMsg(ErrMsg, "Child timed out but wouldn't die");
+ else
+ MakeErrMsg(ErrMsg, "Child timed out", 0);
+
+ return -1; // Timeout detected
+ } else if (errno != EINTR) {
+ MakeErrMsg(ErrMsg, "Error waiting for child process");
+ return -1;
+ }
+
+ // We exited normally without timeout, so turn off the timer.
+ if (secondsToWait) {
+ alarm(0);
+ sigaction(SIGALRM, &Old, 0);
+ }
+
+ // Return the proper exit status. Detect error conditions
+ // so we can return -1 for them and set ErrMsg informatively.
+ int result = 0;
+ if (WIFEXITED(status)) {
+ result = WEXITSTATUS(status);
+#ifdef HAVE_POSIX_SPAWN
+ // The posix_spawn child process returns 127 on any kind of error.
+ // Following the POSIX convention for command-line tools (which posix_spawn
+ // itself apparently does not), check to see if the failure was due to some
+ // reason other than the file not existing, and return 126 in this case.
+ if (result == 127 && path.exists())
+ result = 126;
+#endif
+ if (result == 127) {
+ if (ErrMsg)
+ *ErrMsg = llvm::sys::StrError(ENOENT);
+ return -1;
+ }
+ if (result == 126) {
+ if (ErrMsg)
+ *ErrMsg = "Program could not be executed";
+ return -1;
+ }
+ } else if (WIFSIGNALED(status)) {
+ if (ErrMsg) {
+ *ErrMsg = strsignal(WTERMSIG(status));
+#ifdef WCOREDUMP
+ if (WCOREDUMP(status))
+ *ErrMsg += " (core dumped)";
+#endif
+ }
+ return -1;
+ }
+ return result;
+#else
+ if (ErrMsg)
+ *ErrMsg = "Program::Wait is not implemented on this platform yet!";
+ return -1;
+#endif
+}
+
+bool
+Program::Kill(std::string* ErrMsg) {
+ if (Data_ == 0) {
+ MakeErrMsg(ErrMsg, "Process not started!");
+ return true;
+ }
+
+ uint64_t pid64 = reinterpret_cast<uint64_t>(Data_);
+ pid_t pid = static_cast<pid_t>(pid64);
+
+ if (kill(pid, SIGKILL) != 0) {
+ MakeErrMsg(ErrMsg, "The process couldn't be killed!");
+ return true;
+ }
+
+ return false;
+}
+
+bool Program::ChangeStdinToBinary(){
+ // Do nothing, as Unix doesn't differentiate between text and binary.
+ return false;
+}
+
+bool Program::ChangeStdoutToBinary(){
+ // Do nothing, as Unix doesn't differentiate between text and binary.
+ return false;
+}
+
+bool Program::ChangeStderrToBinary(){
+ // Do nothing, as Unix doesn't differentiate between text and binary.
+ return false;
+}
+
+}
--- /dev/null
+llvm/lib/Support/Unix README
+===========================
+
+This directory provides implementations of the lib/System classes that
+are common to two or more variants of UNIX. For example, the directory
+structure underneath this directory could look like this:
+
+Unix - only code that is truly generic to all UNIX platforms
+ Posix - code that is specific to Posix variants of UNIX
+ SUS - code that is specific to the Single Unix Specification
+ SysV - code that is specific to System V variants of UNIX
+
+As a rule, only those directories actually needing to be created should be
+created. Also, further subdirectories could be created to reflect versions of
+the various standards. For example, under SUS there could be v1, v2, and v3
+subdirectories to reflect the three major versions of SUS.
--- /dev/null
+//= llvm/System/Unix/RWMutex.inc - Unix Reader/Writer Mutual Exclusion Lock =//
+//
+// 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 Unix specific (non-pthread) RWMutex class.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic UNIX code that
+//=== is guaranteed to work on *all* UNIX variants.
+//===----------------------------------------------------------------------===//
+
+namespace llvm {
+
+using namespace sys;
+
+RWMutexImpl::RWMutexImpl() { }
+
+RWMutexImpl::~RWMutexImpl() { }
+
+bool RWMutexImpl::reader_acquire() {
+ return true;
+}
+
+bool RWMutexImpl::reader_release() {
+ return true;
+}
+
+bool RWMutexImpl::writer_acquire() {
+ return true;
+}
+
+bool RWMutexImpl::writer_release() {
+ return true;
+}
+
+}
--- /dev/null
+//===- Signals.cpp - Generic Unix Signals Implementation -----*- 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 some helpful functions for dealing with the possibility of
+// Unix signals occuring while your program is running.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Unix.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/Mutex.h"
+#include <vector>
+#include <algorithm>
+#if HAVE_EXECINFO_H
+# include <execinfo.h> // For backtrace().
+#endif
+#if HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_DLFCN_H && __GNUG__
+#include <dlfcn.h>
+#include <cxxabi.h>
+#endif
+using namespace llvm;
+
+static RETSIGTYPE SignalHandler(int Sig); // defined below.
+
+static SmartMutex<true> SignalsMutex;
+
+/// InterruptFunction - The function to call if ctrl-c is pressed.
+static void (*InterruptFunction)() = 0;
+
+static std::vector<sys::Path> FilesToRemove;
+static std::vector<std::pair<void(*)(void*), void*> > CallBacksToRun;
+
+// IntSigs - Signals that may interrupt the program at any time.
+static const int IntSigs[] = {
+ SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGTERM, SIGUSR1, SIGUSR2
+};
+static const int *const IntSigsEnd =
+ IntSigs + sizeof(IntSigs) / sizeof(IntSigs[0]);
+
+// KillSigs - Signals that are synchronous with the program that will cause it
+// to die.
+static const int KillSigs[] = {
+ SIGILL, SIGTRAP, SIGABRT, SIGFPE, SIGBUS, SIGSEGV
+#ifdef SIGSYS
+ , SIGSYS
+#endif
+#ifdef SIGXCPU
+ , SIGXCPU
+#endif
+#ifdef SIGXFSZ
+ , SIGXFSZ
+#endif
+#ifdef SIGEMT
+ , SIGEMT
+#endif
+};
+static const int *const KillSigsEnd =
+ KillSigs + sizeof(KillSigs) / sizeof(KillSigs[0]);
+
+static unsigned NumRegisteredSignals = 0;
+static struct {
+ struct sigaction SA;
+ int SigNo;
+} RegisteredSignalInfo[(sizeof(IntSigs)+sizeof(KillSigs))/sizeof(KillSigs[0])];
+
+
+static void RegisterHandler(int Signal) {
+ assert(NumRegisteredSignals <
+ sizeof(RegisteredSignalInfo)/sizeof(RegisteredSignalInfo[0]) &&
+ "Out of space for signal handlers!");
+
+ struct sigaction NewHandler;
+
+ NewHandler.sa_handler = SignalHandler;
+ NewHandler.sa_flags = SA_NODEFER|SA_RESETHAND;
+ sigemptyset(&NewHandler.sa_mask);
+
+ // Install the new handler, save the old one in RegisteredSignalInfo.
+ sigaction(Signal, &NewHandler,
+ &RegisteredSignalInfo[NumRegisteredSignals].SA);
+ RegisteredSignalInfo[NumRegisteredSignals].SigNo = Signal;
+ ++NumRegisteredSignals;
+}
+
+static void RegisterHandlers() {
+ // If the handlers are already registered, we're done.
+ if (NumRegisteredSignals != 0) return;
+
+ std::for_each(IntSigs, IntSigsEnd, RegisterHandler);
+ std::for_each(KillSigs, KillSigsEnd, RegisterHandler);
+}
+
+static void UnregisterHandlers() {
+ // Restore all of the signal handlers to how they were before we showed up.
+ for (unsigned i = 0, e = NumRegisteredSignals; i != e; ++i)
+ sigaction(RegisteredSignalInfo[i].SigNo,
+ &RegisteredSignalInfo[i].SA, 0);
+ NumRegisteredSignals = 0;
+}
+
+
+/// RemoveFilesToRemove - Process the FilesToRemove list. This function
+/// should be called with the SignalsMutex lock held.
+static void RemoveFilesToRemove() {
+ while (!FilesToRemove.empty()) {
+ FilesToRemove.back().eraseFromDisk(true);
+ FilesToRemove.pop_back();
+ }
+}
+
+// SignalHandler - The signal handler that runs.
+static RETSIGTYPE SignalHandler(int Sig) {
+ // Restore the signal behavior to default, so that the program actually
+ // crashes when we return and the signal reissues. This also ensures that if
+ // we crash in our signal handler that the program will terminate immediately
+ // instead of recursing in the signal handler.
+ UnregisterHandlers();
+
+ // Unmask all potentially blocked kill signals.
+ sigset_t SigMask;
+ sigfillset(&SigMask);
+ sigprocmask(SIG_UNBLOCK, &SigMask, 0);
+
+ SignalsMutex.acquire();
+ RemoveFilesToRemove();
+
+ if (std::find(IntSigs, IntSigsEnd, Sig) != IntSigsEnd) {
+ if (InterruptFunction) {
+ void (*IF)() = InterruptFunction;
+ SignalsMutex.release();
+ InterruptFunction = 0;
+ IF(); // run the interrupt function.
+ return;
+ }
+
+ SignalsMutex.release();
+ raise(Sig); // Execute the default handler.
+ return;
+ }
+
+ SignalsMutex.release();
+
+ // Otherwise if it is a fault (like SEGV) run any handler.
+ for (unsigned i = 0, e = CallBacksToRun.size(); i != e; ++i)
+ CallBacksToRun[i].first(CallBacksToRun[i].second);
+}
+
+void llvm::sys::RunInterruptHandlers() {
+ SignalsMutex.acquire();
+ RemoveFilesToRemove();
+ SignalsMutex.release();
+}
+
+void llvm::sys::SetInterruptFunction(void (*IF)()) {
+ SignalsMutex.acquire();
+ InterruptFunction = IF;
+ SignalsMutex.release();
+ RegisterHandlers();
+}
+
+// RemoveFileOnSignal - The public API
+bool llvm::sys::RemoveFileOnSignal(const sys::Path &Filename,
+ std::string* ErrMsg) {
+ SignalsMutex.acquire();
+ FilesToRemove.push_back(Filename);
+
+ SignalsMutex.release();
+
+ RegisterHandlers();
+ return false;
+}
+
+// DontRemoveFileOnSignal - The public API
+void llvm::sys::DontRemoveFileOnSignal(const sys::Path &Filename) {
+ SignalsMutex.acquire();
+ std::vector<sys::Path>::reverse_iterator I =
+ std::find(FilesToRemove.rbegin(), FilesToRemove.rend(), Filename);
+ if (I != FilesToRemove.rend())
+ FilesToRemove.erase(I.base()-1);
+ SignalsMutex.release();
+}
+
+/// AddSignalHandler - Add a function to be called when a signal is delivered
+/// to the process. The handler can have a cookie passed to it to identify
+/// what instance of the handler it is.
+void llvm::sys::AddSignalHandler(void (*FnPtr)(void *), void *Cookie) {
+ CallBacksToRun.push_back(std::make_pair(FnPtr, Cookie));
+ RegisterHandlers();
+}
+
+
+// PrintStackTrace - In the case of a program crash or fault, print out a stack
+// trace so that the user has an indication of why and where we died.
+//
+// On glibc systems we have the 'backtrace' function, which works nicely, but
+// doesn't demangle symbols.
+static void PrintStackTrace(void *) {
+#ifdef HAVE_BACKTRACE
+ static void* StackTrace[256];
+ // Use backtrace() to output a backtrace on Linux systems with glibc.
+ int depth = backtrace(StackTrace,
+ static_cast<int>(array_lengthof(StackTrace)));
+#if HAVE_DLFCN_H && __GNUG__
+ int width = 0;
+ for (int i = 0; i < depth; ++i) {
+ Dl_info dlinfo;
+ dladdr(StackTrace[i], &dlinfo);
+ const char* name = strrchr(dlinfo.dli_fname, '/');
+
+ int nwidth;
+ if (name == NULL) nwidth = strlen(dlinfo.dli_fname);
+ else nwidth = strlen(name) - 1;
+
+ if (nwidth > width) width = nwidth;
+ }
+
+ for (int i = 0; i < depth; ++i) {
+ Dl_info dlinfo;
+ dladdr(StackTrace[i], &dlinfo);
+
+ fprintf(stderr, "%-2d", i);
+
+ const char* name = strrchr(dlinfo.dli_fname, '/');
+ if (name == NULL) fprintf(stderr, " %-*s", width, dlinfo.dli_fname);
+ else fprintf(stderr, " %-*s", width, name+1);
+
+ fprintf(stderr, " %#0*lx",
+ (int)(sizeof(void*) * 2) + 2, (unsigned long)StackTrace[i]);
+
+ if (dlinfo.dli_sname != NULL) {
+ int res;
+ fputc(' ', stderr);
+ char* d = abi::__cxa_demangle(dlinfo.dli_sname, NULL, NULL, &res);
+ if (d == NULL) fputs(dlinfo.dli_sname, stderr);
+ else fputs(d, stderr);
+ free(d);
+
+ fprintf(stderr, " + %tu",(char*)StackTrace[i]-(char*)dlinfo.dli_saddr);
+ }
+ fputc('\n', stderr);
+ }
+#else
+ backtrace_symbols_fd(StackTrace, depth, STDERR_FILENO);
+#endif
+#endif
+}
+
+/// PrintStackTraceOnErrorSignal - When an error signal (such as SIBABRT or
+/// SIGSEGV) is delivered to the process, print a stack trace and then exit.
+void llvm::sys::PrintStackTraceOnErrorSignal() {
+ AddSignalHandler(PrintStackTrace, 0);
+}
+
+
+/***/
+
+// On Darwin, raise sends a signal to the main thread instead of the current
+// thread. This has the unfortunate effect that assert() and abort() will end up
+// bypassing our crash recovery attempts. We work around this for anything in
+// the same linkage unit by just defining our own versions of the assert handler
+// and abort.
+
+#ifdef __APPLE__
+
+int raise(int sig) {
+ return pthread_kill(pthread_self(), sig);
+}
+
+void __assert_rtn(const char *func,
+ const char *file,
+ int line,
+ const char *expr) {
+ if (func)
+ fprintf(stderr, "Assertion failed: (%s), function %s, file %s, line %d.\n",
+ expr, func, file, line);
+ else
+ fprintf(stderr, "Assertion failed: (%s), file %s, line %d.\n",
+ expr, file, line);
+ abort();
+}
+
+#include <signal.h>
+#include <pthread.h>
+
+void abort() {
+ raise(SIGABRT);
+ usleep(1000);
+ __builtin_trap();
+}
+
+#endif
--- /dev/null
+//=== llvm/System/Unix/ThreadLocal.inc - Unix Thread Local Data -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Unix specific (non-pthread) ThreadLocal class.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic UNIX code that
+//=== is guaranteed to work on *all* UNIX variants.
+//===----------------------------------------------------------------------===//
+
+namespace llvm {
+using namespace sys;
+ThreadLocalImpl::ThreadLocalImpl() { }
+ThreadLocalImpl::~ThreadLocalImpl() { }
+void ThreadLocalImpl::setInstance(const void* d) { data = const_cast<void*>(d);}
+const void* ThreadLocalImpl::getInstance() { return data; }
+void ThreadLocalImpl::removeInstance() { setInstance(0); }
+}
--- /dev/null
+//===- Unix/TimeValue.cpp - Unix TimeValue Implementation -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Unix specific portion of the TimeValue class.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic UNIX code that
+//=== is guaranteed to work on *all* UNIX variants.
+//===----------------------------------------------------------------------===//
+
+#include "Unix.h"
+
+namespace llvm {
+ using namespace sys;
+
+std::string TimeValue::str() const {
+ char buffer[32];
+
+ time_t ourTime = time_t(this->toEpochTime());
+#ifdef __hpux
+// note that the following line needs -D_REENTRANT on HP-UX to be picked up
+ asctime_r(localtime(&ourTime), buffer);
+#else
+ ::asctime_r(::localtime(&ourTime), buffer);
+#endif
+
+ std::string result(buffer);
+ return result.substr(0,24);
+}
+
+TimeValue TimeValue::now() {
+ struct timeval the_time;
+ timerclear(&the_time);
+ if (0 != ::gettimeofday(&the_time,0)) {
+ // This is *really* unlikely to occur because the only gettimeofday
+ // errors concern the timezone parameter which we're passing in as 0.
+ // In the unlikely case it does happen, just return MinTime, no error
+ // message needed.
+ return MinTime;
+ }
+
+ return TimeValue(
+ static_cast<TimeValue::SecondsType>( the_time.tv_sec + PosixZeroTime.seconds_ ),
+ static_cast<TimeValue::NanoSecondsType>( the_time.tv_usec *
+ NANOSECONDS_PER_MICROSECOND ) );
+}
+
+}
--- /dev/null
+//===- llvm/System/Unix/Unix.h - Common Unix Include File -------*- 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 things specific to Unix implementations.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_UNIX_UNIX_H
+#define LLVM_SYSTEM_UNIX_UNIX_H
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic UNIX code that
+//=== is guaranteed to work on all UNIX variants.
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Config/config.h" // Get autoconf configuration settings
+#include "llvm/System/Errno.h"
+#include <cstdlib>
+#include <cstdio>
+#include <cstring>
+#include <cerrno>
+#include <string>
+#include <algorithm>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#ifdef HAVE_ASSERT_H
+#include <assert.h>
+#endif
+
+#ifdef TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+
+#ifdef HAVE_SYS_WAIT_H
+# include <sys/wait.h>
+#endif
+
+#ifndef WEXITSTATUS
+# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
+#endif
+
+#ifndef WIFEXITED
+# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
+#endif
+
+/// This function builds an error message into \p ErrMsg using the \p prefix
+/// string and the Unix error number given by \p errnum. If errnum is -1, the
+/// default then the value of errno is used.
+/// @brief Make an error message
+///
+/// If the error number can be converted to a string, it will be
+/// separated from prefix by ": ".
+static inline bool MakeErrMsg(
+ std::string* ErrMsg, const std::string& prefix, int errnum = -1) {
+ if (!ErrMsg)
+ return true;
+ if (errnum == -1)
+ errnum = errno;
+ *ErrMsg = prefix + ": " + llvm::sys::StrError(errnum);
+ return true;
+}
+
+#endif
--- /dev/null
+//===- llvm/System/Unix/system_error.inc - Unix error_code ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides the Unix specific implementation of the error_code
+// and error_condition classes.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic UNIX code that
+//=== is guaranteed to work on *all* UNIX variants.
+//===----------------------------------------------------------------------===//
+
+using namespace llvm;
+
+std::string
+_system_error_category::message(int ev) const {
+ return _do_message::message(ev);
+}
+
+error_condition
+_system_error_category::default_error_condition(int ev) const {
+#ifdef ELAST
+ if (ev > ELAST)
+ return error_condition(ev, system_category());
+#endif // ELAST
+ return error_condition(ev, generic_category());
+}
--- /dev/null
+//===-- Valgrind.cpp - Implement Valgrind communication ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines Valgrind communication methods, if HAVE_VALGRIND_VALGRIND_H is
+// defined. If we have valgrind.h but valgrind isn't running, its macros are
+// no-ops.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Valgrind.h"
+#include "llvm/Config/config.h"
+
+#if HAVE_VALGRIND_VALGRIND_H
+#include <valgrind/valgrind.h>
+
+static bool InitNotUnderValgrind() {
+ return !RUNNING_ON_VALGRIND;
+}
+
+// This bool is negated from what we'd expect because code may run before it
+// gets initialized. If that happens, it will appear to be 0 (false), and we
+// want that to cause the rest of the code in this file to run the
+// Valgrind-provided macros.
+static const bool NotUnderValgrind = InitNotUnderValgrind();
+
+bool llvm::sys::RunningOnValgrind() {
+ if (NotUnderValgrind)
+ return false;
+ return RUNNING_ON_VALGRIND;
+}
+
+void llvm::sys::ValgrindDiscardTranslations(const void *Addr, size_t Len) {
+ if (NotUnderValgrind)
+ return;
+
+ VALGRIND_DISCARD_TRANSLATIONS(Addr, Len);
+}
+
+#else // !HAVE_VALGRIND_VALGRIND_H
+
+bool llvm::sys::RunningOnValgrind() {
+ return false;
+}
+
+void llvm::sys::ValgrindDiscardTranslations(const void *Addr, size_t Len) {
+}
+
+#endif // !HAVE_VALGRIND_VALGRIND_H
--- /dev/null
+//===-- Alarm.inc - Implement Win32 Alarm Support ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Win32 Alarm support.
+//
+//===----------------------------------------------------------------------===//
+
+#include <cassert>
+using namespace llvm;
+
+/// NestedSOI - Sanity check. Alarms cannot be nested or run in parallel.
+/// This ensures that they never do.
+static bool NestedSOI = false;
+
+void sys::SetupAlarm(unsigned seconds) {
+ assert(!NestedSOI && "sys::SetupAlarm calls cannot be nested!");
+ NestedSOI = true;
+ // FIXME: Implement for Win32
+}
+
+void sys::TerminateAlarm() {
+ assert(NestedSOI && "sys::TerminateAlarm called without sys::SetupAlarm!");
+ // FIXME: Implement for Win32
+ NestedSOI = false;
+}
+
+int sys::AlarmStatus() {
+ // FIXME: Implement for Win32
+ return 0;
+}
+
+// Don't pull in all of the Windows headers.
+extern "C" void __stdcall Sleep(unsigned long);
+
+void sys::Sleep(unsigned n) {
+ ::Sleep(n*1000);
+}
--- /dev/null
+//===- Win32/DynamicLibrary.cpp - Win32 DL Implementation -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides the Win32 specific implementation of DynamicLibrary.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Windows.h"
+
+#ifdef __MINGW32__
+ #include <imagehlp.h>
+#else
+ #include <dbghelp.h>
+#endif
+
+#ifdef _MSC_VER
+ #include <ntverp.h>
+#endif
+
+#ifdef __MINGW32__
+ #if (HAVE_LIBIMAGEHLP != 1)
+ #error "libimagehlp.a should be present"
+ #endif
+#else
+ #pragma comment(lib, "dbghelp.lib")
+#endif
+
+namespace llvm {
+using namespace sys;
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only Win32 specific code
+//=== and must not be UNIX code.
+//===----------------------------------------------------------------------===//
+
+static std::vector<HMODULE> OpenedHandles;
+
+#ifdef _WIN64
+ typedef DWORD64 ModuleBaseType;
+#else
+ typedef ULONG ModuleBaseType;
+#endif
+
+extern "C" {
+// Use old callback if:
+// - Not using Visual Studio
+// - Visual Studio 2005 or earlier but only if we are not using the Windows SDK
+// or Windows SDK version is older than 6.0
+// Use new callback if:
+// - Newer Visual Studio (comes with newer SDK).
+// - Visual Studio 2005 with Windows SDK 6.0+
+#if !defined(_MSC_VER) || _MSC_VER < 1500 && (!defined(VER_PRODUCTBUILD) || VER_PRODUCTBUILD < 6000)
+ static BOOL CALLBACK ELM_Callback(PSTR ModuleName,
+ ModuleBaseType ModuleBase,
+ ULONG ModuleSize,
+ PVOID UserContext)
+#else
+ static BOOL CALLBACK ELM_Callback(PCSTR ModuleName,
+ ModuleBaseType ModuleBase,
+ ULONG ModuleSize,
+ PVOID UserContext)
+#endif
+ {
+ // Ignore VC++ runtimes prior to 7.1. Somehow some of them get loaded
+ // into the process.
+ if (stricmp(ModuleName, "msvci70") != 0 &&
+ stricmp(ModuleName, "msvcirt") != 0 &&
+ stricmp(ModuleName, "msvcp50") != 0 &&
+ stricmp(ModuleName, "msvcp60") != 0 &&
+ stricmp(ModuleName, "msvcp70") != 0 &&
+ stricmp(ModuleName, "msvcr70") != 0 &&
+#ifndef __MINGW32__
+ // Mingw32 uses msvcrt.dll by default. Don't ignore it.
+ // Otherwise, user should be aware, what he's doing :)
+ stricmp(ModuleName, "msvcrt") != 0 &&
+#endif
+ stricmp(ModuleName, "msvcrt20") != 0 &&
+ stricmp(ModuleName, "msvcrt40") != 0) {
+ OpenedHandles.push_back((HMODULE)ModuleBase);
+ }
+ return TRUE;
+ }
+}
+
+bool DynamicLibrary::LoadLibraryPermanently(const char *filename,
+ std::string *ErrMsg) {
+ if (filename) {
+ HMODULE a_handle = LoadLibrary(filename);
+
+ if (a_handle == 0)
+ return MakeErrMsg(ErrMsg, std::string(filename) + ": Can't open : ");
+
+ OpenedHandles.push_back(a_handle);
+ } else {
+ // When no file is specified, enumerate all DLLs and EXEs in the
+ // process.
+ EnumerateLoadedModules(GetCurrentProcess(), ELM_Callback, 0);
+ }
+
+ // Because we don't remember the handle, we will never free it; hence,
+ // it is loaded permanently.
+ return false;
+}
+
+// Stack probing routines are in the support library (e.g. libgcc), but we don't
+// have dynamic linking on windows. Provide a hook.
+#if defined(__MINGW32__) || defined (_MSC_VER)
+ #define EXPLICIT_SYMBOL(SYM) \
+ if (!strcmp(symbolName, #SYM)) return (void*)&SYM
+ #define EXPLICIT_SYMBOL2(SYMFROM, SYMTO) \
+ if (!strcmp(symbolName, #SYMFROM)) return (void*)&SYMTO
+ #define EXPLICIT_SYMBOL_DEF(SYM) \
+ extern "C" { extern void *SYM; }
+
+ #if defined(__MINGW32__)
+ EXPLICIT_SYMBOL_DEF(_alloca)
+ EXPLICIT_SYMBOL_DEF(__main)
+ EXPLICIT_SYMBOL_DEF(__ashldi3)
+ EXPLICIT_SYMBOL_DEF(__ashrdi3)
+ EXPLICIT_SYMBOL_DEF(__cmpdi2)
+ EXPLICIT_SYMBOL_DEF(__divdi3)
+ EXPLICIT_SYMBOL_DEF(__fixdfdi)
+ EXPLICIT_SYMBOL_DEF(__fixsfdi)
+ EXPLICIT_SYMBOL_DEF(__fixunsdfdi)
+ EXPLICIT_SYMBOL_DEF(__fixunssfdi)
+ EXPLICIT_SYMBOL_DEF(__floatdidf)
+ EXPLICIT_SYMBOL_DEF(__floatdisf)
+ EXPLICIT_SYMBOL_DEF(__lshrdi3)
+ EXPLICIT_SYMBOL_DEF(__moddi3)
+ EXPLICIT_SYMBOL_DEF(__udivdi3)
+ EXPLICIT_SYMBOL_DEF(__umoddi3)
+ #elif defined(_MSC_VER)
+ EXPLICIT_SYMBOL_DEF(_alloca_probe)
+ #endif
+#endif
+
+void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) {
+ // First check symbols added via AddSymbol().
+ if (ExplicitSymbols) {
+ std::map<std::string, void *>::iterator I =
+ ExplicitSymbols->find(symbolName);
+ std::map<std::string, void *>::iterator E = ExplicitSymbols->end();
+ if (I != E)
+ return I->second;
+ }
+
+ // Now search the libraries.
+ for (std::vector<HMODULE>::iterator I = OpenedHandles.begin(),
+ E = OpenedHandles.end(); I != E; ++I) {
+ FARPROC ptr = GetProcAddress((HMODULE)*I, symbolName);
+ if (ptr) {
+ return (void *) ptr;
+ }
+ }
+
+#if defined(__MINGW32__)
+ {
+ EXPLICIT_SYMBOL(_alloca);
+ EXPLICIT_SYMBOL(__main);
+ EXPLICIT_SYMBOL(__ashldi3);
+ EXPLICIT_SYMBOL(__ashrdi3);
+ EXPLICIT_SYMBOL(__cmpdi2);
+ EXPLICIT_SYMBOL(__divdi3);
+ EXPLICIT_SYMBOL(__fixdfdi);
+ EXPLICIT_SYMBOL(__fixsfdi);
+ EXPLICIT_SYMBOL(__fixunsdfdi);
+ EXPLICIT_SYMBOL(__fixunssfdi);
+ EXPLICIT_SYMBOL(__floatdidf);
+ EXPLICIT_SYMBOL(__floatdisf);
+ EXPLICIT_SYMBOL(__lshrdi3);
+ EXPLICIT_SYMBOL(__moddi3);
+ EXPLICIT_SYMBOL(__udivdi3);
+ EXPLICIT_SYMBOL(__umoddi3);
+
+ EXPLICIT_SYMBOL2(alloca, _alloca);
+#undef EXPLICIT_SYMBOL
+#undef EXPLICIT_SYMBOL2
+#undef EXPLICIT_SYMBOL_DEF
+ }
+#elif defined(_MSC_VER)
+ {
+ EXPLICIT_SYMBOL2(alloca, _alloca_probe);
+ EXPLICIT_SYMBOL2(_alloca, _alloca_probe);
+#undef EXPLICIT_SYMBOL
+#undef EXPLICIT_SYMBOL2
+#undef EXPLICIT_SYMBOL_DEF
+ }
+#endif
+
+ return 0;
+}
+
+}
--- /dev/null
+//===- llvm/System/Win32/Host.inc -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Win32 Host support.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Windows.h"
+#include <cstdio>
+#include <string>
+
+using namespace llvm;
+
+std::string sys::getHostTriple() {
+ // FIXME: Adapt to running version.
+ return LLVM_HOSTTRIPLE;
+}
--- /dev/null
+//===- Win32/Memory.cpp - Win32 Memory Implementation -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides the Win32 specific implementation of various Memory
+// management utilities
+//
+//===----------------------------------------------------------------------===//
+
+#include "Windows.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Process.h"
+
+namespace llvm {
+using namespace sys;
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only Win32 specific code
+//=== and must not be UNIX code
+//===----------------------------------------------------------------------===//
+
+MemoryBlock Memory::AllocateRWX(size_t NumBytes,
+ const MemoryBlock *NearBlock,
+ std::string *ErrMsg) {
+ if (NumBytes == 0) return MemoryBlock();
+
+ static const size_t pageSize = Process::GetPageSize();
+ size_t NumPages = (NumBytes+pageSize-1)/pageSize;
+
+ //FIXME: support NearBlock if ever needed on Win64.
+
+ void *pa = VirtualAlloc(NULL, NumPages*pageSize, MEM_COMMIT,
+ PAGE_EXECUTE_READWRITE);
+ if (pa == NULL) {
+ MakeErrMsg(ErrMsg, "Can't allocate RWX Memory: ");
+ return MemoryBlock();
+ }
+
+ MemoryBlock result;
+ result.Address = pa;
+ result.Size = NumPages*pageSize;
+ return result;
+}
+
+bool Memory::ReleaseRWX(MemoryBlock &M, std::string *ErrMsg) {
+ if (M.Address == 0 || M.Size == 0) return false;
+ if (!VirtualFree(M.Address, 0, MEM_RELEASE))
+ return MakeErrMsg(ErrMsg, "Can't release RWX Memory: ");
+ return false;
+}
+
+bool Memory::setWritable(MemoryBlock &M, std::string *ErrMsg) {
+ return true;
+}
+
+bool Memory::setExecutable(MemoryBlock &M, std::string *ErrMsg) {
+ return false;
+}
+
+bool Memory::setRangeWritable(const void *Addr, size_t Size) {
+ return true;
+}
+
+bool Memory::setRangeExecutable(const void *Addr, size_t Size) {
+ return false;
+}
+
+}
--- /dev/null
+//===- llvm/System/Win32/Mutex.inc - Win32 Mutex Implementation -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Win32 specific (non-pthread) Mutex class.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic Win32 code that
+//=== is guaranteed to work on *all* Win32 variants.
+//===----------------------------------------------------------------------===//
+
+#include "Windows.h"
+#include "llvm/Support/Mutex.h"
+
+namespace llvm {
+using namespace sys;
+
+MutexImpl::MutexImpl(bool /*recursive*/)
+{
+ data_ = new CRITICAL_SECTION;
+ InitializeCriticalSection((LPCRITICAL_SECTION)data_);
+}
+
+MutexImpl::~MutexImpl()
+{
+ DeleteCriticalSection((LPCRITICAL_SECTION)data_);
+ delete (LPCRITICAL_SECTION)data_;
+ data_ = 0;
+}
+
+bool
+MutexImpl::acquire()
+{
+ EnterCriticalSection((LPCRITICAL_SECTION)data_);
+ return true;
+}
+
+bool
+MutexImpl::release()
+{
+ LeaveCriticalSection((LPCRITICAL_SECTION)data_);
+ return true;
+}
+
+bool
+MutexImpl::tryacquire()
+{
+ return TryEnterCriticalSection((LPCRITICAL_SECTION)data_);
+}
+
+}
--- /dev/null
+//===- llvm/System/Win32/Path.cpp - Win32 Path Implementation ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides the Win32 specific implementation of the Path class.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic Win32 code that
+//=== is guaranteed to work on *all* Win32 variants.
+//===----------------------------------------------------------------------===//
+
+#include "Windows.h"
+#include <malloc.h>
+#include <cstdio>
+
+// We need to undo a macro defined in Windows.h, otherwise we won't compile:
+#undef CopyFile
+#undef GetCurrentDirectory
+
+// Windows happily accepts either forward or backward slashes, though any path
+// returned by a Win32 API will have backward slashes. As LLVM code basically
+// assumes forward slashes are used, backward slashs are converted where they
+// can be introduced into a path.
+//
+// Another invariant is that a path ends with a slash if and only if the path
+// is a root directory. Any other use of a trailing slash is stripped. Unlike
+// in Unix, Windows has a rather complicated notion of a root path and this
+// invariant helps simply the code.
+
+static void FlipBackSlashes(std::string& s) {
+ for (size_t i = 0; i < s.size(); i++)
+ if (s[i] == '\\')
+ s[i] = '/';
+}
+
+namespace llvm {
+namespace sys {
+
+const char PathSeparator = ';';
+
+StringRef Path::GetEXESuffix() {
+ return "exe";
+}
+
+Path::Path(llvm::StringRef p)
+ : path(p) {
+ FlipBackSlashes(path);
+}
+
+Path::Path(const char *StrStart, unsigned StrLen)
+ : path(StrStart, StrLen) {
+ FlipBackSlashes(path);
+}
+
+Path&
+Path::operator=(StringRef that) {
+ path.assign(that.data(), that.size());
+ FlipBackSlashes(path);
+ return *this;
+}
+
+// push_back 0 on create, and pop_back on delete.
+struct ScopedNullTerminator {
+ std::string &str;
+ ScopedNullTerminator(std::string &s) : str(s) { str.push_back(0); }
+ ~ScopedNullTerminator() {
+ // str.pop_back(); But wait, C++03 doesn't have this...
+ assert(!str.empty() && str[str.size() - 1] == 0
+ && "Null char not present!");
+ str.resize(str.size() - 1);
+ }
+};
+
+bool
+Path::isValid() const {
+ if (path.empty())
+ return false;
+
+ // If there is a colon, it must be the second character, preceded by a letter
+ // and followed by something.
+ size_t len = path.size();
+ // This code assumes that path is null terminated, so make sure it is.
+ ScopedNullTerminator snt(path);
+ size_t pos = path.rfind(':',len);
+ size_t rootslash = 0;
+ if (pos != std::string::npos) {
+ if (pos != 1 || !isalpha(path[0]) || len < 3)
+ return false;
+ rootslash = 2;
+ }
+
+ // Look for a UNC path, and if found adjust our notion of the root slash.
+ if (len > 3 && path[0] == '/' && path[1] == '/') {
+ rootslash = path.find('/', 2);
+ if (rootslash == std::string::npos)
+ rootslash = 0;
+ }
+
+ // Check for illegal characters.
+ if (path.find_first_of("\\<>\"|\001\002\003\004\005\006\007\010\011\012"
+ "\013\014\015\016\017\020\021\022\023\024\025\026"
+ "\027\030\031\032\033\034\035\036\037")
+ != std::string::npos)
+ return false;
+
+ // Remove trailing slash, unless it's a root slash.
+ if (len > rootslash+1 && path[len-1] == '/')
+ path.erase(--len);
+
+ // Check each component for legality.
+ for (pos = 0; pos < len; ++pos) {
+ // A component may not end in a space.
+ if (path[pos] == ' ') {
+ if (path[pos+1] == '/' || path[pos+1] == '\0')
+ return false;
+ }
+
+ // A component may not end in a period.
+ if (path[pos] == '.') {
+ if (path[pos+1] == '/' || path[pos+1] == '\0') {
+ // Unless it is the pseudo-directory "."...
+ if (pos == 0 || path[pos-1] == '/' || path[pos-1] == ':')
+ return true;
+ // or "..".
+ if (pos > 0 && path[pos-1] == '.') {
+ if (pos == 1 || path[pos-2] == '/' || path[pos-2] == ':')
+ return true;
+ }
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+void Path::makeAbsolute() {
+ TCHAR FullPath[MAX_PATH + 1] = {0};
+ LPTSTR FilePart = NULL;
+
+ DWORD RetLength = ::GetFullPathNameA(path.c_str(),
+ sizeof(FullPath)/sizeof(FullPath[0]),
+ FullPath, &FilePart);
+
+ if (0 == RetLength) {
+ // FIXME: Report the error GetLastError()
+ assert(0 && "Unable to make absolute path!");
+ } else if (RetLength > MAX_PATH) {
+ // FIXME: Report too small buffer (needed RetLength bytes).
+ assert(0 && "Unable to make absolute path!");
+ } else {
+ path = FullPath;
+ }
+}
+
+bool
+Path::isAbsolute(const char *NameStart, unsigned NameLen) {
+ assert(NameStart);
+ // FIXME: This does not handle correctly an absolute path starting from
+ // a drive letter or in UNC format.
+ switch (NameLen) {
+ case 0:
+ return false;
+ case 1:
+ case 2:
+ return NameStart[0] == '/';
+ default:
+ return
+ (NameStart[0] == '/' || (NameStart[1] == ':' && NameStart[2] == '/')) ||
+ (NameStart[0] == '\\' || (NameStart[1] == ':' && NameStart[2] == '\\'));
+ }
+}
+
+bool
+Path::isAbsolute() const {
+ // FIXME: This does not handle correctly an absolute path starting from
+ // a drive letter or in UNC format.
+ switch (path.length()) {
+ case 0:
+ return false;
+ case 1:
+ case 2:
+ return path[0] == '/';
+ default:
+ return path[0] == '/' || (path[1] == ':' && path[2] == '/');
+ }
+}
+
+static Path *TempDirectory;
+
+Path
+Path::GetTemporaryDirectory(std::string* ErrMsg) {
+ if (TempDirectory)
+ return *TempDirectory;
+
+ char pathname[MAX_PATH];
+ if (!GetTempPath(MAX_PATH, pathname)) {
+ if (ErrMsg)
+ *ErrMsg = "Can't determine temporary directory";
+ return Path();
+ }
+
+ Path result;
+ result.set(pathname);
+
+ // Append a subdirectory passed on our process id so multiple LLVMs don't
+ // step on each other's toes.
+#ifdef __MINGW32__
+ // Mingw's Win32 header files are broken.
+ sprintf(pathname, "LLVM_%u", unsigned(GetCurrentProcessId()));
+#else
+ sprintf(pathname, "LLVM_%u", GetCurrentProcessId());
+#endif
+ result.appendComponent(pathname);
+
+ // If there's a directory left over from a previous LLVM execution that
+ // happened to have the same process id, get rid of it.
+ result.eraseFromDisk(true);
+
+ // And finally (re-)create the empty directory.
+ result.createDirectoryOnDisk(false);
+ TempDirectory = new Path(result);
+ return *TempDirectory;
+}
+
+// FIXME: the following set of functions don't map to Windows very well.
+Path
+Path::GetRootDirectory() {
+ // This is the only notion that that Windows has of a root directory. Nothing
+ // is here except for drives.
+ return Path("file:///");
+}
+
+void
+Path::GetSystemLibraryPaths(std::vector<sys::Path>& Paths) {
+ char buff[MAX_PATH];
+ // Generic form of C:\Windows\System32
+ HRESULT res = SHGetFolderPathA(NULL,
+ CSIDL_FLAG_CREATE | CSIDL_SYSTEM,
+ NULL,
+ SHGFP_TYPE_CURRENT,
+ buff);
+ if (res != S_OK) {
+ assert(0 && "Failed to get system directory");
+ return;
+ }
+ Paths.push_back(sys::Path(buff));
+
+ // Reset buff.
+ buff[0] = 0;
+ // Generic form of C:\Windows
+ res = SHGetFolderPathA(NULL,
+ CSIDL_FLAG_CREATE | CSIDL_WINDOWS,
+ NULL,
+ SHGFP_TYPE_CURRENT,
+ buff);
+ if (res != S_OK) {
+ assert(0 && "Failed to get windows directory");
+ return;
+ }
+ Paths.push_back(sys::Path(buff));
+}
+
+void
+Path::GetBitcodeLibraryPaths(std::vector<sys::Path>& Paths) {
+ char * env_var = getenv("LLVM_LIB_SEARCH_PATH");
+ if (env_var != 0) {
+ getPathList(env_var,Paths);
+ }
+#ifdef LLVM_LIBDIR
+ {
+ Path tmpPath;
+ if (tmpPath.set(LLVM_LIBDIR))
+ if (tmpPath.canRead())
+ Paths.push_back(tmpPath);
+ }
+#endif
+ GetSystemLibraryPaths(Paths);
+}
+
+Path
+Path::GetLLVMDefaultConfigDir() {
+ Path ret = GetUserHomeDirectory();
+ if (!ret.appendComponent(".llvm"))
+ assert(0 && "Failed to append .llvm");
+ return ret;
+}
+
+Path
+Path::GetUserHomeDirectory() {
+ char buff[MAX_PATH];
+ HRESULT res = SHGetFolderPathA(NULL,
+ CSIDL_FLAG_CREATE | CSIDL_APPDATA,
+ NULL,
+ SHGFP_TYPE_CURRENT,
+ buff);
+ if (res != S_OK)
+ assert(0 && "Failed to get user home directory");
+ return Path(buff);
+}
+
+Path
+Path::GetCurrentDirectory() {
+ char pathname[MAX_PATH];
+ ::GetCurrentDirectoryA(MAX_PATH,pathname);
+ return Path(pathname);
+}
+
+/// GetMainExecutable - Return the path to the main executable, given the
+/// value of argv[0] from program startup.
+Path Path::GetMainExecutable(const char *argv0, void *MainAddr) {
+ char pathname[MAX_PATH];
+ DWORD ret = ::GetModuleFileNameA(NULL, pathname, MAX_PATH);
+ return ret != MAX_PATH ? Path(pathname) : Path();
+}
+
+
+// FIXME: the above set of functions don't map to Windows very well.
+
+
+StringRef Path::getDirname() const {
+ return getDirnameCharSep(path, "/");
+}
+
+StringRef
+Path::getBasename() const {
+ // Find the last slash
+ size_t slash = path.rfind('/');
+ if (slash == std::string::npos)
+ slash = 0;
+ else
+ slash++;
+
+ size_t dot = path.rfind('.');
+ if (dot == std::string::npos || dot < slash)
+ return StringRef(path).substr(slash);
+ else
+ return StringRef(path).substr(slash, dot - slash);
+}
+
+StringRef
+Path::getSuffix() const {
+ // Find the last slash
+ size_t slash = path.rfind('/');
+ if (slash == std::string::npos)
+ slash = 0;
+ else
+ slash++;
+
+ size_t dot = path.rfind('.');
+ if (dot == std::string::npos || dot < slash)
+ return StringRef("");
+ else
+ return StringRef(path).substr(dot + 1);
+}
+
+bool
+Path::exists() const {
+ DWORD attr = GetFileAttributes(path.c_str());
+ return attr != INVALID_FILE_ATTRIBUTES;
+}
+
+bool
+Path::isDirectory() const {
+ DWORD attr = GetFileAttributes(path.c_str());
+ return (attr != INVALID_FILE_ATTRIBUTES) &&
+ (attr & FILE_ATTRIBUTE_DIRECTORY);
+}
+
+bool
+Path::isSymLink() const {
+ DWORD attributes = GetFileAttributes(path.c_str());
+
+ if (attributes == INVALID_FILE_ATTRIBUTES)
+ // There's no sane way to report this :(.
+ assert(0 && "GetFileAttributes returned INVALID_FILE_ATTRIBUTES");
+
+ // This isn't exactly what defines a NTFS symlink, but it is only true for
+ // paths that act like a symlink.
+ return attributes & FILE_ATTRIBUTE_REPARSE_POINT;
+}
+
+bool
+Path::canRead() const {
+ // FIXME: take security attributes into account.
+ DWORD attr = GetFileAttributes(path.c_str());
+ return attr != INVALID_FILE_ATTRIBUTES;
+}
+
+bool
+Path::canWrite() const {
+ // FIXME: take security attributes into account.
+ DWORD attr = GetFileAttributes(path.c_str());
+ return (attr != INVALID_FILE_ATTRIBUTES) && !(attr & FILE_ATTRIBUTE_READONLY);
+}
+
+bool
+Path::canExecute() const {
+ // FIXME: take security attributes into account.
+ DWORD attr = GetFileAttributes(path.c_str());
+ return attr != INVALID_FILE_ATTRIBUTES;
+}
+
+bool
+Path::isRegularFile() const {
+ if (isDirectory())
+ return false;
+ return true;
+}
+
+StringRef
+Path::getLast() const {
+ // Find the last slash
+ size_t pos = path.rfind('/');
+
+ // Handle the corner cases
+ if (pos == std::string::npos)
+ return path;
+
+ // If the last character is a slash, we have a root directory
+ if (pos == path.length()-1)
+ return path;
+
+ // Return everything after the last slash
+ return StringRef(path).substr(pos+1);
+}
+
+const FileStatus *
+PathWithStatus::getFileStatus(bool update, std::string *ErrStr) const {
+ if (!fsIsValid || update) {
+ WIN32_FILE_ATTRIBUTE_DATA fi;
+ if (!GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &fi)) {
+ MakeErrMsg(ErrStr, "getStatusInfo():" + std::string(path) +
+ ": Can't get status: ");
+ return 0;
+ }
+
+ status.fileSize = fi.nFileSizeHigh;
+ status.fileSize <<= sizeof(fi.nFileSizeHigh)*8;
+ status.fileSize += fi.nFileSizeLow;
+
+ status.mode = fi.dwFileAttributes & FILE_ATTRIBUTE_READONLY ? 0555 : 0777;
+ status.user = 9999; // Not applicable to Windows, so...
+ status.group = 9999; // Not applicable to Windows, so...
+
+ // FIXME: this is only unique if the file is accessed by the same file path.
+ // How do we do this for C:\dir\file and ..\dir\file ? Unix has inode
+ // numbers, but the concept doesn't exist in Windows.
+ status.uniqueID = 0;
+ for (unsigned i = 0; i < path.length(); ++i)
+ status.uniqueID += path[i];
+
+ ULARGE_INTEGER ui;
+ ui.LowPart = fi.ftLastWriteTime.dwLowDateTime;
+ ui.HighPart = fi.ftLastWriteTime.dwHighDateTime;
+ status.modTime.fromWin32Time(ui.QuadPart);
+
+ status.isDir = fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
+ fsIsValid = true;
+ }
+ return &status;
+}
+
+bool Path::makeReadableOnDisk(std::string* ErrMsg) {
+ // All files are readable on Windows (ignoring security attributes).
+ return false;
+}
+
+bool Path::makeWriteableOnDisk(std::string* ErrMsg) {
+ DWORD attr = GetFileAttributes(path.c_str());
+
+ // If it doesn't exist, we're done.
+ if (attr == INVALID_FILE_ATTRIBUTES)
+ return false;
+
+ if (attr & FILE_ATTRIBUTE_READONLY) {
+ if (!SetFileAttributes(path.c_str(), attr & ~FILE_ATTRIBUTE_READONLY)) {
+ MakeErrMsg(ErrMsg, std::string(path) + ": Can't make file writable: ");
+ return true;
+ }
+ }
+ return false;
+}
+
+bool Path::makeExecutableOnDisk(std::string* ErrMsg) {
+ // All files are executable on Windows (ignoring security attributes).
+ return false;
+}
+
+bool
+Path::getDirectoryContents(std::set<Path>& result, std::string* ErrMsg) const {
+ WIN32_FILE_ATTRIBUTE_DATA fi;
+ if (!GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &fi)) {
+ MakeErrMsg(ErrMsg, path + ": can't get status of file");
+ return true;
+ }
+
+ if (!(fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
+ if (ErrMsg)
+ *ErrMsg = path + ": not a directory";
+ return true;
+ }
+
+ result.clear();
+ WIN32_FIND_DATA fd;
+ std::string searchpath = path;
+ if (path.size() == 0 || searchpath[path.size()-1] == '/')
+ searchpath += "*";
+ else
+ searchpath += "/*";
+
+ HANDLE h = FindFirstFile(searchpath.c_str(), &fd);
+ if (h == INVALID_HANDLE_VALUE) {
+ if (GetLastError() == ERROR_FILE_NOT_FOUND)
+ return true; // not really an error, now is it?
+ MakeErrMsg(ErrMsg, path + ": Can't read directory: ");
+ return true;
+ }
+
+ do {
+ if (fd.cFileName[0] == '.')
+ continue;
+ Path aPath(path);
+ aPath.appendComponent(&fd.cFileName[0]);
+ result.insert(aPath);
+ } while (FindNextFile(h, &fd));
+
+ DWORD err = GetLastError();
+ FindClose(h);
+ if (err != ERROR_NO_MORE_FILES) {
+ SetLastError(err);
+ MakeErrMsg(ErrMsg, path + ": Can't read directory: ");
+ return true;
+ }
+ return false;
+}
+
+bool
+Path::set(StringRef a_path) {
+ if (a_path.empty())
+ return false;
+ std::string save(path);
+ path = a_path;
+ FlipBackSlashes(path);
+ if (!isValid()) {
+ path = save;
+ return false;
+ }
+ return true;
+}
+
+bool
+Path::appendComponent(StringRef name) {
+ if (name.empty())
+ return false;
+ std::string save(path);
+ if (!path.empty()) {
+ size_t last = path.size() - 1;
+ if (path[last] != '/')
+ path += '/';
+ }
+ path += name;
+ if (!isValid()) {
+ path = save;
+ return false;
+ }
+ return true;
+}
+
+bool
+Path::eraseComponent() {
+ size_t slashpos = path.rfind('/',path.size());
+ if (slashpos == path.size() - 1 || slashpos == std::string::npos)
+ return false;
+ std::string save(path);
+ path.erase(slashpos);
+ if (!isValid()) {
+ path = save;
+ return false;
+ }
+ return true;
+}
+
+bool
+Path::eraseSuffix() {
+ size_t dotpos = path.rfind('.',path.size());
+ size_t slashpos = path.rfind('/',path.size());
+ if (dotpos != std::string::npos) {
+ if (slashpos == std::string::npos || dotpos > slashpos+1) {
+ std::string save(path);
+ path.erase(dotpos, path.size()-dotpos);
+ if (!isValid()) {
+ path = save;
+ return false;
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+inline bool PathMsg(std::string* ErrMsg, const char* pathname, const char*msg) {
+ if (ErrMsg)
+ *ErrMsg = std::string(pathname) + ": " + std::string(msg);
+ return true;
+}
+
+bool
+Path::createDirectoryOnDisk(bool create_parents, std::string* ErrMsg) {
+ // Get a writeable copy of the path name
+ size_t len = path.length();
+ char *pathname = reinterpret_cast<char *>(_alloca(len+2));
+ path.copy(pathname, len);
+ pathname[len] = 0;
+
+ // Make sure it ends with a slash.
+ if (len == 0 || pathname[len - 1] != '/') {
+ pathname[len] = '/';
+ pathname[++len] = 0;
+ }
+
+ // Determine starting point for initial / search.
+ char *next = pathname;
+ if (pathname[0] == '/' && pathname[1] == '/') {
+ // Skip host name.
+ next = strchr(pathname+2, '/');
+ if (next == NULL)
+ return PathMsg(ErrMsg, pathname, "badly formed remote directory");
+
+ // Skip share name.
+ next = strchr(next+1, '/');
+ if (next == NULL)
+ return PathMsg(ErrMsg, pathname,"badly formed remote directory");
+
+ next++;
+ if (*next == 0)
+ return PathMsg(ErrMsg, pathname, "badly formed remote directory");
+
+ } else {
+ if (pathname[1] == ':')
+ next += 2; // skip drive letter
+ if (*next == '/')
+ next++; // skip root directory
+ }
+
+ // If we're supposed to create intermediate directories
+ if (create_parents) {
+ // Loop through the directory components until we're done
+ while (*next) {
+ next = strchr(next, '/');
+ *next = 0;
+ if (!CreateDirectory(pathname, NULL) &&
+ GetLastError() != ERROR_ALREADY_EXISTS)
+ return MakeErrMsg(ErrMsg,
+ std::string(pathname) + ": Can't create directory: ");
+ *next++ = '/';
+ }
+ } else {
+ // Drop trailing slash.
+ pathname[len-1] = 0;
+ if (!CreateDirectory(pathname, NULL) &&
+ GetLastError() != ERROR_ALREADY_EXISTS) {
+ return MakeErrMsg(ErrMsg, std::string(pathname) +
+ ": Can't create directory: ");
+ }
+ }
+ return false;
+}
+
+bool
+Path::createFileOnDisk(std::string* ErrMsg) {
+ // Create the file
+ HANDLE h = CreateFile(path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_NEW,
+ FILE_ATTRIBUTE_NORMAL, NULL);
+ if (h == INVALID_HANDLE_VALUE)
+ return MakeErrMsg(ErrMsg, path + ": Can't create file: ");
+
+ CloseHandle(h);
+ return false;
+}
+
+bool
+Path::eraseFromDisk(bool remove_contents, std::string *ErrStr) const {
+ WIN32_FILE_ATTRIBUTE_DATA fi;
+ if (!GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &fi))
+ return true;
+
+ if (fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+ // If it doesn't exist, we're done.
+ if (!exists())
+ return false;
+
+ char *pathname = reinterpret_cast<char *>(_alloca(path.length()+3));
+ int lastchar = path.length() - 1 ;
+ path.copy(pathname, lastchar+1);
+
+ // Make path end with '/*'.
+ if (pathname[lastchar] != '/')
+ pathname[++lastchar] = '/';
+ pathname[lastchar+1] = '*';
+ pathname[lastchar+2] = 0;
+
+ if (remove_contents) {
+ WIN32_FIND_DATA fd;
+ HANDLE h = FindFirstFile(pathname, &fd);
+
+ // It's a bad idea to alter the contents of a directory while enumerating
+ // its contents. So build a list of its contents first, then destroy them.
+
+ if (h != INVALID_HANDLE_VALUE) {
+ std::vector<Path> list;
+
+ do {
+ if (strcmp(fd.cFileName, ".") == 0)
+ continue;
+ if (strcmp(fd.cFileName, "..") == 0)
+ continue;
+
+ Path aPath(path);
+ aPath.appendComponent(&fd.cFileName[0]);
+ list.push_back(aPath);
+ } while (FindNextFile(h, &fd));
+
+ DWORD err = GetLastError();
+ FindClose(h);
+ if (err != ERROR_NO_MORE_FILES) {
+ SetLastError(err);
+ return MakeErrMsg(ErrStr, path + ": Can't read directory: ");
+ }
+
+ for (std::vector<Path>::iterator I = list.begin(); I != list.end();
+ ++I) {
+ Path &aPath = *I;
+ aPath.eraseFromDisk(true);
+ }
+ } else {
+ if (GetLastError() != ERROR_FILE_NOT_FOUND)
+ return MakeErrMsg(ErrStr, path + ": Can't read directory: ");
+ }
+ }
+
+ pathname[lastchar] = 0;
+ if (!RemoveDirectory(pathname))
+ return MakeErrMsg(ErrStr,
+ std::string(pathname) + ": Can't destroy directory: ");
+ return false;
+ } else {
+ // Read-only files cannot be deleted on Windows. Must remove the read-only
+ // attribute first.
+ if (fi.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
+ if (!SetFileAttributes(path.c_str(),
+ fi.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY))
+ return MakeErrMsg(ErrStr, path + ": Can't destroy file: ");
+ }
+
+ if (!DeleteFile(path.c_str()))
+ return MakeErrMsg(ErrStr, path + ": Can't destroy file: ");
+ return false;
+ }
+}
+
+bool Path::getMagicNumber(std::string& Magic, unsigned len) const {
+ assert(len < 1024 && "Request for magic string too long");
+ char* buf = reinterpret_cast<char*>(alloca(len));
+
+ HANDLE h = CreateFile(path.c_str(),
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (h == INVALID_HANDLE_VALUE)
+ return false;
+
+ DWORD nRead = 0;
+ BOOL ret = ReadFile(h, buf, len, &nRead, NULL);
+ CloseHandle(h);
+
+ if (!ret || nRead != len)
+ return false;
+
+ Magic = std::string(buf, len);
+ return true;
+}
+
+bool
+Path::renamePathOnDisk(const Path& newName, std::string* ErrMsg) {
+ if (!MoveFileEx(path.c_str(), newName.c_str(), MOVEFILE_REPLACE_EXISTING))
+ return MakeErrMsg(ErrMsg, "Can't move '" + path + "' to '" + newName.path
+ + "': ");
+ return false;
+}
+
+bool
+Path::setStatusInfoOnDisk(const FileStatus &si, std::string *ErrMsg) const {
+ // FIXME: should work on directories also.
+ if (!si.isFile) {
+ return true;
+ }
+
+ HANDLE h = CreateFile(path.c_str(),
+ FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (h == INVALID_HANDLE_VALUE)
+ return true;
+
+ BY_HANDLE_FILE_INFORMATION bhfi;
+ if (!GetFileInformationByHandle(h, &bhfi)) {
+ DWORD err = GetLastError();
+ CloseHandle(h);
+ SetLastError(err);
+ return MakeErrMsg(ErrMsg, path + ": GetFileInformationByHandle: ");
+ }
+
+ ULARGE_INTEGER ui;
+ ui.QuadPart = si.modTime.toWin32Time();
+ FILETIME ft;
+ ft.dwLowDateTime = ui.LowPart;
+ ft.dwHighDateTime = ui.HighPart;
+ BOOL ret = SetFileTime(h, NULL, &ft, &ft);
+ DWORD err = GetLastError();
+ CloseHandle(h);
+ if (!ret) {
+ SetLastError(err);
+ return MakeErrMsg(ErrMsg, path + ": SetFileTime: ");
+ }
+
+ // Best we can do with Unix permission bits is to interpret the owner
+ // writable bit.
+ if (si.mode & 0200) {
+ if (bhfi.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
+ if (!SetFileAttributes(path.c_str(),
+ bhfi.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY))
+ return MakeErrMsg(ErrMsg, path + ": SetFileAttributes: ");
+ }
+ } else {
+ if (!(bhfi.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) {
+ if (!SetFileAttributes(path.c_str(),
+ bhfi.dwFileAttributes | FILE_ATTRIBUTE_READONLY))
+ return MakeErrMsg(ErrMsg, path + ": SetFileAttributes: ");
+ }
+ }
+
+ return false;
+}
+
+bool
+CopyFile(const sys::Path &Dest, const sys::Path &Src, std::string* ErrMsg) {
+ // Can't use CopyFile macro defined in Windows.h because it would mess up the
+ // above line. We use the expansion it would have in a non-UNICODE build.
+ if (!::CopyFileA(Src.c_str(), Dest.c_str(), false))
+ return MakeErrMsg(ErrMsg, "Can't copy '" + Src.str() +
+ "' to '" + Dest.str() + "': ");
+ return false;
+}
+
+bool
+Path::makeUnique(bool reuse_current, std::string* ErrMsg) {
+ if (reuse_current && !exists())
+ return false; // File doesn't exist already, just use it!
+
+ // Reserve space for -XXXXXX at the end.
+ char *FNBuffer = (char*) alloca(path.size()+8);
+ unsigned offset = path.size();
+ path.copy(FNBuffer, offset);
+
+ // Find a numeric suffix that isn't used by an existing file. Assume there
+ // won't be more than 1 million files with the same prefix. Probably a safe
+ // bet.
+ static unsigned FCounter = 0;
+ do {
+ sprintf(FNBuffer+offset, "-%06u", FCounter);
+ if (++FCounter > 999999)
+ FCounter = 0;
+ path = FNBuffer;
+ } while (exists());
+ return false;
+}
+
+bool
+Path::createTemporaryFileOnDisk(bool reuse_current, std::string* ErrMsg) {
+ // Make this into a unique file name
+ makeUnique(reuse_current, ErrMsg);
+
+ // Now go and create it
+ HANDLE h = CreateFile(path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_NEW,
+ FILE_ATTRIBUTE_NORMAL, NULL);
+ if (h == INVALID_HANDLE_VALUE)
+ return MakeErrMsg(ErrMsg, path + ": can't create file");
+
+ CloseHandle(h);
+ return false;
+}
+
+/// MapInFilePages - Not yet implemented on win32.
+const char *Path::MapInFilePages(int FD, uint64_t FileSize) {
+ return 0;
+}
+
+/// MapInFilePages - Not yet implemented on win32.
+void Path::UnMapFilePages(const char *Base, uint64_t FileSize) {
+ assert(0 && "NOT IMPLEMENTED");
+}
+
+}
+}
--- /dev/null
+//===- Win32/Process.cpp - Win32 Process Implementation ------- -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides the Win32 specific implementation of the Process class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Windows.h"
+#include <psapi.h>
+#include <malloc.h>
+#include <io.h>
+
+#ifdef __MINGW32__
+ #if (HAVE_LIBPSAPI != 1)
+ #error "libpsapi.a should be present"
+ #endif
+#else
+ #pragma comment(lib, "psapi.lib")
+#endif
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only Win32 specific code
+//=== and must not be UNIX code
+//===----------------------------------------------------------------------===//
+
+#ifdef __MINGW32__
+// This ban should be lifted when MinGW 1.0+ has defined this value.
+# define _HEAPOK (-2)
+#endif
+
+namespace llvm {
+using namespace sys;
+
+// This function retrieves the page size using GetSystemInfo and is present
+// solely so it can be called once in Process::GetPageSize to initialize the
+// static variable PageSize.
+inline unsigned GetPageSizeOnce() {
+ // NOTE: A 32-bit application running under WOW64 is supposed to use
+ // GetNativeSystemInfo. However, this interface is not present prior
+ // to Windows XP so to use it requires dynamic linking. It is not clear
+ // how this affects the reported page size, if at all. One could argue
+ // that LLVM ought to run as 64-bits on a 64-bit system, anyway.
+ SYSTEM_INFO info;
+ GetSystemInfo(&info);
+ return static_cast<unsigned>(info.dwPageSize);
+}
+
+unsigned
+Process::GetPageSize() {
+ static const unsigned PageSize = GetPageSizeOnce();
+ return PageSize;
+}
+
+size_t
+Process::GetMallocUsage()
+{
+ _HEAPINFO hinfo;
+ hinfo._pentry = NULL;
+
+ size_t size = 0;
+
+ while (_heapwalk(&hinfo) == _HEAPOK)
+ size += hinfo._size;
+
+ return size;
+}
+
+size_t
+Process::GetTotalMemoryUsage()
+{
+ PROCESS_MEMORY_COUNTERS pmc;
+ GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc));
+ return pmc.PagefileUsage;
+}
+
+void
+Process::GetTimeUsage(
+ TimeValue& elapsed, TimeValue& user_time, TimeValue& sys_time)
+{
+ elapsed = TimeValue::now();
+
+ uint64_t ProcCreate, ProcExit, KernelTime, UserTime;
+ GetProcessTimes(GetCurrentProcess(), (FILETIME*)&ProcCreate,
+ (FILETIME*)&ProcExit, (FILETIME*)&KernelTime,
+ (FILETIME*)&UserTime);
+
+ // FILETIME's are # of 100 nanosecond ticks (1/10th of a microsecond)
+ user_time.seconds( UserTime / 10000000 );
+ user_time.nanoseconds( unsigned(UserTime % 10000000) * 100 );
+ sys_time.seconds( KernelTime / 10000000 );
+ sys_time.nanoseconds( unsigned(KernelTime % 10000000) * 100 );
+}
+
+int Process::GetCurrentUserId()
+{
+ return 65536;
+}
+
+int Process::GetCurrentGroupId()
+{
+ return 65536;
+}
+
+// Some LLVM programs such as bugpoint produce core files as a normal part of
+// their operation. To prevent the disk from filling up, this configuration item
+// does what's necessary to prevent their generation.
+void Process::PreventCoreFiles() {
+ // Windows doesn't do core files, but it does do modal pop-up message
+ // boxes. As this method is used by bugpoint, preventing these pop-ups
+ // is the moral equivalent of suppressing core files.
+ SetErrorMode(SEM_FAILCRITICALERRORS |
+ SEM_NOGPFAULTERRORBOX |
+ SEM_NOOPENFILEERRORBOX);
+}
+
+bool Process::StandardInIsUserInput() {
+ return FileDescriptorIsDisplayed(0);
+}
+
+bool Process::StandardOutIsDisplayed() {
+ return FileDescriptorIsDisplayed(1);
+}
+
+bool Process::StandardErrIsDisplayed() {
+ return FileDescriptorIsDisplayed(2);
+}
+
+bool Process::FileDescriptorIsDisplayed(int fd) {
+ DWORD Mode; // Unused
+ return (GetConsoleMode((HANDLE)_get_osfhandle(fd), &Mode) != 0);
+}
+
+unsigned Process::StandardOutColumns() {
+ unsigned Columns = 0;
+ CONSOLE_SCREEN_BUFFER_INFO csbi;
+ if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi))
+ Columns = csbi.dwSize.X;
+ return Columns;
+}
+
+unsigned Process::StandardErrColumns() {
+ unsigned Columns = 0;
+ CONSOLE_SCREEN_BUFFER_INFO csbi;
+ if (GetConsoleScreenBufferInfo(GetStdHandle(STD_ERROR_HANDLE), &csbi))
+ Columns = csbi.dwSize.X;
+ return Columns;
+}
+
+// It always has colors.
+bool Process::StandardErrHasColors() {
+ return StandardErrIsDisplayed();
+}
+
+bool Process::StandardOutHasColors() {
+ return StandardOutIsDisplayed();
+}
+
+namespace {
+class DefaultColors
+{
+ private:
+ WORD defaultColor;
+ public:
+ DefaultColors()
+ :defaultColor(GetCurrentColor()) {}
+ static unsigned GetCurrentColor() {
+ CONSOLE_SCREEN_BUFFER_INFO csbi;
+ if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi))
+ return csbi.wAttributes;
+ return 0;
+ }
+ WORD operator()() const { return defaultColor; }
+};
+
+DefaultColors defaultColors;
+}
+
+bool Process::ColorNeedsFlush() {
+ return true;
+}
+
+const char *Process::OutputBold(bool bg) {
+ WORD colors = DefaultColors::GetCurrentColor();
+ if (bg)
+ colors |= BACKGROUND_INTENSITY;
+ else
+ colors |= FOREGROUND_INTENSITY;
+ SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), colors);
+ return 0;
+}
+
+const char *Process::OutputColor(char code, bool bold, bool bg) {
+ WORD colors;
+ if (bg) {
+ colors = ((code&1) ? BACKGROUND_RED : 0) |
+ ((code&2) ? BACKGROUND_GREEN : 0 ) |
+ ((code&4) ? BACKGROUND_BLUE : 0);
+ if (bold)
+ colors |= BACKGROUND_INTENSITY;
+ } else {
+ colors = ((code&1) ? FOREGROUND_RED : 0) |
+ ((code&2) ? FOREGROUND_GREEN : 0 ) |
+ ((code&4) ? FOREGROUND_BLUE : 0);
+ if (bold)
+ colors |= FOREGROUND_INTENSITY;
+ }
+ SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), colors);
+ return 0;
+}
+
+const char *Process::ResetColor() {
+ SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), defaultColors());
+ return 0;
+}
+
+}
--- /dev/null
+//===- Win32/Program.cpp - Win32 Program Implementation ------- -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides the Win32 specific implementation of the Program class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Windows.h"
+#include <cstdio>
+#include <malloc.h>
+#include <io.h>
+#include <fcntl.h>
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only Win32 specific code
+//=== and must not be UNIX code
+//===----------------------------------------------------------------------===//
+
+#ifdef __MINGW32__
+// Ancient mingw32's w32api might not have this declaration.
+extern "C"
+BOOL WINAPI SetInformationJobObject(HANDLE hJob,
+ JOBOBJECTINFOCLASS JobObjectInfoClass,
+ LPVOID lpJobObjectInfo,
+ DWORD cbJobObjectInfoLength);
+#endif
+
+namespace {
+ struct Win32ProcessInfo {
+ HANDLE hProcess;
+ DWORD dwProcessId;
+ };
+}
+
+namespace llvm {
+using namespace sys;
+
+Program::Program() : Data_(0) {}
+
+Program::~Program() {
+ if (Data_) {
+ Win32ProcessInfo* wpi = reinterpret_cast<Win32ProcessInfo*>(Data_);
+ CloseHandle(wpi->hProcess);
+ delete wpi;
+ Data_ = 0;
+ }
+}
+
+unsigned Program::GetPid() const {
+ Win32ProcessInfo* wpi = reinterpret_cast<Win32ProcessInfo*>(Data_);
+ return wpi->dwProcessId;
+}
+
+// This function just uses the PATH environment variable to find the program.
+Path
+Program::FindProgramByName(const std::string& progName) {
+
+ // Check some degenerate cases
+ if (progName.length() == 0) // no program
+ return Path();
+ Path temp;
+ if (!temp.set(progName)) // invalid name
+ return Path();
+ // Return paths with slashes verbatim.
+ if (progName.find('\\') != std::string::npos ||
+ progName.find('/') != std::string::npos)
+ return temp;
+
+ // At this point, the file name is valid and does not contain slashes.
+ // Let Windows search for it.
+ char buffer[MAX_PATH];
+ char *dummy = NULL;
+ DWORD len = SearchPath(NULL, progName.c_str(), ".exe", MAX_PATH,
+ buffer, &dummy);
+
+ // See if it wasn't found.
+ if (len == 0)
+ return Path();
+
+ // See if we got the entire path.
+ if (len < MAX_PATH)
+ return Path(buffer);
+
+ // Buffer was too small; grow and retry.
+ while (true) {
+ char *b = reinterpret_cast<char *>(_alloca(len+1));
+ DWORD len2 = SearchPath(NULL, progName.c_str(), ".exe", len+1, b, &dummy);
+
+ // It is unlikely the search failed, but it's always possible some file
+ // was added or removed since the last search, so be paranoid...
+ if (len2 == 0)
+ return Path();
+ else if (len2 <= len)
+ return Path(b);
+
+ len = len2;
+ }
+}
+
+static HANDLE RedirectIO(const Path *path, int fd, std::string* ErrMsg) {
+ HANDLE h;
+ if (path == 0) {
+ DuplicateHandle(GetCurrentProcess(), (HANDLE)_get_osfhandle(fd),
+ GetCurrentProcess(), &h,
+ 0, TRUE, DUPLICATE_SAME_ACCESS);
+ return h;
+ }
+
+ const char *fname;
+ if (path->isEmpty())
+ fname = "NUL";
+ else
+ fname = path->c_str();
+
+ SECURITY_ATTRIBUTES sa;
+ sa.nLength = sizeof(sa);
+ sa.lpSecurityDescriptor = 0;
+ sa.bInheritHandle = TRUE;
+
+ h = CreateFile(fname, fd ? GENERIC_WRITE : GENERIC_READ, FILE_SHARE_READ,
+ &sa, fd == 0 ? OPEN_EXISTING : CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, NULL);
+ if (h == INVALID_HANDLE_VALUE) {
+ MakeErrMsg(ErrMsg, std::string(fname) + ": Can't open file for " +
+ (fd ? "input: " : "output: "));
+ }
+
+ return h;
+}
+
+/// ArgNeedsQuotes - Check whether argument needs to be quoted when calling
+/// CreateProcess.
+static bool ArgNeedsQuotes(const char *Str) {
+ return Str[0] == '\0' || strchr(Str, ' ') != 0;
+}
+
+
+/// ArgLenWithQuotes - Check whether argument needs to be quoted when calling
+/// CreateProcess and returns length of quoted arg with escaped quotes
+static unsigned int ArgLenWithQuotes(const char *Str) {
+ unsigned int len = ArgNeedsQuotes(Str) ? 2 : 0;
+
+ while (*Str != '\0') {
+ if (*Str == '\"')
+ ++len;
+
+ ++len;
+ ++Str;
+ }
+
+ return len;
+}
+
+
+bool
+Program::Execute(const Path& path,
+ const char** args,
+ const char** envp,
+ const Path** redirects,
+ unsigned memoryLimit,
+ std::string* ErrMsg) {
+ if (Data_) {
+ Win32ProcessInfo* wpi = reinterpret_cast<Win32ProcessInfo*>(Data_);
+ CloseHandle(wpi->hProcess);
+ delete wpi;
+ Data_ = 0;
+ }
+
+ if (!path.canExecute()) {
+ if (ErrMsg)
+ *ErrMsg = "program not executable";
+ return false;
+ }
+
+ // Windows wants a command line, not an array of args, to pass to the new
+ // process. We have to concatenate them all, while quoting the args that
+ // have embedded spaces (or are empty).
+
+ // First, determine the length of the command line.
+ unsigned len = 0;
+ for (unsigned i = 0; args[i]; i++) {
+ len += ArgLenWithQuotes(args[i]) + 1;
+ }
+
+ // Now build the command line.
+ char *command = reinterpret_cast<char *>(_alloca(len+1));
+ char *p = command;
+
+ for (unsigned i = 0; args[i]; i++) {
+ const char *arg = args[i];
+
+ bool needsQuoting = ArgNeedsQuotes(arg);
+ if (needsQuoting)
+ *p++ = '"';
+
+ while (*arg != '\0') {
+ if (*arg == '\"')
+ *p++ = '\\';
+
+ *p++ = *arg++;
+ }
+
+ if (needsQuoting)
+ *p++ = '"';
+ *p++ = ' ';
+ }
+
+ *p = 0;
+
+ // The pointer to the environment block for the new process.
+ char *envblock = 0;
+
+ if (envp) {
+ // An environment block consists of a null-terminated block of
+ // null-terminated strings. Convert the array of environment variables to
+ // an environment block by concatenating them.
+
+ // First, determine the length of the environment block.
+ len = 0;
+ for (unsigned i = 0; envp[i]; i++)
+ len += strlen(envp[i]) + 1;
+
+ // Now build the environment block.
+ envblock = reinterpret_cast<char *>(_alloca(len+1));
+ p = envblock;
+
+ for (unsigned i = 0; envp[i]; i++) {
+ const char *ev = envp[i];
+ size_t len = strlen(ev) + 1;
+ memcpy(p, ev, len);
+ p += len;
+ }
+
+ *p = 0;
+ }
+
+ // Create a child process.
+ STARTUPINFO si;
+ memset(&si, 0, sizeof(si));
+ si.cb = sizeof(si);
+ si.hStdInput = INVALID_HANDLE_VALUE;
+ si.hStdOutput = INVALID_HANDLE_VALUE;
+ si.hStdError = INVALID_HANDLE_VALUE;
+
+ if (redirects) {
+ si.dwFlags = STARTF_USESTDHANDLES;
+
+ si.hStdInput = RedirectIO(redirects[0], 0, ErrMsg);
+ if (si.hStdInput == INVALID_HANDLE_VALUE) {
+ MakeErrMsg(ErrMsg, "can't redirect stdin");
+ return false;
+ }
+ si.hStdOutput = RedirectIO(redirects[1], 1, ErrMsg);
+ if (si.hStdOutput == INVALID_HANDLE_VALUE) {
+ CloseHandle(si.hStdInput);
+ MakeErrMsg(ErrMsg, "can't redirect stdout");
+ return false;
+ }
+ if (redirects[1] && redirects[2] && *(redirects[1]) == *(redirects[2])) {
+ // If stdout and stderr should go to the same place, redirect stderr
+ // to the handle already open for stdout.
+ DuplicateHandle(GetCurrentProcess(), si.hStdOutput,
+ GetCurrentProcess(), &si.hStdError,
+ 0, TRUE, DUPLICATE_SAME_ACCESS);
+ } else {
+ // Just redirect stderr
+ si.hStdError = RedirectIO(redirects[2], 2, ErrMsg);
+ if (si.hStdError == INVALID_HANDLE_VALUE) {
+ CloseHandle(si.hStdInput);
+ CloseHandle(si.hStdOutput);
+ MakeErrMsg(ErrMsg, "can't redirect stderr");
+ return false;
+ }
+ }
+ }
+
+ PROCESS_INFORMATION pi;
+ memset(&pi, 0, sizeof(pi));
+
+ fflush(stdout);
+ fflush(stderr);
+ BOOL rc = CreateProcess(path.c_str(), command, NULL, NULL, TRUE, 0,
+ envblock, NULL, &si, &pi);
+ DWORD err = GetLastError();
+
+ // Regardless of whether the process got created or not, we are done with
+ // the handles we created for it to inherit.
+ CloseHandle(si.hStdInput);
+ CloseHandle(si.hStdOutput);
+ CloseHandle(si.hStdError);
+
+ // Now return an error if the process didn't get created.
+ if (!rc) {
+ SetLastError(err);
+ MakeErrMsg(ErrMsg, std::string("Couldn't execute program '") +
+ path.str() + "'");
+ return false;
+ }
+ Win32ProcessInfo* wpi = new Win32ProcessInfo;
+ wpi->hProcess = pi.hProcess;
+ wpi->dwProcessId = pi.dwProcessId;
+ Data_ = wpi;
+
+ // Make sure these get closed no matter what.
+ AutoHandle hThread(pi.hThread);
+
+ // Assign the process to a job if a memory limit is defined.
+ AutoHandle hJob(0);
+ if (memoryLimit != 0) {
+ hJob = CreateJobObject(0, 0);
+ bool success = false;
+ if (hJob != 0) {
+ JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli;
+ memset(&jeli, 0, sizeof(jeli));
+ jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_PROCESS_MEMORY;
+ jeli.ProcessMemoryLimit = uintptr_t(memoryLimit) * 1048576;
+ if (SetInformationJobObject(hJob, JobObjectExtendedLimitInformation,
+ &jeli, sizeof(jeli))) {
+ if (AssignProcessToJobObject(hJob, pi.hProcess))
+ success = true;
+ }
+ }
+ if (!success) {
+ SetLastError(GetLastError());
+ MakeErrMsg(ErrMsg, std::string("Unable to set memory limit"));
+ TerminateProcess(pi.hProcess, 1);
+ WaitForSingleObject(pi.hProcess, INFINITE);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+int
+Program::Wait(const Path &path,
+ unsigned secondsToWait,
+ std::string* ErrMsg) {
+ if (Data_ == 0) {
+ MakeErrMsg(ErrMsg, "Process not started!");
+ return -1;
+ }
+
+ Win32ProcessInfo* wpi = reinterpret_cast<Win32ProcessInfo*>(Data_);
+ HANDLE hProcess = wpi->hProcess;
+
+ // Wait for the process to terminate.
+ DWORD millisecondsToWait = INFINITE;
+ if (secondsToWait > 0)
+ millisecondsToWait = secondsToWait * 1000;
+
+ if (WaitForSingleObject(hProcess, millisecondsToWait) == WAIT_TIMEOUT) {
+ if (!TerminateProcess(hProcess, 1)) {
+ MakeErrMsg(ErrMsg, "Failed to terminate timed-out program.");
+ return -1;
+ }
+ WaitForSingleObject(hProcess, INFINITE);
+ }
+
+ // Get its exit status.
+ DWORD status;
+ BOOL rc = GetExitCodeProcess(hProcess, &status);
+ DWORD err = GetLastError();
+
+ if (!rc) {
+ SetLastError(err);
+ MakeErrMsg(ErrMsg, "Failed getting status for program.");
+ return -1;
+ }
+
+ return status;
+}
+
+bool
+Program::Kill(std::string* ErrMsg) {
+ if (Data_ == 0) {
+ MakeErrMsg(ErrMsg, "Process not started!");
+ return true;
+ }
+
+ Win32ProcessInfo* wpi = reinterpret_cast<Win32ProcessInfo*>(Data_);
+ HANDLE hProcess = wpi->hProcess;
+ if (TerminateProcess(hProcess, 1) == 0) {
+ MakeErrMsg(ErrMsg, "The process couldn't be killed!");
+ return true;
+ }
+
+ return false;
+}
+
+bool Program::ChangeStdinToBinary(){
+ int result = _setmode( _fileno(stdin), _O_BINARY );
+ return result == -1;
+}
+
+bool Program::ChangeStdoutToBinary(){
+ int result = _setmode( _fileno(stdout), _O_BINARY );
+ return result == -1;
+}
+
+bool Program::ChangeStderrToBinary(){
+ int result = _setmode( _fileno(stderr), _O_BINARY );
+ return result == -1;
+}
+
+}
--- /dev/null
+//= llvm/System/Win32/Mutex.inc - Win32 Reader/Writer Mutual Exclusion Lock =//
+//
+// 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 Win32 specific (non-pthread) RWMutex class.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic Win32 code that
+//=== is guaranteed to work on *all* Win32 variants.
+//===----------------------------------------------------------------------===//
+
+#include "Windows.h"
+
+// FIXME: Windows does not have reader-writer locks pre-Vista. If you want
+// real reader-writer locks, you a threads implementation for Windows.
+
+namespace llvm {
+using namespace sys;
+
+RWMutexImpl::RWMutexImpl() {
+ data_ = calloc(1, sizeof(CRITICAL_SECTION));
+ InitializeCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
+}
+
+RWMutexImpl::~RWMutexImpl() {
+ DeleteCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
+ free(data_);
+}
+
+bool RWMutexImpl::reader_acquire() {
+ EnterCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
+ return true;
+}
+
+bool RWMutexImpl::reader_release() {
+ LeaveCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
+ return true;
+}
+
+bool RWMutexImpl::writer_acquire() {
+ EnterCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
+ return true;
+}
+
+bool RWMutexImpl::writer_release() {
+ LeaveCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
+ return true;
+}
+
+
+}
--- /dev/null
+//===- Win32/Signals.cpp - Win32 Signals Implementation ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides the Win32 specific implementation of the Signals class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Windows.h"
+#include <stdio.h>
+#include <vector>
+#include <algorithm>
+
+#ifdef __MINGW32__
+ #include <imagehlp.h>
+#else
+ #include <dbghelp.h>
+#endif
+#include <psapi.h>
+
+#ifdef __MINGW32__
+ #if ((HAVE_LIBIMAGEHLP != 1) || (HAVE_LIBPSAPI != 1))
+ #error "libimagehlp.a & libpsapi.a should be present"
+ #endif
+#else
+ #pragma comment(lib, "psapi.lib")
+ #pragma comment(lib, "dbghelp.lib")
+#endif
+
+// Forward declare.
+static LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep);
+static BOOL WINAPI LLVMConsoleCtrlHandler(DWORD dwCtrlType);
+
+// InterruptFunction - The function to call if ctrl-c is pressed.
+static void (*InterruptFunction)() = 0;
+
+static std::vector<llvm::sys::Path> *FilesToRemove = NULL;
+static std::vector<std::pair<void(*)(void*), void*> > *CallBacksToRun = 0;
+static bool RegisteredUnhandledExceptionFilter = false;
+static bool CleanupExecuted = false;
+static bool ExitOnUnhandledExceptions = false;
+static PTOP_LEVEL_EXCEPTION_FILTER OldFilter = NULL;
+
+// Windows creates a new thread to execute the console handler when an event
+// (such as CTRL/C) occurs. This causes concurrency issues with the above
+// globals which this critical section addresses.
+static CRITICAL_SECTION CriticalSection;
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only Win32 specific code
+//=== and must not be UNIX code
+//===----------------------------------------------------------------------===//
+
+#ifdef _MSC_VER
+/// CRTReportHook - Function called on a CRT debugging event.
+static int CRTReportHook(int ReportType, char *Message, int *Return) {
+ // Don't cause a DebugBreak() on return.
+ if (Return)
+ *Return = 0;
+
+ switch (ReportType) {
+ default:
+ case _CRT_ASSERT:
+ fprintf(stderr, "CRT assert: %s\n", Message);
+ // FIXME: Is there a way to just crash? Perhaps throw to the unhandled
+ // exception code? Perhaps SetErrorMode() handles this.
+ _exit(3);
+ break;
+ case _CRT_ERROR:
+ fprintf(stderr, "CRT error: %s\n", Message);
+ // FIXME: Is there a way to just crash? Perhaps throw to the unhandled
+ // exception code? Perhaps SetErrorMode() handles this.
+ _exit(3);
+ break;
+ case _CRT_WARN:
+ fprintf(stderr, "CRT warn: %s\n", Message);
+ break;
+ }
+
+ // Don't call _CrtDbgReport.
+ return TRUE;
+}
+#endif
+
+static void RegisterHandler() {
+ if (RegisteredUnhandledExceptionFilter) {
+ EnterCriticalSection(&CriticalSection);
+ return;
+ }
+
+ // Now's the time to create the critical section. This is the first time
+ // through here, and there's only one thread.
+ InitializeCriticalSection(&CriticalSection);
+
+ // Enter it immediately. Now if someone hits CTRL/C, the console handler
+ // can't proceed until the globals are updated.
+ EnterCriticalSection(&CriticalSection);
+
+ RegisteredUnhandledExceptionFilter = true;
+ OldFilter = SetUnhandledExceptionFilter(LLVMUnhandledExceptionFilter);
+ SetConsoleCtrlHandler(LLVMConsoleCtrlHandler, TRUE);
+
+ // Environment variable to disable any kind of crash dialog.
+ if (getenv("LLVM_DISABLE_CRT_DEBUG")) {
+#ifdef _MSC_VER
+ _CrtSetReportHook(CRTReportHook);
+#endif
+ ExitOnUnhandledExceptions = true;
+ }
+
+ // IMPORTANT NOTE: Caller must call LeaveCriticalSection(&CriticalSection) or
+ // else multi-threading problems will ensue.
+}
+
+// RemoveFileOnSignal - The public API
+bool sys::RemoveFileOnSignal(const sys::Path &Filename, std::string* ErrMsg) {
+ RegisterHandler();
+
+ if (CleanupExecuted) {
+ if (ErrMsg)
+ *ErrMsg = "Process terminating -- cannot register for removal";
+ return true;
+ }
+
+ if (FilesToRemove == NULL)
+ FilesToRemove = new std::vector<sys::Path>;
+
+ FilesToRemove->push_back(Filename);
+
+ LeaveCriticalSection(&CriticalSection);
+ return false;
+}
+
+// DontRemoveFileOnSignal - The public API
+void sys::DontRemoveFileOnSignal(const sys::Path &Filename) {
+ if (FilesToRemove == NULL)
+ return;
+
+ RegisterHandler();
+
+ FilesToRemove->push_back(Filename);
+ std::vector<sys::Path>::reverse_iterator I =
+ std::find(FilesToRemove->rbegin(), FilesToRemove->rend(), Filename);
+ if (I != FilesToRemove->rend())
+ FilesToRemove->erase(I.base()-1);
+
+ LeaveCriticalSection(&CriticalSection);
+}
+
+/// PrintStackTraceOnErrorSignal - When an error signal (such as SIBABRT or
+/// SIGSEGV) is delivered to the process, print a stack trace and then exit.
+void sys::PrintStackTraceOnErrorSignal() {
+ RegisterHandler();
+ LeaveCriticalSection(&CriticalSection);
+}
+
+
+void sys::SetInterruptFunction(void (*IF)()) {
+ RegisterHandler();
+ InterruptFunction = IF;
+ LeaveCriticalSection(&CriticalSection);
+}
+
+
+/// AddSignalHandler - Add a function to be called when a signal is delivered
+/// to the process. The handler can have a cookie passed to it to identify
+/// what instance of the handler it is.
+void sys::AddSignalHandler(void (*FnPtr)(void *), void *Cookie) {
+ if (CallBacksToRun == 0)
+ CallBacksToRun = new std::vector<std::pair<void(*)(void*), void*> >();
+ CallBacksToRun->push_back(std::make_pair(FnPtr, Cookie));
+ RegisterHandler();
+ LeaveCriticalSection(&CriticalSection);
+}
+}
+
+static void Cleanup() {
+ EnterCriticalSection(&CriticalSection);
+
+ // Prevent other thread from registering new files and directories for
+ // removal, should we be executing because of the console handler callback.
+ CleanupExecuted = true;
+
+ // FIXME: open files cannot be deleted.
+
+ if (FilesToRemove != NULL)
+ while (!FilesToRemove->empty()) {
+ FilesToRemove->back().eraseFromDisk();
+ FilesToRemove->pop_back();
+ }
+
+ if (CallBacksToRun)
+ for (unsigned i = 0, e = CallBacksToRun->size(); i != e; ++i)
+ (*CallBacksToRun)[i].first((*CallBacksToRun)[i].second);
+
+ LeaveCriticalSection(&CriticalSection);
+}
+
+void llvm::sys::RunInterruptHandlers() {
+ Cleanup();
+}
+
+static LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep) {
+ Cleanup();
+
+#ifdef _WIN64
+ // TODO: provide a x64 friendly version of the following
+#else
+
+ // Initialize the STACKFRAME structure.
+ STACKFRAME StackFrame;
+ memset(&StackFrame, 0, sizeof(StackFrame));
+
+ StackFrame.AddrPC.Offset = ep->ContextRecord->Eip;
+ StackFrame.AddrPC.Mode = AddrModeFlat;
+ StackFrame.AddrStack.Offset = ep->ContextRecord->Esp;
+ StackFrame.AddrStack.Mode = AddrModeFlat;
+ StackFrame.AddrFrame.Offset = ep->ContextRecord->Ebp;
+ StackFrame.AddrFrame.Mode = AddrModeFlat;
+
+ HANDLE hProcess = GetCurrentProcess();
+ HANDLE hThread = GetCurrentThread();
+
+ // Initialize the symbol handler.
+ SymSetOptions(SYMOPT_DEFERRED_LOADS|SYMOPT_LOAD_LINES);
+ SymInitialize(hProcess, NULL, TRUE);
+
+ while (true) {
+ if (!StackWalk(IMAGE_FILE_MACHINE_I386, hProcess, hThread, &StackFrame,
+ ep->ContextRecord, NULL, SymFunctionTableAccess,
+ SymGetModuleBase, NULL)) {
+ break;
+ }
+
+ if (StackFrame.AddrFrame.Offset == 0)
+ break;
+
+ // Print the PC in hexadecimal.
+ DWORD PC = StackFrame.AddrPC.Offset;
+ fprintf(stderr, "%08lX", PC);
+
+ // Print the parameters. Assume there are four.
+ fprintf(stderr, " (0x%08lX 0x%08lX 0x%08lX 0x%08lX)",
+ StackFrame.Params[0],
+ StackFrame.Params[1], StackFrame.Params[2], StackFrame.Params[3]);
+
+ // Verify the PC belongs to a module in this process.
+ if (!SymGetModuleBase(hProcess, PC)) {
+ fputs(" <unknown module>\n", stderr);
+ continue;
+ }
+
+ // Print the symbol name.
+ char buffer[512];
+ IMAGEHLP_SYMBOL *symbol = reinterpret_cast<IMAGEHLP_SYMBOL *>(buffer);
+ memset(symbol, 0, sizeof(IMAGEHLP_SYMBOL));
+ symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
+ symbol->MaxNameLength = 512 - sizeof(IMAGEHLP_SYMBOL);
+
+ DWORD dwDisp;
+ if (!SymGetSymFromAddr(hProcess, PC, &dwDisp, symbol)) {
+ fputc('\n', stderr);
+ continue;
+ }
+
+ buffer[511] = 0;
+ if (dwDisp > 0)
+ fprintf(stderr, ", %s()+%04lu bytes(s)", symbol->Name, dwDisp);
+ else
+ fprintf(stderr, ", %s", symbol->Name);
+
+ // Print the source file and line number information.
+ IMAGEHLP_LINE line;
+ memset(&line, 0, sizeof(line));
+ line.SizeOfStruct = sizeof(line);
+ if (SymGetLineFromAddr(hProcess, PC, &dwDisp, &line)) {
+ fprintf(stderr, ", %s, line %lu", line.FileName, line.LineNumber);
+ if (dwDisp > 0)
+ fprintf(stderr, "+%04lu byte(s)", dwDisp);
+ }
+
+ fputc('\n', stderr);
+ }
+
+#endif
+
+ if (ExitOnUnhandledExceptions)
+ _exit(-3);
+
+ // Allow dialog box to pop up allowing choice to start debugger.
+ if (OldFilter)
+ return (*OldFilter)(ep);
+ else
+ return EXCEPTION_CONTINUE_SEARCH;
+}
+
+static BOOL WINAPI LLVMConsoleCtrlHandler(DWORD dwCtrlType) {
+ // We are running in our very own thread, courtesy of Windows.
+ EnterCriticalSection(&CriticalSection);
+ Cleanup();
+
+ // If an interrupt function has been set, go and run one it; otherwise,
+ // the process dies.
+ void (*IF)() = InterruptFunction;
+ InterruptFunction = 0; // Don't run it on another CTRL-C.
+
+ if (IF) {
+ // Note: if the interrupt function throws an exception, there is nothing
+ // to catch it in this thread so it will kill the process.
+ IF(); // Run it now.
+ LeaveCriticalSection(&CriticalSection);
+ return TRUE; // Don't kill the process.
+ }
+
+ // Allow normal processing to take place; i.e., the process dies.
+ LeaveCriticalSection(&CriticalSection);
+ return FALSE;
+}
--- /dev/null
+//= llvm/System/Win32/ThreadLocal.inc - Win32 Thread Local Data -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Win32 specific (non-pthread) ThreadLocal class.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic Win32 code that
+//=== is guaranteed to work on *all* Win32 variants.
+//===----------------------------------------------------------------------===//
+
+#include "Windows.h"
+#include "llvm/Support/ThreadLocal.h"
+
+namespace llvm {
+using namespace sys;
+
+ThreadLocalImpl::ThreadLocalImpl() {
+ DWORD* tls = new DWORD;
+ *tls = TlsAlloc();
+ assert(*tls != TLS_OUT_OF_INDEXES);
+ data = tls;
+}
+
+ThreadLocalImpl::~ThreadLocalImpl() {
+ DWORD* tls = static_cast<DWORD*>(data);
+ TlsFree(*tls);
+ delete tls;
+}
+
+const void* ThreadLocalImpl::getInstance() {
+ DWORD* tls = static_cast<DWORD*>(data);
+ return TlsGetValue(*tls);
+}
+
+void ThreadLocalImpl::setInstance(const void* d){
+ DWORD* tls = static_cast<DWORD*>(data);
+ int errorcode = TlsSetValue(*tls, const_cast<void*>(d));
+ assert(errorcode != 0);
+ (void)errorcode;
+}
+
+void ThreadLocalImpl::removeInstance() {
+ setInstance(0);
+}
+
+}
--- /dev/null
+//===- Win32/TimeValue.cpp - Win32 TimeValue Implementation -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides the Win32 implementation of the TimeValue class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Windows.h"
+#include <time.h>
+
+namespace llvm {
+using namespace sys;
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only Win32 specific code.
+//===----------------------------------------------------------------------===//
+
+TimeValue TimeValue::now() {
+ uint64_t ft;
+ GetSystemTimeAsFileTime(reinterpret_cast<FILETIME *>(&ft));
+
+ TimeValue t(0, 0);
+ t.fromWin32Time(ft);
+ return t;
+}
+
+std::string TimeValue::str() const {
+#ifdef __MINGW32__
+ // This ban may be lifted by either:
+ // (i) a future MinGW version other than 1.0 inherents the __time64_t type, or
+ // (ii) configure tests for either the time_t or __time64_t type.
+ time_t ourTime = time_t(this->toEpochTime());
+ struct tm *lt = ::localtime(&ourTime);
+#else
+ __time64_t ourTime = this->toEpochTime();
+ struct tm *lt = ::_localtime64(&ourTime);
+#endif
+
+ char buffer[25];
+ strftime(buffer, 25, "%a %b %d %H:%M:%S %Y", lt);
+ return std::string(buffer);
+}
+
+
+}
--- /dev/null
+//===- Win32/Win32.h - Common Win32 Include File ----------------*- 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 things specific to Win32 implementations.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic Win32 code that
+//=== is guaranteed to work on *all* Win32 variants.
+//===----------------------------------------------------------------------===//
+
+// Require at least Windows 2000 API.
+#define _WIN32_WINNT 0x0500
+#define _WIN32_IE 0x0500 // MinGW at it again.
+#define WIN32_LEAN_AND_MEAN
+
+#include "llvm/Config/config.h" // Get build system configuration settings
+#include <Windows.h>
+#include <ShlObj.h>
+#include <cassert>
+#include <string>
+
+inline bool MakeErrMsg(std::string* ErrMsg, const std::string& prefix) {
+ if (!ErrMsg)
+ return true;
+ char *buffer = NULL;
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, GetLastError(), 0, (LPSTR)&buffer, 1, NULL);
+ *ErrMsg = prefix + buffer;
+ LocalFree(buffer);
+ return true;
+}
+
+class AutoHandle {
+ HANDLE handle;
+
+public:
+ AutoHandle(HANDLE h) : handle(h) {}
+
+ ~AutoHandle() {
+ if (handle)
+ CloseHandle(handle);
+ }
+
+ operator HANDLE() {
+ return handle;
+ }
+
+ AutoHandle &operator=(HANDLE h) {
+ handle = h;
+ return *this;
+ }
+};
--- /dev/null
+//===- llvm/System/Win32/system_error.inc - Windows error_code --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides the Windows specific implementation of the error_code
+// and error_condition classes.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic Windows code that
+//=== is guaranteed to work on *all* Windows variants.
+//===----------------------------------------------------------------------===//
+
+#include <Windows.h>
+#include <WinError.h>
+
+using namespace llvm;
+
+std::string
+_system_error_category::message(int ev) const {
+ LPVOID lpMsgBuf = 0;
+ DWORD retval = ::FormatMessageA(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ ev,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+ (LPSTR) &lpMsgBuf,
+ 0,
+ NULL);
+ if (retval == 0) {
+ ::LocalFree(lpMsgBuf);
+ return std::string("Unknown error");
+ }
+
+ std::string str( static_cast<LPCSTR>(lpMsgBuf) );
+ ::LocalFree(lpMsgBuf);
+
+ while (str.size()
+ && (str[str.size()-1] == '\n' || str[str.size()-1] == '\r'))
+ str.erase( str.size()-1 );
+ if (str.size() && str[str.size()-1] == '.')
+ str.erase( str.size()-1 );
+ return str;
+}
+
+// I'd rather not double the line count of the following.
+#define MAP_ERR_TO_COND(x, y) case x: return make_error_condition(errc::y)
+
+error_condition
+_system_error_category::default_error_condition(int ev) const {
+ switch (ev) {
+ MAP_ERR_TO_COND(0, success);
+ // Windows system -> posix_errno decode table ---------------------------//
+ // see WinError.h comments for descriptions of errors
+ MAP_ERR_TO_COND(ERROR_ACCESS_DENIED, permission_denied);
+ MAP_ERR_TO_COND(ERROR_ALREADY_EXISTS, file_exists);
+ MAP_ERR_TO_COND(ERROR_BAD_UNIT, no_such_device);
+ MAP_ERR_TO_COND(ERROR_BUFFER_OVERFLOW, filename_too_long);
+ MAP_ERR_TO_COND(ERROR_BUSY, device_or_resource_busy);
+ MAP_ERR_TO_COND(ERROR_BUSY_DRIVE, device_or_resource_busy);
+ MAP_ERR_TO_COND(ERROR_CANNOT_MAKE, permission_denied);
+ MAP_ERR_TO_COND(ERROR_CANTOPEN, io_error);
+ MAP_ERR_TO_COND(ERROR_CANTREAD, io_error);
+ MAP_ERR_TO_COND(ERROR_CANTWRITE, io_error);
+ MAP_ERR_TO_COND(ERROR_CURRENT_DIRECTORY, permission_denied);
+ MAP_ERR_TO_COND(ERROR_DEV_NOT_EXIST, no_such_device);
+ MAP_ERR_TO_COND(ERROR_DEVICE_IN_USE, device_or_resource_busy);
+ MAP_ERR_TO_COND(ERROR_DIR_NOT_EMPTY, directory_not_empty);
+ MAP_ERR_TO_COND(ERROR_DIRECTORY, invalid_argument);
+ MAP_ERR_TO_COND(ERROR_DISK_FULL, no_space_on_device);
+ MAP_ERR_TO_COND(ERROR_FILE_EXISTS, file_exists);
+ MAP_ERR_TO_COND(ERROR_FILE_NOT_FOUND, no_such_file_or_directory);
+ MAP_ERR_TO_COND(ERROR_HANDLE_DISK_FULL, no_space_on_device);
+ MAP_ERR_TO_COND(ERROR_INVALID_ACCESS, permission_denied);
+ MAP_ERR_TO_COND(ERROR_INVALID_DRIVE, no_such_device);
+ MAP_ERR_TO_COND(ERROR_INVALID_FUNCTION, function_not_supported);
+ MAP_ERR_TO_COND(ERROR_INVALID_HANDLE, invalid_argument);
+ MAP_ERR_TO_COND(ERROR_INVALID_NAME, invalid_argument);
+ MAP_ERR_TO_COND(ERROR_LOCK_VIOLATION, no_lock_available);
+ MAP_ERR_TO_COND(ERROR_LOCKED, no_lock_available);
+ MAP_ERR_TO_COND(ERROR_NEGATIVE_SEEK, invalid_argument);
+ MAP_ERR_TO_COND(ERROR_NOACCESS, permission_denied);
+ MAP_ERR_TO_COND(ERROR_NOT_ENOUGH_MEMORY, not_enough_memory);
+ MAP_ERR_TO_COND(ERROR_NOT_READY, resource_unavailable_try_again);
+ MAP_ERR_TO_COND(ERROR_NOT_SAME_DEVICE, cross_device_link);
+ MAP_ERR_TO_COND(ERROR_OPEN_FAILED, io_error);
+ MAP_ERR_TO_COND(ERROR_OPEN_FILES, device_or_resource_busy);
+ MAP_ERR_TO_COND(ERROR_OPERATION_ABORTED, operation_canceled);
+ MAP_ERR_TO_COND(ERROR_OUTOFMEMORY, not_enough_memory);
+ MAP_ERR_TO_COND(ERROR_PATH_NOT_FOUND, no_such_file_or_directory);
+ MAP_ERR_TO_COND(ERROR_READ_FAULT, io_error);
+ MAP_ERR_TO_COND(ERROR_RETRY, resource_unavailable_try_again);
+ MAP_ERR_TO_COND(ERROR_SEEK, io_error);
+ MAP_ERR_TO_COND(ERROR_SHARING_VIOLATION, permission_denied);
+ MAP_ERR_TO_COND(ERROR_TOO_MANY_OPEN_FILES, too_many_files_open);
+ MAP_ERR_TO_COND(ERROR_WRITE_FAULT, io_error);
+ MAP_ERR_TO_COND(ERROR_WRITE_PROTECT, permission_denied);
+ MAP_ERR_TO_COND(ERROR_SEM_TIMEOUT, timed_out);
+ MAP_ERR_TO_COND(WSAEACCES, permission_denied);
+ MAP_ERR_TO_COND(WSAEADDRINUSE, address_in_use);
+ MAP_ERR_TO_COND(WSAEADDRNOTAVAIL, address_not_available);
+ MAP_ERR_TO_COND(WSAEAFNOSUPPORT, address_family_not_supported);
+ MAP_ERR_TO_COND(WSAEALREADY, connection_already_in_progress);
+ MAP_ERR_TO_COND(WSAEBADF, bad_file_descriptor);
+ MAP_ERR_TO_COND(WSAECONNABORTED, connection_aborted);
+ MAP_ERR_TO_COND(WSAECONNREFUSED, connection_refused);
+ MAP_ERR_TO_COND(WSAECONNRESET, connection_reset);
+ MAP_ERR_TO_COND(WSAEDESTADDRREQ, destination_address_required);
+ MAP_ERR_TO_COND(WSAEFAULT, bad_address);
+ MAP_ERR_TO_COND(WSAEHOSTUNREACH, host_unreachable);
+ MAP_ERR_TO_COND(WSAEINPROGRESS, operation_in_progress);
+ MAP_ERR_TO_COND(WSAEINTR, interrupted);
+ MAP_ERR_TO_COND(WSAEINVAL, invalid_argument);
+ MAP_ERR_TO_COND(WSAEISCONN, already_connected);
+ MAP_ERR_TO_COND(WSAEMFILE, too_many_files_open);
+ MAP_ERR_TO_COND(WSAEMSGSIZE, message_size);
+ MAP_ERR_TO_COND(WSAENAMETOOLONG, filename_too_long);
+ MAP_ERR_TO_COND(WSAENETDOWN, network_down);
+ MAP_ERR_TO_COND(WSAENETRESET, network_reset);
+ MAP_ERR_TO_COND(WSAENETUNREACH, network_unreachable);
+ MAP_ERR_TO_COND(WSAENOBUFS, no_buffer_space);
+ MAP_ERR_TO_COND(WSAENOPROTOOPT, no_protocol_option);
+ MAP_ERR_TO_COND(WSAENOTCONN, not_connected);
+ MAP_ERR_TO_COND(WSAENOTSOCK, not_a_socket);
+ MAP_ERR_TO_COND(WSAEOPNOTSUPP, operation_not_supported);
+ MAP_ERR_TO_COND(WSAEPROTONOSUPPORT, protocol_not_supported);
+ MAP_ERR_TO_COND(WSAEPROTOTYPE, wrong_protocol_type);
+ MAP_ERR_TO_COND(WSAETIMEDOUT, timed_out);
+ MAP_ERR_TO_COND(WSAEWOULDBLOCK, operation_would_block);
+ default: return error_condition(ev, system_category());
+ }
+}
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Format.h"
-#include "llvm/System/Program.h"
-#include "llvm/System/Process.h"
+#include "llvm/Support/Program.h"
+#include "llvm/Support/Process.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Config/config.h"
--- /dev/null
+//===---------------------- system_error.cpp ------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This was lifted from libc++ and modified for C++03.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/system_error.h"
+#include "llvm/Support/Errno.h"
+#include <string>
+#include <cstring>
+
+namespace llvm {
+
+// class error_category
+
+error_category::error_category() {
+}
+
+error_category::~error_category() {
+}
+
+error_condition
+error_category::default_error_condition(int ev) const {
+ return error_condition(ev, *this);
+}
+
+bool
+error_category::equivalent(int code, const error_condition& condition) const {
+ return default_error_condition(code) == condition;
+}
+
+bool
+error_category::equivalent(const error_code& code, int condition) const {
+ return *this == code.category() && code.value() == condition;
+}
+
+std::string
+_do_message::message(int ev) const {
+ return std::string(sys::StrError(ev));
+}
+
+class _generic_error_category : public _do_message {
+public:
+ virtual const char* name() const;
+ virtual std::string message(int ev) const;
+};
+
+const char*
+_generic_error_category::name() const {
+ return "generic";
+}
+
+std::string
+_generic_error_category::message(int ev) const {
+#ifdef ELAST
+ if (ev > ELAST)
+ return std::string("unspecified generic_category error");
+#endif // ELAST
+ return _do_message::message(ev);
+}
+
+const error_category&
+generic_category() {
+ static _generic_error_category s;
+ return s;
+}
+
+class _system_error_category : public _do_message {
+public:
+ virtual const char* name() const;
+ virtual std::string message(int ev) const;
+ virtual error_condition default_error_condition(int ev) const;
+};
+
+const char*
+_system_error_category::name() const {
+ return "system";
+}
+
+// std::string _system_error_category::message(int ev) const {
+// Is in Platform/system_error.inc
+
+// error_condition _system_error_category::default_error_condition(int ev) const
+// Is in Platform/system_error.inc
+
+const error_category&
+system_category() {
+ static _system_error_category s;
+ return s;
+}
+
+// error_condition
+
+std::string
+error_condition::message() const {
+ return _cat_->message(_val_);
+}
+
+// error_code
+
+std::string
+error_code::message() const {
+ return _cat_->message(_val_);
+}
+
+} // end namespace llvm
+
+// Include the truly platform-specific parts of this class.
+#if defined(LLVM_ON_UNIX)
+#include "Unix/system_error.inc"
+#endif
+#if defined(LLVM_ON_WIN32)
+#include "Windows/system_error.inc"
+#endif
+++ /dev/null
-//===- Alarm.cpp - Alarm Generation Support ---------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the Alarm functionality
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/System/Alarm.h"
-#include "llvm/Config/config.h"
-
-namespace llvm {
-using namespace sys;
-
-//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only TRULY operating system
-//=== independent code.
-//===----------------------------------------------------------------------===//
-
-}
-
-// Include the platform-specific parts of this class.
-#ifdef LLVM_ON_UNIX
-#include "Unix/Alarm.inc"
-#endif
-#ifdef LLVM_ON_WIN32
-#include "Win32/Alarm.inc"
-#endif
+++ /dev/null
-//===-- Atomic.cpp - Atomic Operations --------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This header file implements atomic operations.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/System/Atomic.h"
-#include "llvm/Config/config.h"
-
-using namespace llvm;
-
-#if defined(_MSC_VER)
-#include <windows.h>
-#undef MemoryFence
-#endif
-
-void sys::MemoryFence() {
-#if LLVM_MULTITHREADED==0
- return;
-#else
-# if defined(__GNUC__)
- __sync_synchronize();
-# elif defined(_MSC_VER)
- MemoryBarrier();
-# else
-# error No memory fence implementation for your platform!
-# endif
-#endif
-}
-
-sys::cas_flag sys::CompareAndSwap(volatile sys::cas_flag* ptr,
- sys::cas_flag new_value,
- sys::cas_flag old_value) {
-#if LLVM_MULTITHREADED==0
- sys::cas_flag result = *ptr;
- if (result == old_value)
- *ptr = new_value;
- return result;
-#elif defined(__GNUC__)
- return __sync_val_compare_and_swap(ptr, old_value, new_value);
-#elif defined(_MSC_VER)
- return InterlockedCompareExchange(ptr, new_value, old_value);
-#else
-# error No compare-and-swap implementation for your platform!
-#endif
-}
-
-sys::cas_flag sys::AtomicIncrement(volatile sys::cas_flag* ptr) {
-#if LLVM_MULTITHREADED==0
- ++(*ptr);
- return *ptr;
-#elif defined(__GNUC__)
- return __sync_add_and_fetch(ptr, 1);
-#elif defined(_MSC_VER)
- return InterlockedIncrement(ptr);
-#else
-# error No atomic increment implementation for your platform!
-#endif
-}
-
-sys::cas_flag sys::AtomicDecrement(volatile sys::cas_flag* ptr) {
-#if LLVM_MULTITHREADED==0
- --(*ptr);
- return *ptr;
-#elif defined(__GNUC__)
- return __sync_sub_and_fetch(ptr, 1);
-#elif defined(_MSC_VER)
- return InterlockedDecrement(ptr);
-#else
-# error No atomic decrement implementation for your platform!
-#endif
-}
-
-sys::cas_flag sys::AtomicAdd(volatile sys::cas_flag* ptr, sys::cas_flag val) {
-#if LLVM_MULTITHREADED==0
- *ptr += val;
- return *ptr;
-#elif defined(__GNUC__)
- return __sync_add_and_fetch(ptr, val);
-#elif defined(_MSC_VER)
- return InterlockedExchangeAdd(ptr, val) + val;
-#else
-# error No atomic add implementation for your platform!
-#endif
-}
-
-sys::cas_flag sys::AtomicMul(volatile sys::cas_flag* ptr, sys::cas_flag val) {
- sys::cas_flag original, result;
- do {
- original = *ptr;
- result = original * val;
- } while (sys::CompareAndSwap(ptr, result, original) != original);
-
- return result;
-}
-
-sys::cas_flag sys::AtomicDiv(volatile sys::cas_flag* ptr, sys::cas_flag val) {
- sys::cas_flag original, result;
- do {
- original = *ptr;
- result = original / val;
- } while (sys::CompareAndSwap(ptr, result, original) != original);
-
- return result;
-}
+++ /dev/null
-set(LLVM_REQUIRES_RTTI 1)
-if( MINGW )
- set(LLVM_REQUIRES_EH 1)
-endif()
-
-add_llvm_library(LLVMSystem
- Alarm.cpp
- Atomic.cpp
- Disassembler.cpp
- DynamicLibrary.cpp
- Errno.cpp
- Host.cpp
- IncludeFile.cpp
- Memory.cpp
- Mutex.cpp
- Path.cpp
- Process.cpp
- Program.cpp
- RWMutex.cpp
- SearchForAddressOfSpecialSymbol.cpp
- Signals.cpp
- system_error.cpp
- ThreadLocal.cpp
- Threading.cpp
- TimeValue.cpp
- Valgrind.cpp
- Unix/Alarm.inc
- Unix/Host.inc
- Unix/Memory.inc
- Unix/Mutex.inc
- Unix/Path.inc
- Unix/Process.inc
- Unix/Program.inc
- Unix/RWMutex.inc
- Unix/Signals.inc
- Unix/system_error.inc
- Unix/ThreadLocal.inc
- Unix/TimeValue.inc
- Win32/Alarm.inc
- Win32/DynamicLibrary.inc
- Win32/Host.inc
- Win32/Memory.inc
- Win32/Mutex.inc
- Win32/Path.inc
- Win32/Process.inc
- Win32/Program.inc
- Win32/RWMutex.inc
- Win32/Signals.inc
- Win32/system_error.inc
- Win32/ThreadLocal.inc
- Win32/TimeValue.inc
- )
+++ /dev/null
-//===- lib/System/Disassembler.cpp ------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the necessary glue to call external disassembler
-// libraries.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Config/config.h"
-#include "llvm/System/Disassembler.h"
-
-#include <cassert>
-#include <iomanip>
-#include <string>
-#include <sstream>
-
-#if USE_UDIS86
-#include <udis86.h>
-#endif
-
-using namespace llvm;
-
-bool llvm::sys::hasDisassembler()
-{
-#if defined (__i386__) || defined (__amd64__) || defined (__x86_64__)
- // We have option to enable udis86 library.
-# if USE_UDIS86
- return true;
-#else
- return false;
-#endif
-#else
- return false;
-#endif
-}
-
-std::string llvm::sys::disassembleBuffer(uint8_t* start, size_t length,
- uint64_t pc) {
- std::stringstream res;
-
-#if (defined (__i386__) || defined (__amd64__) || defined (__x86_64__)) \
- && USE_UDIS86
- unsigned bits;
-# if defined(__i386__)
- bits = 32;
-# else
- bits = 64;
-# endif
-
- ud_t ud_obj;
-
- ud_init(&ud_obj);
- ud_set_input_buffer(&ud_obj, start, length);
- ud_set_mode(&ud_obj, bits);
- ud_set_pc(&ud_obj, pc);
- ud_set_syntax(&ud_obj, UD_SYN_ATT);
-
- res << std::setbase(16)
- << std::setw(bits/4);
-
- while (ud_disassemble(&ud_obj)) {
- res << ud_insn_off(&ud_obj) << ":\t" << ud_insn_asm(&ud_obj) << "\n";
- }
-#else
- res << "No disassembler available. See configure help for options.\n";
-#endif
-
- return res.str();
-}
+++ /dev/null
-//===-- DynamicLibrary.cpp - Runtime link/load libraries --------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This header file implements the operating system DynamicLibrary concept.
-//
-// FIXME: This file leaks the ExplicitSymbols and OpenedHandles vector, and is
-// not thread safe!
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/System/DynamicLibrary.h"
-#include "llvm/System/Mutex.h"
-#include "llvm/Config/config.h"
-#include <cstdio>
-#include <cstring>
-#include <map>
-#include <vector>
-
-// Collection of symbol name/value pairs to be searched prior to any libraries.
-static std::map<std::string, void*> *ExplicitSymbols = 0;
-
-namespace {
-
-struct ExplicitSymbolsDeleter {
- ~ExplicitSymbolsDeleter() {
- if (ExplicitSymbols)
- delete ExplicitSymbols;
- }
-};
-
-}
-
-static ExplicitSymbolsDeleter Dummy;
-
-void llvm::sys::DynamicLibrary::AddSymbol(const char* symbolName,
- void *symbolValue) {
- if (ExplicitSymbols == 0)
- ExplicitSymbols = new std::map<std::string, void*>();
- (*ExplicitSymbols)[symbolName] = symbolValue;
-}
-
-#ifdef LLVM_ON_WIN32
-
-#include "Win32/DynamicLibrary.inc"
-
-#else
-
-#if HAVE_DLFCN_H
-#include <dlfcn.h>
-using namespace llvm;
-using namespace llvm::sys;
-
-//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only TRULY operating system
-//=== independent code.
-//===----------------------------------------------------------------------===//
-
-static SmartMutex<true>* HandlesMutex;
-static std::vector<void *> *OpenedHandles = 0;
-
-static bool InitializeMutex() {
- HandlesMutex = new SmartMutex<true>;
- return HandlesMutex != 0;
-}
-
-static bool EnsureMutexInitialized() {
- static bool result = InitializeMutex();
- return result;
-}
-
-
-bool DynamicLibrary::LoadLibraryPermanently(const char *Filename,
- std::string *ErrMsg) {
- void *H = dlopen(Filename, RTLD_LAZY|RTLD_GLOBAL);
- if (H == 0) {
- if (ErrMsg) *ErrMsg = dlerror();
- return true;
- }
-#ifdef __CYGWIN__
- // Cygwin searches symbols only in the main
- // with the handle of dlopen(NULL, RTLD_GLOBAL).
- if (Filename == NULL)
- H = RTLD_DEFAULT;
-#endif
- EnsureMutexInitialized();
- SmartScopedLock<true> Lock(*HandlesMutex);
- if (OpenedHandles == 0)
- OpenedHandles = new std::vector<void *>();
- OpenedHandles->push_back(H);
- return false;
-}
-#else
-
-using namespace llvm;
-using namespace llvm::sys;
-
-bool DynamicLibrary::LoadLibraryPermanently(const char *Filename,
- std::string *ErrMsg) {
- if (ErrMsg) *ErrMsg = "dlopen() not supported on this platform";
- return true;
-}
-#endif
-
-namespace llvm {
-void *SearchForAddressOfSpecialSymbol(const char* symbolName);
-}
-
-void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) {
- // First check symbols added via AddSymbol().
- if (ExplicitSymbols) {
- std::map<std::string, void *>::iterator I =
- ExplicitSymbols->find(symbolName);
- std::map<std::string, void *>::iterator E = ExplicitSymbols->end();
-
- if (I != E)
- return I->second;
- }
-
-#if HAVE_DLFCN_H
- // Now search the libraries.
- EnsureMutexInitialized();
- SmartScopedLock<true> Lock(*HandlesMutex);
- if (OpenedHandles) {
- for (std::vector<void *>::iterator I = OpenedHandles->begin(),
- E = OpenedHandles->end(); I != E; ++I) {
- //lt_ptr ptr = lt_dlsym(*I, symbolName);
- void *ptr = dlsym(*I, symbolName);
- if (ptr) {
- return ptr;
- }
- }
- }
-#endif
-
- if (void *Result = llvm::SearchForAddressOfSpecialSymbol(symbolName))
- return Result;
-
-// This macro returns the address of a well-known, explicit symbol
-#define EXPLICIT_SYMBOL(SYM) \
- if (!strcmp(symbolName, #SYM)) return &SYM
-
-// On linux we have a weird situation. The stderr/out/in symbols are both
-// macros and global variables because of standards requirements. So, we
-// boldly use the EXPLICIT_SYMBOL macro without checking for a #define first.
-#if defined(__linux__)
- {
- EXPLICIT_SYMBOL(stderr);
- EXPLICIT_SYMBOL(stdout);
- EXPLICIT_SYMBOL(stdin);
- }
-#else
- // For everything else, we want to check to make sure the symbol isn't defined
- // as a macro before using EXPLICIT_SYMBOL.
- {
-#ifndef stdin
- EXPLICIT_SYMBOL(stdin);
-#endif
-#ifndef stdout
- EXPLICIT_SYMBOL(stdout);
-#endif
-#ifndef stderr
- EXPLICIT_SYMBOL(stderr);
-#endif
- }
-#endif
-#undef EXPLICIT_SYMBOL
-
- return 0;
-}
-
-#endif // LLVM_ON_WIN32
+++ /dev/null
-//===- Errno.cpp - errno support --------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the errno wrappers.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/System/Errno.h"
-#include "llvm/Config/config.h" // Get autoconf configuration settings
-
-#if HAVE_STRING_H
-#include <string.h>
-
-#if HAVE_ERRNO_H
-#include <errno.h>
-#endif
-
-//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only TRULY operating system
-//=== independent code.
-//===----------------------------------------------------------------------===//
-
-namespace llvm {
-namespace sys {
-
-#if HAVE_ERRNO_H
-std::string StrError() {
- return StrError(errno);
-}
-#endif // HAVE_ERRNO_H
-
-std::string StrError(int errnum) {
- const int MaxErrStrLen = 2000;
- char buffer[MaxErrStrLen];
- buffer[0] = '\0';
- char* str = buffer;
-#ifdef HAVE_STRERROR_R
- // strerror_r is thread-safe.
- if (errnum)
-# if defined(__GLIBC__) && defined(_GNU_SOURCE)
- // glibc defines its own incompatible version of strerror_r
- // which may not use the buffer supplied.
- str = strerror_r(errnum,buffer,MaxErrStrLen-1);
-# else
- strerror_r(errnum,buffer,MaxErrStrLen-1);
-# endif
-#elif defined(HAVE_STRERROR_S) // Windows.
- if (errnum)
- strerror_s(buffer, errnum);
-#elif defined(HAVE_STRERROR)
- // Copy the thread un-safe result of strerror into
- // the buffer as fast as possible to minimize impact
- // of collision of strerror in multiple threads.
- if (errnum)
- strncpy(buffer,strerror(errnum),MaxErrStrLen-1);
- buffer[MaxErrStrLen-1] = '\0';
-#else
- // Strange that this system doesn't even have strerror
- // but, oh well, just use a generic message
- sprintf(buffer, "Error #%d", errnum);
-#endif
- return str;
-}
-
-} // namespace sys
-} // namespace llvm
-
-#endif // HAVE_STRING_H
+++ /dev/null
-//===-- Host.cpp - Implement OS Host Concept --------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This header file implements the operating system Host concept.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/System/Host.h"
-#include "llvm/Config/config.h"
-#include <string.h>
-
-// Include the platform-specific parts of this class.
-#ifdef LLVM_ON_UNIX
-#include "Unix/Host.inc"
-#endif
-#ifdef LLVM_ON_WIN32
-#include "Win32/Host.inc"
-#endif
-#ifdef _MSC_VER
-#include <intrin.h>
-#endif
-
-//===----------------------------------------------------------------------===//
-//
-// Implementations of the CPU detection routines
-//
-//===----------------------------------------------------------------------===//
-
-using namespace llvm;
-
-#if defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)\
- || defined(__x86_64__) || defined(_M_AMD64) || defined (_M_X64)
-
-/// GetX86CpuIDAndInfo - Execute the specified cpuid and return the 4 values in the
-/// specified arguments. If we can't run cpuid on the host, return true.
-static bool GetX86CpuIDAndInfo(unsigned value, unsigned *rEAX,
- unsigned *rEBX, unsigned *rECX, unsigned *rEDX) {
-#if defined(__x86_64__) || defined(_M_AMD64) || defined (_M_X64)
- #if defined(__GNUC__)
- // gcc doesn't know cpuid would clobber ebx/rbx. Preseve it manually.
- asm ("movq\t%%rbx, %%rsi\n\t"
- "cpuid\n\t"
- "xchgq\t%%rbx, %%rsi\n\t"
- : "=a" (*rEAX),
- "=S" (*rEBX),
- "=c" (*rECX),
- "=d" (*rEDX)
- : "a" (value));
- return false;
- #elif defined(_MSC_VER)
- int registers[4];
- __cpuid(registers, value);
- *rEAX = registers[0];
- *rEBX = registers[1];
- *rECX = registers[2];
- *rEDX = registers[3];
- return false;
- #endif
-#elif defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)
- #if defined(__GNUC__)
- asm ("movl\t%%ebx, %%esi\n\t"
- "cpuid\n\t"
- "xchgl\t%%ebx, %%esi\n\t"
- : "=a" (*rEAX),
- "=S" (*rEBX),
- "=c" (*rECX),
- "=d" (*rEDX)
- : "a" (value));
- return false;
- #elif defined(_MSC_VER)
- __asm {
- mov eax,value
- cpuid
- mov esi,rEAX
- mov dword ptr [esi],eax
- mov esi,rEBX
- mov dword ptr [esi],ebx
- mov esi,rECX
- mov dword ptr [esi],ecx
- mov esi,rEDX
- mov dword ptr [esi],edx
- }
- return false;
- #endif
-#endif
- return true;
-}
-
-static void DetectX86FamilyModel(unsigned EAX, unsigned &Family,
- unsigned &Model) {
- Family = (EAX >> 8) & 0xf; // Bits 8 - 11
- Model = (EAX >> 4) & 0xf; // Bits 4 - 7
- if (Family == 6 || Family == 0xf) {
- if (Family == 0xf)
- // Examine extended family ID if family ID is F.
- Family += (EAX >> 20) & 0xff; // Bits 20 - 27
- // Examine extended model ID if family ID is 6 or F.
- Model += ((EAX >> 16) & 0xf) << 4; // Bits 16 - 19
- }
-}
-
-std::string sys::getHostCPUName() {
- unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
- if (GetX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX))
- return "generic";
- unsigned Family = 0;
- unsigned Model = 0;
- DetectX86FamilyModel(EAX, Family, Model);
-
- bool HasSSE3 = (ECX & 0x1);
- GetX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
- bool Em64T = (EDX >> 29) & 0x1;
-
- union {
- unsigned u[3];
- char c[12];
- } text;
-
- GetX86CpuIDAndInfo(0, &EAX, text.u+0, text.u+2, text.u+1);
- if (memcmp(text.c, "GenuineIntel", 12) == 0) {
- switch (Family) {
- case 3:
- return "i386";
- case 4:
- switch (Model) {
- case 0: // Intel486 DX processors
- case 1: // Intel486 DX processors
- case 2: // Intel486 SX processors
- case 3: // Intel487 processors, IntelDX2 OverDrive processors,
- // IntelDX2 processors
- case 4: // Intel486 SL processor
- case 5: // IntelSX2 processors
- case 7: // Write-Back Enhanced IntelDX2 processors
- case 8: // IntelDX4 OverDrive processors, IntelDX4 processors
- default: return "i486";
- }
- case 5:
- switch (Model) {
- case 1: // Pentium OverDrive processor for Pentium processor (60, 66),
- // Pentium processors (60, 66)
- case 2: // Pentium OverDrive processor for Pentium processor (75, 90,
- // 100, 120, 133), Pentium processors (75, 90, 100, 120, 133,
- // 150, 166, 200)
- case 3: // Pentium OverDrive processors for Intel486 processor-based
- // systems
- return "pentium";
-
- case 4: // Pentium OverDrive processor with MMX technology for Pentium
- // processor (75, 90, 100, 120, 133), Pentium processor with
- // MMX technology (166, 200)
- return "pentium-mmx";
-
- default: return "pentium";
- }
- case 6:
- switch (Model) {
- case 1: // Pentium Pro processor
- return "pentiumpro";
-
- case 3: // Intel Pentium II OverDrive processor, Pentium II processor,
- // model 03
- case 5: // Pentium II processor, model 05, Pentium II Xeon processor,
- // model 05, and Intel Celeron processor, model 05
- case 6: // Celeron processor, model 06
- return "pentium2";
-
- case 7: // Pentium III processor, model 07, and Pentium III Xeon
- // processor, model 07
- case 8: // Pentium III processor, model 08, Pentium III Xeon processor,
- // model 08, and Celeron processor, model 08
- case 10: // Pentium III Xeon processor, model 0Ah
- case 11: // Pentium III processor, model 0Bh
- return "pentium3";
-
- case 9: // Intel Pentium M processor, Intel Celeron M processor model 09.
- case 13: // Intel Pentium M processor, Intel Celeron M processor, model
- // 0Dh. All processors are manufactured using the 90 nm process.
- return "pentium-m";
-
- case 14: // Intel Core Duo processor, Intel Core Solo processor, model
- // 0Eh. All processors are manufactured using the 65 nm process.
- return "yonah";
-
- case 15: // Intel Core 2 Duo processor, Intel Core 2 Duo mobile
- // processor, Intel Core 2 Quad processor, Intel Core 2 Quad
- // mobile processor, Intel Core 2 Extreme processor, Intel
- // Pentium Dual-Core processor, Intel Xeon processor, model
- // 0Fh. All processors are manufactured using the 65 nm process.
- case 22: // Intel Celeron processor model 16h. All processors are
- // manufactured using the 65 nm process
- return "core2";
-
- case 21: // Intel EP80579 Integrated Processor and Intel EP80579
- // Integrated Processor with Intel QuickAssist Technology
- return "i686"; // FIXME: ???
-
- case 23: // Intel Core 2 Extreme processor, Intel Xeon processor, model
- // 17h. All processors are manufactured using the 45 nm process.
- //
- // 45nm: Penryn , Wolfdale, Yorkfield (XE)
- return "penryn";
-
- case 26: // Intel Core i7 processor and Intel Xeon processor. All
- // processors are manufactured using the 45 nm process.
- case 29: // Intel Xeon processor MP. All processors are manufactured using
- // the 45 nm process.
- case 30: // Intel(R) Core(TM) i7 CPU 870 @ 2.93GHz.
- // As found in a Summer 2010 model iMac.
- case 37: // Intel Core i7, laptop version.
- return "corei7";
-
- case 28: // Intel Atom processor. All processors are manufactured using
- // the 45 nm process
- return "atom";
-
- default: return "i686";
- }
- case 15: {
- switch (Model) {
- case 0: // Pentium 4 processor, Intel Xeon processor. All processors are
- // model 00h and manufactured using the 0.18 micron process.
- case 1: // Pentium 4 processor, Intel Xeon processor, Intel Xeon
- // processor MP, and Intel Celeron processor. All processors are
- // model 01h and manufactured using the 0.18 micron process.
- case 2: // Pentium 4 processor, Mobile Intel Pentium 4 processor - M,
- // Intel Xeon processor, Intel Xeon processor MP, Intel Celeron
- // processor, and Mobile Intel Celeron processor. All processors
- // are model 02h and manufactured using the 0.13 micron process.
- return (Em64T) ? "x86-64" : "pentium4";
-
- case 3: // Pentium 4 processor, Intel Xeon processor, Intel Celeron D
- // processor. All processors are model 03h and manufactured using
- // the 90 nm process.
- case 4: // Pentium 4 processor, Pentium 4 processor Extreme Edition,
- // Pentium D processor, Intel Xeon processor, Intel Xeon
- // processor MP, Intel Celeron D processor. All processors are
- // model 04h and manufactured using the 90 nm process.
- case 6: // Pentium 4 processor, Pentium D processor, Pentium processor
- // Extreme Edition, Intel Xeon processor, Intel Xeon processor
- // MP, Intel Celeron D processor. All processors are model 06h
- // and manufactured using the 65 nm process.
- return (Em64T) ? "nocona" : "prescott";
-
- default:
- return (Em64T) ? "x86-64" : "pentium4";
- }
- }
-
- default:
- return "generic";
- }
- } else if (memcmp(text.c, "AuthenticAMD", 12) == 0) {
- // FIXME: this poorly matches the generated SubtargetFeatureKV table. There
- // appears to be no way to generate the wide variety of AMD-specific targets
- // from the information returned from CPUID.
- switch (Family) {
- case 4:
- return "i486";
- case 5:
- switch (Model) {
- case 6:
- case 7: return "k6";
- case 8: return "k6-2";
- case 9:
- case 13: return "k6-3";
- default: return "pentium";
- }
- case 6:
- switch (Model) {
- case 4: return "athlon-tbird";
- case 6:
- case 7:
- case 8: return "athlon-mp";
- case 10: return "athlon-xp";
- default: return "athlon";
- }
- case 15:
- if (HasSSE3)
- return "k8-sse3";
- switch (Model) {
- case 1: return "opteron";
- case 5: return "athlon-fx"; // also opteron
- default: return "athlon64";
- }
- case 16:
- return "amdfam10";
- default:
- return "generic";
- }
- }
- return "generic";
-}
-#else
-std::string sys::getHostCPUName() {
- return "generic";
-}
-#endif
-
-bool sys::getHostCPUFeatures(StringMap<bool> &Features){
- return false;
-}
+++ /dev/null
-//===- lib/System/IncludeFile.cpp - Ensure Linking Of Implementation -----===//
-//
-// 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 IncludeFile constructor.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/System/IncludeFile.h"
-
-using namespace llvm;
-
-// This constructor is used to ensure linking of other modules. See the
-// llvm/System/IncludeFile.h header for details.
-IncludeFile::IncludeFile(const void*) {}
+++ /dev/null
-##===- lib/System/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 = LLVMSystem
-BUILD_ARCHIVE = 1
-REQUIRES_RTTI = 1
-
-EXTRA_DIST = Unix Win32 README.txt
-
-include $(LEVEL)/Makefile.common
-
-CompileCommonOpts := $(filter-out -pedantic,$(CompileCommonOpts))
-CompileCommonOpts := $(filter-out -Wno-long-long,$(CompileCommonOpts))
+++ /dev/null
-//===- Memory.cpp - Memory Handling Support ---------------------*- 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 some helpful functions for allocating memory and dealing
-// with memory mapped files
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/System/Memory.h"
-#include "llvm/System/Valgrind.h"
-#include "llvm/Config/config.h"
-
-namespace llvm {
-using namespace sys;
-}
-
-// Include the platform-specific parts of this class.
-#ifdef LLVM_ON_UNIX
-#include "Unix/Memory.inc"
-#endif
-#ifdef LLVM_ON_WIN32
-#include "Win32/Memory.inc"
-#endif
-
-extern "C" void sys_icache_invalidate(const void *Addr, size_t len);
-
-/// InvalidateInstructionCache - Before the JIT can run a block of code
-/// that has been emitted it must invalidate the instruction cache on some
-/// platforms.
-void llvm::sys::Memory::InvalidateInstructionCache(const void *Addr,
- size_t Len) {
-
-// icache invalidation for PPC and ARM.
-#if defined(__APPLE__)
-
-# if (defined(__POWERPC__) || defined (__ppc__) || \
- defined(_POWER) || defined(_ARCH_PPC)) || defined(__arm__)
- sys_icache_invalidate(Addr, Len);
-# endif
-
-#else
-
-# if (defined(__POWERPC__) || defined (__ppc__) || \
- defined(_POWER) || defined(_ARCH_PPC)) && defined(__GNUC__)
- const size_t LineSize = 32;
-
- const intptr_t Mask = ~(LineSize - 1);
- const intptr_t StartLine = ((intptr_t) Addr) & Mask;
- const intptr_t EndLine = ((intptr_t) Addr + Len + LineSize - 1) & Mask;
-
- for (intptr_t Line = StartLine; Line < EndLine; Line += LineSize)
- asm volatile("dcbf 0, %0" : : "r"(Line));
- asm volatile("sync");
-
- for (intptr_t Line = StartLine; Line < EndLine; Line += LineSize)
- asm volatile("icbi 0, %0" : : "r"(Line));
- asm volatile("isync");
-# elif defined(__arm__) && defined(__GNUC__)
- // FIXME: Can we safely always call this for __GNUC__ everywhere?
- char *Start = (char*) Addr;
- char *End = Start + Len;
- __clear_cache(Start, End);
-# endif
-
-#endif // end apple
-
- ValgrindDiscardTranslations(Addr, Len);
-}
+++ /dev/null
-//===- Mutex.cpp - Mutual Exclusion Lock ------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the llvm::sys::Mutex class.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Config/config.h"
-#include "llvm/System/Mutex.h"
-
-//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only TRULY operating system
-//=== independent code.
-//===----------------------------------------------------------------------===//
-
-#if !defined(ENABLE_THREADS) || ENABLE_THREADS == 0
-// Define all methods as no-ops if threading is explicitly disabled
-namespace llvm {
-using namespace sys;
-MutexImpl::MutexImpl( bool recursive) { }
-MutexImpl::~MutexImpl() { }
-bool MutexImpl::acquire() { return true; }
-bool MutexImpl::release() { return true; }
-bool MutexImpl::tryacquire() { return true; }
-}
-#else
-
-#if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_MUTEX_LOCK)
-
-#include <cassert>
-#include <pthread.h>
-#include <stdlib.h>
-
-namespace llvm {
-using namespace sys;
-
-
-// This variable is useful for situations where the pthread library has been
-// compiled with weak linkage for its interface symbols. This allows the
-// threading support to be turned off by simply not linking against -lpthread.
-// In that situation, the value of pthread_mutex_init will be 0 and
-// consequently pthread_enabled will be false. In such situations, all the
-// pthread operations become no-ops and the functions all return false. If
-// pthread_mutex_init does have an address, then mutex support is enabled.
-// Note: all LLVM tools will link against -lpthread if its available since it
-// is configured into the LIBS variable.
-// Note: this line of code generates a warning if pthread_mutex_init is not
-// declared with weak linkage. It's safe to ignore the warning.
-static const bool pthread_enabled = true;
-
-// Construct a Mutex using pthread calls
-MutexImpl::MutexImpl( bool recursive)
- : data_(0)
-{
- if (pthread_enabled)
- {
- // Declare the pthread_mutex data structures
- pthread_mutex_t* mutex =
- static_cast<pthread_mutex_t*>(malloc(sizeof(pthread_mutex_t)));
- pthread_mutexattr_t attr;
-
- // Initialize the mutex attributes
- int errorcode = pthread_mutexattr_init(&attr);
- assert(errorcode == 0);
-
- // Initialize the mutex as a recursive mutex, if requested, or normal
- // otherwise.
- int kind = ( recursive ? PTHREAD_MUTEX_RECURSIVE : PTHREAD_MUTEX_NORMAL );
- errorcode = pthread_mutexattr_settype(&attr, kind);
- assert(errorcode == 0);
-
-#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__DragonFly__)
- // Make it a process local mutex
- errorcode = pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_PRIVATE);
-#endif
-
- // Initialize the mutex
- errorcode = pthread_mutex_init(mutex, &attr);
- assert(errorcode == 0);
-
- // Destroy the attributes
- errorcode = pthread_mutexattr_destroy(&attr);
- assert(errorcode == 0);
-
- // Assign the data member
- data_ = mutex;
- }
-}
-
-// Destruct a Mutex
-MutexImpl::~MutexImpl()
-{
- if (pthread_enabled)
- {
- pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_);
- assert(mutex != 0);
- pthread_mutex_destroy(mutex);
- free(mutex);
- }
-}
-
-bool
-MutexImpl::acquire()
-{
- if (pthread_enabled)
- {
- pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_);
- assert(mutex != 0);
-
- int errorcode = pthread_mutex_lock(mutex);
- return errorcode == 0;
- } else return false;
-}
-
-bool
-MutexImpl::release()
-{
- if (pthread_enabled)
- {
- pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_);
- assert(mutex != 0);
-
- int errorcode = pthread_mutex_unlock(mutex);
- return errorcode == 0;
- } else return false;
-}
-
-bool
-MutexImpl::tryacquire()
-{
- if (pthread_enabled)
- {
- pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_);
- assert(mutex != 0);
-
- int errorcode = pthread_mutex_trylock(mutex);
- return errorcode == 0;
- } else return false;
-}
-
-}
-
-#elif defined(LLVM_ON_UNIX)
-#include "Unix/Mutex.inc"
-#elif defined( LLVM_ON_WIN32)
-#include "Win32/Mutex.inc"
-#else
-#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in System/Mutex.cpp
-#endif
-#endif
-
+++ /dev/null
-//===-- Path.cpp - Implement OS Path Concept --------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This header file implements the operating system Path concept.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/System/Path.h"
-#include "llvm/Config/config.h"
-#include <cassert>
-#include <cstring>
-#include <ostream>
-using namespace llvm;
-using namespace sys;
-
-//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only TRULY operating system
-//=== independent code.
-//===----------------------------------------------------------------------===//
-
-bool Path::operator==(const Path &that) const {
- return path == that.path;
-}
-
-bool Path::operator<(const Path& that) const {
- return path < that.path;
-}
-
-Path
-Path::GetLLVMConfigDir() {
- Path result;
-#ifdef LLVM_ETCDIR
- if (result.set(LLVM_ETCDIR))
- return result;
-#endif
- return GetLLVMDefaultConfigDir();
-}
-
-LLVMFileType
-sys::IdentifyFileType(const char *magic, unsigned length) {
- assert(magic && "Invalid magic number string");
- assert(length >=4 && "Invalid magic number length");
- switch ((unsigned char)magic[0]) {
- case 0xDE: // 0x0B17C0DE = BC wraper
- if (magic[1] == (char)0xC0 && magic[2] == (char)0x17 &&
- magic[3] == (char)0x0B)
- return Bitcode_FileType;
- break;
- case 'B':
- if (magic[1] == 'C' && magic[2] == (char)0xC0 && magic[3] == (char)0xDE)
- return Bitcode_FileType;
- break;
- case '!':
- if (length >= 8)
- if (memcmp(magic,"!<arch>\n",8) == 0)
- return Archive_FileType;
- break;
-
- case '\177':
- if (magic[1] == 'E' && magic[2] == 'L' && magic[3] == 'F') {
- if (length >= 18 && magic[17] == 0)
- switch (magic[16]) {
- default: break;
- case 1: return ELF_Relocatable_FileType;
- case 2: return ELF_Executable_FileType;
- case 3: return ELF_SharedObject_FileType;
- case 4: return ELF_Core_FileType;
- }
- }
- break;
-
- case 0xCA:
- if (magic[1] == char(0xFE) && magic[2] == char(0xBA) &&
- magic[3] == char(0xBE)) {
- // This is complicated by an overlap with Java class files.
- // See the Mach-O section in /usr/share/file/magic for details.
- if (length >= 8 && magic[7] < 43)
- // FIXME: Universal Binary of any type.
- return Mach_O_DynamicallyLinkedSharedLib_FileType;
- }
- break;
-
- case 0xFE:
- case 0xCE: {
- uint16_t type = 0;
- if (magic[0] == char(0xFE) && magic[1] == char(0xED) &&
- magic[2] == char(0xFA) && magic[3] == char(0xCE)) {
- /* Native endian */
- if (length >= 16) type = magic[14] << 8 | magic[15];
- } else if (magic[0] == char(0xCE) && magic[1] == char(0xFA) &&
- magic[2] == char(0xED) && magic[3] == char(0xFE)) {
- /* Reverse endian */
- if (length >= 14) type = magic[13] << 8 | magic[12];
- }
- switch (type) {
- default: break;
- case 1: return Mach_O_Object_FileType;
- case 2: return Mach_O_Executable_FileType;
- case 3: return Mach_O_FixedVirtualMemorySharedLib_FileType;
- case 4: return Mach_O_Core_FileType;
- case 5: return Mach_O_PreloadExecutable_FileType;
- case 6: return Mach_O_DynamicallyLinkedSharedLib_FileType;
- case 7: return Mach_O_DynamicLinker_FileType;
- case 8: return Mach_O_Bundle_FileType;
- case 9: return Mach_O_DynamicallyLinkedSharedLibStub_FileType;
- case 10: break; // FIXME: MH_DSYM companion file with only debug.
- }
- break;
- }
- case 0xF0: // PowerPC Windows
- case 0x83: // Alpha 32-bit
- case 0x84: // Alpha 64-bit
- case 0x66: // MPS R4000 Windows
- case 0x50: // mc68K
- case 0x4c: // 80386 Windows
- if (magic[1] == 0x01)
- return COFF_FileType;
-
- case 0x90: // PA-RISC Windows
- case 0x68: // mc68K Windows
- if (magic[1] == 0x02)
- return COFF_FileType;
- break;
- case 0x64: // x86-64 Windows.
- if (magic[1] == char(0x86))
- return COFF_FileType;
- break;
-
- default:
- break;
- }
- return Unknown_FileType;
-}
-
-bool
-Path::isArchive() const {
- return hasMagicNumber("!<arch>\012");
-}
-
-bool
-Path::isDynamicLibrary() const {
- std::string Magic;
- if (getMagicNumber(Magic, 64))
- switch (IdentifyFileType(Magic.c_str(),
- static_cast<unsigned>(Magic.length()))) {
- default: return false;
- case Mach_O_FixedVirtualMemorySharedLib_FileType:
- case Mach_O_DynamicallyLinkedSharedLib_FileType:
- case Mach_O_DynamicallyLinkedSharedLibStub_FileType:
- case ELF_SharedObject_FileType:
- case COFF_FileType: return true;
- }
-
- return false;
-}
-
-bool
-Path::isObjectFile() const {
- std::string Magic;
- if (getMagicNumber(Magic, 64))
- if (IdentifyFileType(Magic.c_str(),
- static_cast<unsigned>(Magic.length()))
- != Unknown_FileType) {
- // Everything in LLVMFileType is currently an object file.
- return true;
- }
-
- return false;
-}
-
-Path
-Path::FindLibrary(std::string& name) {
- std::vector<sys::Path> LibPaths;
- GetSystemLibraryPaths(LibPaths);
- for (unsigned i = 0; i < LibPaths.size(); ++i) {
- sys::Path FullPath(LibPaths[i]);
- FullPath.appendComponent("lib" + name + LTDL_SHLIB_EXT);
- if (FullPath.isDynamicLibrary())
- return FullPath;
- FullPath.eraseSuffix();
- FullPath.appendSuffix("a");
- if (FullPath.isArchive())
- return FullPath;
- }
- return sys::Path();
-}
-
-StringRef Path::GetDLLSuffix() {
- return &(LTDL_SHLIB_EXT[1]);
-}
-
-bool
-Path::appendSuffix(StringRef suffix) {
- if (!suffix.empty()) {
- std::string save(path);
- path.append(".");
- path.append(suffix);
- if (!isValid()) {
- path = save;
- return false;
- }
- }
-
- return true;
-}
-
-bool
-Path::isBitcodeFile() const {
- std::string actualMagic;
- if (!getMagicNumber(actualMagic, 4))
- return false;
- LLVMFileType FT =
- IdentifyFileType(actualMagic.c_str(),
- static_cast<unsigned>(actualMagic.length()));
- return FT == Bitcode_FileType;
-}
-
-bool Path::hasMagicNumber(StringRef Magic) const {
- std::string actualMagic;
- if (getMagicNumber(actualMagic, static_cast<unsigned>(Magic.size())))
- return Magic == actualMagic;
- return false;
-}
-
-static void getPathList(const char*path, std::vector<Path>& Paths) {
- const char* at = path;
- const char* delim = strchr(at, PathSeparator);
- Path tmpPath;
- while (delim != 0) {
- std::string tmp(at, size_t(delim-at));
- if (tmpPath.set(tmp))
- if (tmpPath.canRead())
- Paths.push_back(tmpPath);
- at = delim + 1;
- delim = strchr(at, PathSeparator);
- }
-
- if (*at != 0)
- if (tmpPath.set(std::string(at)))
- if (tmpPath.canRead())
- Paths.push_back(tmpPath);
-}
-
-static StringRef getDirnameCharSep(StringRef path, const char *Sep) {
- assert(Sep[0] != '\0' && Sep[1] == '\0' &&
- "Sep must be a 1-character string literal.");
- if (path.empty())
- return ".";
-
- // If the path is all slashes, return a single slash.
- // Otherwise, remove all trailing slashes.
-
- signed pos = static_cast<signed>(path.size()) - 1;
-
- while (pos >= 0 && path[pos] == Sep[0])
- --pos;
-
- if (pos < 0)
- return path[0] == Sep[0] ? Sep : ".";
-
- // Any slashes left?
- signed i = 0;
-
- while (i < pos && path[i] != Sep[0])
- ++i;
-
- if (i == pos) // No slashes? Return "."
- return ".";
-
- // There is at least one slash left. Remove all trailing non-slashes.
- while (pos >= 0 && path[pos] != Sep[0])
- --pos;
-
- // Remove any trailing slashes.
- while (pos >= 0 && path[pos] == Sep[0])
- --pos;
-
- if (pos < 0)
- return path[0] == Sep[0] ? Sep : ".";
-
- return path.substr(0, pos+1);
-}
-
-// Include the truly platform-specific parts of this class.
-#if defined(LLVM_ON_UNIX)
-#include "Unix/Path.inc"
-#endif
-#if defined(LLVM_ON_WIN32)
-#include "Win32/Path.inc"
-#endif
-
+++ /dev/null
-//===-- Process.cpp - Implement OS Process Concept --------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This header file implements the operating system Process concept.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/System/Process.h"
-#include "llvm/Config/config.h"
-
-namespace llvm {
-using namespace sys;
-
-//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only TRULY operating system
-//=== independent code.
-//===----------------------------------------------------------------------===//
-
-}
-
-// Include the platform-specific parts of this class.
-#ifdef LLVM_ON_UNIX
-#include "Unix/Process.inc"
-#endif
-#ifdef LLVM_ON_WIN32
-#include "Win32/Process.inc"
-#endif
+++ /dev/null
-//===-- Program.cpp - Implement OS Program Concept --------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This header file implements the operating system Program concept.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/System/Program.h"
-#include "llvm/Config/config.h"
-using namespace llvm;
-using namespace sys;
-
-//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only TRULY operating system
-//=== independent code.
-//===----------------------------------------------------------------------===//
-
-int
-Program::ExecuteAndWait(const Path& path,
- const char** args,
- const char** envp,
- const Path** redirects,
- unsigned secondsToWait,
- unsigned memoryLimit,
- std::string* ErrMsg) {
- Program prg;
- if (prg.Execute(path, args, envp, redirects, memoryLimit, ErrMsg))
- return prg.Wait(path, secondsToWait, ErrMsg);
- else
- return -1;
-}
-
-void
-Program::ExecuteNoWait(const Path& path,
- const char** args,
- const char** envp,
- const Path** redirects,
- unsigned memoryLimit,
- std::string* ErrMsg) {
- Program prg;
- prg.Execute(path, args, envp, redirects, memoryLimit, ErrMsg);
-}
-
-// Include the platform-specific parts of this class.
-#ifdef LLVM_ON_UNIX
-#include "Unix/Program.inc"
-#endif
-#ifdef LLVM_ON_WIN32
-#include "Win32/Program.inc"
-#endif
+++ /dev/null
-Design Of lib/System
-====================
-
-The software in this directory is designed to completely shield LLVM from any
-and all operating system specific functionality. It is not intended to be a
-complete operating system wrapper (such as ACE), but only to provide the
-functionality necessary to support LLVM.
-
-The software located here, of necessity, has very specific and stringent design
-rules. Violation of these rules means that cracks in the shield could form and
-the primary goal of the library is defeated. By consistently using this library,
-LLVM becomes more easily ported to new platforms since the only thing requiring
-porting is this library.
-
-Complete documentation for the library can be found in the file:
- llvm/docs/SystemLibrary.html
-or at this URL:
- http://llvm.org/docs/SystemLibrary.html
-
-While we recommend that you read the more detailed documentation, for the
-impatient, here's a high level summary of the library's requirements.
-
- 1. No system header files are to be exposed through the interface.
- 2. Std C++ and Std C header files are okay to be exposed through the interface.
- 3. No exposed system-specific functions.
- 4. No exposed system-specific data.
- 5. Data in lib/System classes must use only simple C++ intrinsic types.
- 6. Errors are handled by returning "true" and setting an optional std::string
- 7. Library must not throw any exceptions, period.
- 8. Interface functions must not have throw() specifications.
- 9. No duplicate function impementations are permitted within an operating
- system class.
-
-To accomplish these requirements, the library has numerous design criteria that
-must be satisfied. Here's a high level summary of the library's design criteria:
-
- 1. No unused functionality (only what LLVM needs)
- 2. High-Level Interfaces
- 3. Use Opaque Classes
- 4. Common Implementations</a></li>
- 5. Multiple Implementations</a></li>
- 6. Minimize Memory Allocation</a></li>
- 7. No Virtual Methods
+++ /dev/null
-//===- RWMutex.cpp - Reader/Writer Mutual Exclusion Lock --------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the llvm::sys::RWMutex class.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Config/config.h"
-#include "llvm/System/RWMutex.h"
-#include <cstring>
-
-//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only TRULY operating system
-//=== independent code.
-//===----------------------------------------------------------------------===//
-
-#if !defined(ENABLE_THREADS) || ENABLE_THREADS == 0
-// Define all methods as no-ops if threading is explicitly disabled
-namespace llvm {
-using namespace sys;
-RWMutexImpl::RWMutexImpl() { }
-RWMutexImpl::~RWMutexImpl() { }
-bool RWMutexImpl::reader_acquire() { return true; }
-bool RWMutexImpl::reader_release() { return true; }
-bool RWMutexImpl::writer_acquire() { return true; }
-bool RWMutexImpl::writer_release() { return true; }
-}
-#else
-
-#if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_RWLOCK_INIT)
-
-#include <cassert>
-#include <pthread.h>
-#include <stdlib.h>
-
-namespace llvm {
-using namespace sys;
-
-
-// This variable is useful for situations where the pthread library has been
-// compiled with weak linkage for its interface symbols. This allows the
-// threading support to be turned off by simply not linking against -lpthread.
-// In that situation, the value of pthread_mutex_init will be 0 and
-// consequently pthread_enabled will be false. In such situations, all the
-// pthread operations become no-ops and the functions all return false. If
-// pthread_rwlock_init does have an address, then rwlock support is enabled.
-// Note: all LLVM tools will link against -lpthread if its available since it
-// is configured into the LIBS variable.
-// Note: this line of code generates a warning if pthread_rwlock_init is not
-// declared with weak linkage. It's safe to ignore the warning.
-static const bool pthread_enabled = true;
-
-// Construct a RWMutex using pthread calls
-RWMutexImpl::RWMutexImpl()
- : data_(0)
-{
- if (pthread_enabled)
- {
- // Declare the pthread_rwlock data structures
- pthread_rwlock_t* rwlock =
- static_cast<pthread_rwlock_t*>(malloc(sizeof(pthread_rwlock_t)));
-
-#ifdef __APPLE__
- // Workaround a bug/mis-feature in Darwin's pthread_rwlock_init.
- bzero(rwlock, sizeof(pthread_rwlock_t));
-#endif
-
- // Initialize the rwlock
- int errorcode = pthread_rwlock_init(rwlock, NULL);
- (void)errorcode;
- assert(errorcode == 0);
-
- // Assign the data member
- data_ = rwlock;
- }
-}
-
-// Destruct a RWMutex
-RWMutexImpl::~RWMutexImpl()
-{
- if (pthread_enabled)
- {
- pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
- assert(rwlock != 0);
- pthread_rwlock_destroy(rwlock);
- free(rwlock);
- }
-}
-
-bool
-RWMutexImpl::reader_acquire()
-{
- if (pthread_enabled)
- {
- pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
- assert(rwlock != 0);
-
- int errorcode = pthread_rwlock_rdlock(rwlock);
- return errorcode == 0;
- } else return false;
-}
-
-bool
-RWMutexImpl::reader_release()
-{
- if (pthread_enabled)
- {
- pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
- assert(rwlock != 0);
-
- int errorcode = pthread_rwlock_unlock(rwlock);
- return errorcode == 0;
- } else return false;
-}
-
-bool
-RWMutexImpl::writer_acquire()
-{
- if (pthread_enabled)
- {
- pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
- assert(rwlock != 0);
-
- int errorcode = pthread_rwlock_wrlock(rwlock);
- return errorcode == 0;
- } else return false;
-}
-
-bool
-RWMutexImpl::writer_release()
-{
- if (pthread_enabled)
- {
- pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
- assert(rwlock != 0);
-
- int errorcode = pthread_rwlock_unlock(rwlock);
- return errorcode == 0;
- } else return false;
-}
-
-}
-
-#elif defined(LLVM_ON_UNIX)
-#include "Unix/RWMutex.inc"
-#elif defined( LLVM_ON_WIN32)
-#include "Win32/RWMutex.inc"
-#else
-#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in System/Mutex.cpp
-#endif
-#endif
+++ /dev/null
-//===- SearchForAddressOfSpecialSymbol.cpp - Function addresses -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file pulls the addresses of certain symbols out of the linker. It must
-// include as few header files as possible because it declares the symbols as
-// void*, which would conflict with the actual symbol type if any header
-// declared it.
-//
-//===----------------------------------------------------------------------===//
-
-#include <string.h>
-
-// Must declare the symbols in the global namespace.
-static void *DoSearch(const char* symbolName) {
-#define EXPLICIT_SYMBOL(SYM) \
- extern void *SYM; if (!strcmp(symbolName, #SYM)) return &SYM
-
- // If this is darwin, it has some funky issues, try to solve them here. Some
- // important symbols are marked 'private external' which doesn't allow
- // SearchForAddressOfSymbol to find them. As such, we special case them here,
- // there is only a small handful of them.
-
-#ifdef __APPLE__
- {
- EXPLICIT_SYMBOL(__ashldi3);
- EXPLICIT_SYMBOL(__ashrdi3);
- EXPLICIT_SYMBOL(__cmpdi2);
- EXPLICIT_SYMBOL(__divdi3);
- EXPLICIT_SYMBOL(__fixdfdi);
- EXPLICIT_SYMBOL(__fixsfdi);
- EXPLICIT_SYMBOL(__fixunsdfdi);
- EXPLICIT_SYMBOL(__fixunssfdi);
- EXPLICIT_SYMBOL(__floatdidf);
- EXPLICIT_SYMBOL(__floatdisf);
- EXPLICIT_SYMBOL(__lshrdi3);
- EXPLICIT_SYMBOL(__moddi3);
- EXPLICIT_SYMBOL(__udivdi3);
- EXPLICIT_SYMBOL(__umoddi3);
-
- // __eprintf is sometimes used for assert() handling on x86.
-#ifdef __i386__
- EXPLICIT_SYMBOL(__eprintf);
-#endif
- }
-#endif
-
-#ifdef __CYGWIN__
- {
- EXPLICIT_SYMBOL(_alloca);
- EXPLICIT_SYMBOL(__main);
- }
-#endif
-
-#undef EXPLICIT_SYMBOL
- return 0;
-}
-
-namespace llvm {
-void *SearchForAddressOfSpecialSymbol(const char* symbolName) {
- return DoSearch(symbolName);
-}
-} // namespace llvm
+++ /dev/null
-//===- Signals.cpp - Signal Handling support --------------------*- 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 some helpful functions for dealing with the possibility of
-// Unix signals occuring while your program is running.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/System/Signals.h"
-#include "llvm/Config/config.h"
-
-namespace llvm {
-using namespace sys;
-
-//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only TRULY operating system
-//=== independent code.
-//===----------------------------------------------------------------------===//
-
-}
-
-// Include the platform-specific parts of this class.
-#ifdef LLVM_ON_UNIX
-#include "Unix/Signals.inc"
-#endif
-#ifdef LLVM_ON_WIN32
-#include "Win32/Signals.inc"
-#endif
+++ /dev/null
-//===- ThreadLocal.cpp - Thread Local Data ----------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the llvm::sys::ThreadLocal class.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Config/config.h"
-#include "llvm/System/ThreadLocal.h"
-
-//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only TRULY operating system
-//=== independent code.
-//===----------------------------------------------------------------------===//
-
-#if !defined(ENABLE_THREADS) || ENABLE_THREADS == 0
-// Define all methods as no-ops if threading is explicitly disabled
-namespace llvm {
-using namespace sys;
-ThreadLocalImpl::ThreadLocalImpl() { }
-ThreadLocalImpl::~ThreadLocalImpl() { }
-void ThreadLocalImpl::setInstance(const void* d) { data = const_cast<void*>(d);}
-const void* ThreadLocalImpl::getInstance() { return data; }
-void ThreadLocalImpl::removeInstance() { data = 0; }
-}
-#else
-
-#if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_GETSPECIFIC)
-
-#include <cassert>
-#include <pthread.h>
-#include <stdlib.h>
-
-namespace llvm {
-using namespace sys;
-
-ThreadLocalImpl::ThreadLocalImpl() : data(0) {
- pthread_key_t* key = new pthread_key_t;
- int errorcode = pthread_key_create(key, NULL);
- assert(errorcode == 0);
- (void) errorcode;
- data = (void*)key;
-}
-
-ThreadLocalImpl::~ThreadLocalImpl() {
- pthread_key_t* key = static_cast<pthread_key_t*>(data);
- int errorcode = pthread_key_delete(*key);
- assert(errorcode == 0);
- (void) errorcode;
- delete key;
-}
-
-void ThreadLocalImpl::setInstance(const void* d) {
- pthread_key_t* key = static_cast<pthread_key_t*>(data);
- int errorcode = pthread_setspecific(*key, d);
- assert(errorcode == 0);
- (void) errorcode;
-}
-
-const void* ThreadLocalImpl::getInstance() {
- pthread_key_t* key = static_cast<pthread_key_t*>(data);
- return pthread_getspecific(*key);
-}
-
-void ThreadLocalImpl::removeInstance() {
- setInstance(0);
-}
-
-}
-
-#elif defined(LLVM_ON_UNIX)
-#include "Unix/ThreadLocal.inc"
-#elif defined( LLVM_ON_WIN32)
-#include "Win32/ThreadLocal.inc"
-#else
-#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in System/ThreadLocal.cpp
-#endif
-#endif
-
+++ /dev/null
-//===-- llvm/System/Threading.cpp- Control multithreading mode --*- C++ -*-==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements llvm_start_multithreaded() and friends.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/System/Threading.h"
-#include "llvm/System/Atomic.h"
-#include "llvm/System/Mutex.h"
-#include "llvm/Config/config.h"
-#include <cassert>
-
-using namespace llvm;
-
-static bool multithreaded_mode = false;
-
-static sys::Mutex* global_lock = 0;
-
-bool llvm::llvm_start_multithreaded() {
-#ifdef LLVM_MULTITHREADED
- assert(!multithreaded_mode && "Already multithreaded!");
- multithreaded_mode = true;
- global_lock = new sys::Mutex(true);
-
- // We fence here to ensure that all initialization is complete BEFORE we
- // return from llvm_start_multithreaded().
- sys::MemoryFence();
- return true;
-#else
- return false;
-#endif
-}
-
-void llvm::llvm_stop_multithreaded() {
-#ifdef LLVM_MULTITHREADED
- assert(multithreaded_mode && "Not currently multithreaded!");
-
- // We fence here to insure that all threaded operations are complete BEFORE we
- // return from llvm_stop_multithreaded().
- sys::MemoryFence();
-
- multithreaded_mode = false;
- delete global_lock;
-#endif
-}
-
-bool llvm::llvm_is_multithreaded() {
- return multithreaded_mode;
-}
-
-void llvm::llvm_acquire_global_lock() {
- if (multithreaded_mode) global_lock->acquire();
-}
-
-void llvm::llvm_release_global_lock() {
- if (multithreaded_mode) global_lock->release();
-}
-
-#if defined(LLVM_MULTITHREADED) && defined(HAVE_PTHREAD_H)
-#include <pthread.h>
-
-struct ThreadInfo {
- void (*UserFn)(void *);
- void *UserData;
-};
-static void *ExecuteOnThread_Dispatch(void *Arg) {
- ThreadInfo *TI = reinterpret_cast<ThreadInfo*>(Arg);
- TI->UserFn(TI->UserData);
- return 0;
-}
-
-void llvm::llvm_execute_on_thread(void (*Fn)(void*), void *UserData,
- unsigned RequestedStackSize) {
- ThreadInfo Info = { Fn, UserData };
- pthread_attr_t Attr;
- pthread_t Thread;
-
- // Construct the attributes object.
- if (::pthread_attr_init(&Attr) != 0)
- return;
-
- // Set the requested stack size, if given.
- if (RequestedStackSize != 0) {
- if (::pthread_attr_setstacksize(&Attr, RequestedStackSize) != 0)
- goto error;
- }
-
- // Construct and execute the thread.
- if (::pthread_create(&Thread, &Attr, ExecuteOnThread_Dispatch, &Info) != 0)
- goto error;
-
- // Wait for the thread and clean up.
- ::pthread_join(Thread, 0);
-
- error:
- ::pthread_attr_destroy(&Attr);
-}
-
-#else
-
-// No non-pthread implementation, currently.
-
-void llvm::llvm_execute_on_thread(void (*Fn)(void*), void *UserData,
- unsigned RequestedStackSize) {
- (void) RequestedStackSize;
- Fn(UserData);
-}
-
-#endif
+++ /dev/null
-//===-- TimeValue.cpp - Implement OS TimeValue Concept ----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the operating system TimeValue concept.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/System/TimeValue.h"
-#include "llvm/Config/config.h"
-
-namespace llvm {
-using namespace sys;
-
-const TimeValue TimeValue::MinTime = TimeValue ( INT64_MIN,0 );
-const TimeValue TimeValue::MaxTime = TimeValue ( INT64_MAX,0 );
-const TimeValue TimeValue::ZeroTime = TimeValue ( 0,0 );
-const TimeValue TimeValue::PosixZeroTime = TimeValue ( -946684800,0 );
-const TimeValue TimeValue::Win32ZeroTime = TimeValue ( -12591158400ULL,0 );
-
-void
-TimeValue::normalize( void ) {
- if ( nanos_ >= NANOSECONDS_PER_SECOND ) {
- do {
- seconds_++;
- nanos_ -= NANOSECONDS_PER_SECOND;
- } while ( nanos_ >= NANOSECONDS_PER_SECOND );
- } else if (nanos_ <= -NANOSECONDS_PER_SECOND ) {
- do {
- seconds_--;
- nanos_ += NANOSECONDS_PER_SECOND;
- } while (nanos_ <= -NANOSECONDS_PER_SECOND);
- }
-
- if (seconds_ >= 1 && nanos_ < 0) {
- seconds_--;
- nanos_ += NANOSECONDS_PER_SECOND;
- } else if (seconds_ < 0 && nanos_ > 0) {
- seconds_++;
- nanos_ -= NANOSECONDS_PER_SECOND;
- }
-}
-
-}
-
-/// Include the platform specific portion of TimeValue class
-#ifdef LLVM_ON_UNIX
-#include "Unix/TimeValue.inc"
-#endif
-#ifdef LLVM_ON_WIN32
-#include "Win32/TimeValue.inc"
-#endif
-
+++ /dev/null
-//===-- Alarm.inc - Implement Unix Alarm Support ----------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the UNIX Alarm support.
-//
-//===----------------------------------------------------------------------===//
-
-#include <signal.h>
-#include <unistd.h>
-#include <cassert>
-using namespace llvm;
-
-/// AlarmCancelled - This flag is set by the SIGINT signal handler if the
-/// user presses CTRL-C.
-static volatile bool AlarmCancelled = false;
-
-/// AlarmTriggered - This flag is set by the SIGALRM signal handler if the
-/// alarm was triggered.
-static volatile bool AlarmTriggered = false;
-
-/// NestedSOI - Sanity check. Alarms cannot be nested or run in parallel.
-/// This ensures that they never do.
-static bool NestedSOI = false;
-
-static RETSIGTYPE SigIntHandler(int Sig) {
- AlarmCancelled = true;
- signal(SIGINT, SigIntHandler);
-}
-
-static RETSIGTYPE SigAlarmHandler(int Sig) {
- AlarmTriggered = true;
-}
-
-static void (*OldSigIntHandler) (int);
-
-void sys::SetupAlarm(unsigned seconds) {
- assert(!NestedSOI && "sys::SetupAlarm calls cannot be nested!");
- NestedSOI = true;
- AlarmCancelled = false;
- AlarmTriggered = false;
- ::signal(SIGALRM, SigAlarmHandler);
- OldSigIntHandler = ::signal(SIGINT, SigIntHandler);
- ::alarm(seconds);
-}
-
-void sys::TerminateAlarm() {
- assert(NestedSOI && "sys::TerminateAlarm called without sys::SetupAlarm!");
- ::alarm(0);
- ::signal(SIGALRM, SIG_DFL);
- ::signal(SIGINT, OldSigIntHandler);
- AlarmCancelled = false;
- AlarmTriggered = false;
- NestedSOI = false;
-}
-
-int sys::AlarmStatus() {
- if (AlarmCancelled)
- return -1;
- if (AlarmTriggered)
- return 1;
- return 0;
-}
-
-void sys::Sleep(unsigned n) {
- ::sleep(n);
-}
+++ /dev/null
- //===- llvm/System/Unix/Host.inc -------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the UNIX Host support.
-//
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only generic UNIX code that
-//=== is guaranteed to work on *all* UNIX variants.
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Config/config.h"
-#include "llvm/ADT/StringRef.h"
-#include "Unix.h"
-#include <sys/utsname.h>
-#include <string>
-
-using namespace llvm;
-
-static std::string getOSVersion() {
- struct utsname info;
-
- if (uname(&info))
- return "";
-
- return info.release;
-}
-
-std::string sys::getHostTriple() {
- // FIXME: Derive directly instead of relying on the autoconf generated
- // variable.
-
- StringRef HostTripleString(LLVM_HOSTTRIPLE);
- std::pair<StringRef, StringRef> ArchSplit = HostTripleString.split('-');
-
- // Normalize the arch, since the host triple may not actually match the host.
- std::string Arch = ArchSplit.first;
-
- // It would be nice to do this in terms of llvm::Triple, but that is in
- // Support which is layered above us.
-#if defined(__x86_64__)
- Arch = "x86_64";
-#elif defined(__i386__)
- Arch = "i386";
-#elif defined(__ppc64__)
- Arch = "powerpc64";
-#elif defined(__ppc__)
- Arch = "powerpc";
-#elif defined(__arm__)
-
- // FIXME: We need to pick the right ARM triple (which involves querying the
- // chip). However, for now this is most important for LLVM arch selection, so
- // we only need to make sure to distinguish ARM and Thumb.
-# if defined(__thumb__)
- Arch = "thumb";
-# else
- Arch = "arm";
-# endif
-
-#else
-
- // FIXME: When enough auto-detection is in place, this should just
- // #error. Then at least the arch selection is done, and we only need the OS
- // etc selection to kill off the use of LLVM_HOSTTRIPLE.
-
-#endif
-
- std::string Triple(Arch);
- Triple += '-';
- Triple += ArchSplit.second;
-
- // Force i<N>86 to i386.
- if (Triple[0] == 'i' && isdigit(Triple[1]) &&
- Triple[2] == '8' && Triple[3] == '6')
- Triple[1] = '3';
-
- // On darwin, we want to update the version to match that of the
- // host.
- std::string::size_type DarwinDashIdx = Triple.find("-darwin");
- if (DarwinDashIdx != std::string::npos) {
- Triple.resize(DarwinDashIdx + strlen("-darwin"));
-
- // Only add the major part of the os version.
- std::string Version = getOSVersion();
- Triple += Version.substr(0, Version.find('.'));
- }
-
- return Triple;
-}
+++ /dev/null
-//===- Unix/Memory.cpp - Generic UNIX System Configuration ------*- 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 some functions for various memory management utilities.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Unix.h"
-#include "llvm/System/DataTypes.h"
-#include "llvm/System/Process.h"
-
-#ifdef HAVE_SYS_MMAN_H
-#include <sys/mman.h>
-#endif
-
-#ifdef __APPLE__
-#include <mach/mach.h>
-#endif
-
-/// AllocateRWX - Allocate a slab of memory with read/write/execute
-/// permissions. This is typically used for JIT applications where we want
-/// to emit code to the memory then jump to it. Getting this type of memory
-/// is very OS specific.
-///
-llvm::sys::MemoryBlock
-llvm::sys::Memory::AllocateRWX(size_t NumBytes, const MemoryBlock* NearBlock,
- std::string *ErrMsg) {
- if (NumBytes == 0) return MemoryBlock();
-
- size_t pageSize = Process::GetPageSize();
- size_t NumPages = (NumBytes+pageSize-1)/pageSize;
-
- int fd = -1;
-#ifdef NEED_DEV_ZERO_FOR_MMAP
- static int zero_fd = open("/dev/zero", O_RDWR);
- if (zero_fd == -1) {
- MakeErrMsg(ErrMsg, "Can't open /dev/zero device");
- return MemoryBlock();
- }
- fd = zero_fd;
-#endif
-
- int flags = MAP_PRIVATE |
-#ifdef HAVE_MMAP_ANONYMOUS
- MAP_ANONYMOUS
-#else
- MAP_ANON
-#endif
- ;
-
- void* start = NearBlock ? (unsigned char*)NearBlock->base() +
- NearBlock->size() : 0;
-
-#if defined(__APPLE__) && defined(__arm__)
- void *pa = ::mmap(start, pageSize*NumPages, PROT_READ|PROT_EXEC,
- flags, fd, 0);
-#else
- void *pa = ::mmap(start, pageSize*NumPages, PROT_READ|PROT_WRITE|PROT_EXEC,
- flags, fd, 0);
-#endif
- if (pa == MAP_FAILED) {
- if (NearBlock) //Try again without a near hint
- return AllocateRWX(NumBytes, 0);
-
- MakeErrMsg(ErrMsg, "Can't allocate RWX Memory");
- return MemoryBlock();
- }
-
-#if defined(__APPLE__) && defined(__arm__)
- kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)pa,
- (vm_size_t)(pageSize*NumPages), 0,
- VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_COPY);
- if (KERN_SUCCESS != kr) {
- MakeErrMsg(ErrMsg, "vm_protect max RX failed");
- return sys::MemoryBlock();
- }
-
- kr = vm_protect(mach_task_self(), (vm_address_t)pa,
- (vm_size_t)(pageSize*NumPages), 0,
- VM_PROT_READ | VM_PROT_WRITE);
- if (KERN_SUCCESS != kr) {
- MakeErrMsg(ErrMsg, "vm_protect RW failed");
- return sys::MemoryBlock();
- }
-#endif
-
- MemoryBlock result;
- result.Address = pa;
- result.Size = NumPages*pageSize;
-
- return result;
-}
-
-bool llvm::sys::Memory::ReleaseRWX(MemoryBlock &M, std::string *ErrMsg) {
- if (M.Address == 0 || M.Size == 0) return false;
- if (0 != ::munmap(M.Address, M.Size))
- return MakeErrMsg(ErrMsg, "Can't release RWX Memory");
- return false;
-}
-
-bool llvm::sys::Memory::setWritable (MemoryBlock &M, std::string *ErrMsg) {
-#if defined(__APPLE__) && defined(__arm__)
- if (M.Address == 0 || M.Size == 0) return false;
- sys::Memory::InvalidateInstructionCache(M.Address, M.Size);
- kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)M.Address,
- (vm_size_t)M.Size, 0, VM_PROT_READ | VM_PROT_WRITE);
- return KERN_SUCCESS == kr;
-#else
- return true;
-#endif
-}
-
-bool llvm::sys::Memory::setExecutable (MemoryBlock &M, std::string *ErrMsg) {
-#if defined(__APPLE__) && defined(__arm__)
- if (M.Address == 0 || M.Size == 0) return false;
- sys::Memory::InvalidateInstructionCache(M.Address, M.Size);
- kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)M.Address,
- (vm_size_t)M.Size, 0, VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_COPY);
- return KERN_SUCCESS == kr;
-#else
- return false;
-#endif
-}
-
-bool llvm::sys::Memory::setRangeWritable(const void *Addr, size_t Size) {
-#if defined(__APPLE__) && defined(__arm__)
- kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)Addr,
- (vm_size_t)Size, 0,
- VM_PROT_READ | VM_PROT_WRITE);
- return KERN_SUCCESS == kr;
-#else
- return true;
-#endif
-}
-
-bool llvm::sys::Memory::setRangeExecutable(const void *Addr, size_t Size) {
-#if defined(__APPLE__) && defined(__arm__)
- kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)Addr,
- (vm_size_t)Size, 0,
- VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_COPY);
- return KERN_SUCCESS == kr;
-#else
- return true;
-#endif
-}
+++ /dev/null
-//===- llvm/System/Unix/Mutex.inc - Unix Mutex Implementation ---*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the Unix specific (non-pthread) Mutex class.
-//
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only generic UNIX code that
-//=== is guaranteed to work on *all* UNIX variants.
-//===----------------------------------------------------------------------===//
-
-namespace llvm
-{
-using namespace sys;
-
-MutexImpl::MutexImpl( bool recursive)
-{
-}
-
-MutexImpl::~MutexImpl()
-{
-}
-
-bool
-MutexImpl::release()
-{
- return true;
-}
-
-bool
-MutexImpl::tryacquire( void )
-{
- return true;
-}
-
-}
+++ /dev/null
-//===- llvm/System/Unix/Path.cpp - Unix Path Implementation -----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the Unix specific portion of the Path class.
-//
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only generic UNIX code that
-//=== is guaranteed to work on *all* UNIX variants.
-//===----------------------------------------------------------------------===//
-
-#include "Unix.h"
-#if HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#if HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_SYS_MMAN_H
-#include <sys/mman.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#if HAVE_UTIME_H
-#include <utime.h>
-#endif
-#if HAVE_TIME_H
-#include <time.h>
-#endif
-#if HAVE_DIRENT_H
-# include <dirent.h>
-# define NAMLEN(dirent) strlen((dirent)->d_name)
-#else
-# define dirent direct
-# define NAMLEN(dirent) (dirent)->d_namlen
-# if HAVE_SYS_NDIR_H
-# include <sys/ndir.h>
-# endif
-# if HAVE_SYS_DIR_H
-# include <sys/dir.h>
-# endif
-# if HAVE_NDIR_H
-# include <ndir.h>
-# endif
-#endif
-
-#if HAVE_DLFCN_H
-#include <dlfcn.h>
-#endif
-
-#ifdef __APPLE__
-#include <mach-o/dyld.h>
-#endif
-
-// Put in a hack for Cygwin which falsely reports that the mkdtemp function
-// is available when it is not.
-#ifdef __CYGWIN__
-# undef HAVE_MKDTEMP
-#endif
-
-namespace {
-inline bool lastIsSlash(const std::string& path) {
- return !path.empty() && path[path.length() - 1] == '/';
-}
-
-}
-
-namespace llvm {
-using namespace sys;
-
-const char sys::PathSeparator = ':';
-
-StringRef Path::GetEXESuffix() {
- return StringRef();
-}
-
-Path::Path(StringRef p)
- : path(p) {}
-
-Path::Path(const char *StrStart, unsigned StrLen)
- : path(StrStart, StrLen) {}
-
-Path&
-Path::operator=(StringRef that) {
- path.assign(that.data(), that.size());
- return *this;
-}
-
-bool
-Path::isValid() const {
- // Empty paths are considered invalid here.
- // This code doesn't check MAXPATHLEN because there's no need. Nothing in
- // LLVM manipulates Paths with fixed-sizes arrays, and if the OS can't
- // handle names longer than some limit, it'll report this on demand using
- // ENAMETOLONG.
- return !path.empty();
-}
-
-bool
-Path::isAbsolute(const char *NameStart, unsigned NameLen) {
- assert(NameStart);
- if (NameLen == 0)
- return false;
- return NameStart[0] == '/';
-}
-
-bool
-Path::isAbsolute() const {
- if (path.empty())
- return false;
- return path[0] == '/';
-}
-
-void Path::makeAbsolute() {
- if (isAbsolute())
- return;
-
- Path CWD = Path::GetCurrentDirectory();
- assert(CWD.isAbsolute() && "GetCurrentDirectory returned relative path!");
-
- CWD.appendComponent(path);
-
- path = CWD.str();
-}
-
-Path
-Path::GetRootDirectory() {
- Path result;
- result.set("/");
- return result;
-}
-
-Path
-Path::GetTemporaryDirectory(std::string *ErrMsg) {
-#if defined(HAVE_MKDTEMP)
- // The best way is with mkdtemp but that's not available on many systems,
- // Linux and FreeBSD have it. Others probably won't.
- char pathname[] = "/tmp/llvm_XXXXXX";
- if (0 == mkdtemp(pathname)) {
- MakeErrMsg(ErrMsg,
- std::string(pathname) + ": can't create temporary directory");
- return Path();
- }
- return Path(pathname);
-#elif defined(HAVE_MKSTEMP)
- // If no mkdtemp is available, mkstemp can be used to create a temporary file
- // which is then removed and created as a directory. We prefer this over
- // mktemp because of mktemp's inherent security and threading risks. We still
- // have a slight race condition from the time the temporary file is created to
- // the time it is re-created as a directoy.
- char pathname[] = "/tmp/llvm_XXXXXX";
- int fd = 0;
- if (-1 == (fd = mkstemp(pathname))) {
- MakeErrMsg(ErrMsg,
- std::string(pathname) + ": can't create temporary directory");
- return Path();
- }
- ::close(fd);
- ::unlink(pathname); // start race condition, ignore errors
- if (-1 == ::mkdir(pathname, S_IRWXU)) { // end race condition
- MakeErrMsg(ErrMsg,
- std::string(pathname) + ": can't create temporary directory");
- return Path();
- }
- return Path(pathname);
-#elif defined(HAVE_MKTEMP)
- // If a system doesn't have mkdtemp(3) or mkstemp(3) but it does have
- // mktemp(3) then we'll assume that system (e.g. AIX) has a reasonable
- // implementation of mktemp(3) and doesn't follow BSD 4.3's lead of replacing
- // the XXXXXX with the pid of the process and a letter. That leads to only
- // twenty six temporary files that can be generated.
- char pathname[] = "/tmp/llvm_XXXXXX";
- char *TmpName = ::mktemp(pathname);
- if (TmpName == 0) {
- MakeErrMsg(ErrMsg,
- std::string(TmpName) + ": can't create unique directory name");
- return Path();
- }
- if (-1 == ::mkdir(TmpName, S_IRWXU)) {
- MakeErrMsg(ErrMsg,
- std::string(TmpName) + ": can't create temporary directory");
- return Path();
- }
- return Path(TmpName);
-#else
- // This is the worst case implementation. tempnam(3) leaks memory unless its
- // on an SVID2 (or later) system. On BSD 4.3 it leaks. tmpnam(3) has thread
- // issues. The mktemp(3) function doesn't have enough variability in the
- // temporary name generated. So, we provide our own implementation that
- // increments an integer from a random number seeded by the current time. This
- // should be sufficiently unique that we don't have many collisions between
- // processes. Generally LLVM processes don't run very long and don't use very
- // many temporary files so this shouldn't be a big issue for LLVM.
- static time_t num = ::time(0);
- char pathname[MAXPATHLEN];
- do {
- num++;
- sprintf(pathname, "/tmp/llvm_%010u", unsigned(num));
- } while ( 0 == access(pathname, F_OK ) );
- if (-1 == ::mkdir(pathname, S_IRWXU)) {
- MakeErrMsg(ErrMsg,
- std::string(pathname) + ": can't create temporary directory");
- return Path();
- }
- return Path(pathname);
-#endif
-}
-
-void
-Path::GetSystemLibraryPaths(std::vector<sys::Path>& Paths) {
-#ifdef LTDL_SHLIBPATH_VAR
- char* env_var = getenv(LTDL_SHLIBPATH_VAR);
- if (env_var != 0) {
- getPathList(env_var,Paths);
- }
-#endif
- // FIXME: Should this look at LD_LIBRARY_PATH too?
- Paths.push_back(sys::Path("/usr/local/lib/"));
- Paths.push_back(sys::Path("/usr/X11R6/lib/"));
- Paths.push_back(sys::Path("/usr/lib/"));
- Paths.push_back(sys::Path("/lib/"));
-}
-
-void
-Path::GetBitcodeLibraryPaths(std::vector<sys::Path>& Paths) {
- char * env_var = getenv("LLVM_LIB_SEARCH_PATH");
- if (env_var != 0) {
- getPathList(env_var,Paths);
- }
-#ifdef LLVM_LIBDIR
- {
- Path tmpPath;
- if (tmpPath.set(LLVM_LIBDIR))
- if (tmpPath.canRead())
- Paths.push_back(tmpPath);
- }
-#endif
- GetSystemLibraryPaths(Paths);
-}
-
-Path
-Path::GetLLVMDefaultConfigDir() {
- return Path("/etc/llvm/");
-}
-
-Path
-Path::GetUserHomeDirectory() {
- const char* home = getenv("HOME");
- if (home) {
- Path result;
- if (result.set(home))
- return result;
- }
- return GetRootDirectory();
-}
-
-Path
-Path::GetCurrentDirectory() {
- char pathname[MAXPATHLEN];
- if (!getcwd(pathname,MAXPATHLEN)) {
- assert (false && "Could not query current working directory.");
- return Path();
- }
-
- return Path(pathname);
-}
-
-#if defined(__FreeBSD__) || defined (__NetBSD__) || defined(__minix)
-static int
-test_dir(char buf[PATH_MAX], char ret[PATH_MAX],
- const char *dir, const char *bin)
-{
- struct stat sb;
-
- snprintf(buf, PATH_MAX, "%s/%s", dir, bin);
- if (realpath(buf, ret) == NULL)
- return (1);
- if (stat(buf, &sb) != 0)
- return (1);
-
- return (0);
-}
-
-static char *
-getprogpath(char ret[PATH_MAX], const char *bin)
-{
- char *pv, *s, *t, buf[PATH_MAX];
-
- /* First approach: absolute path. */
- if (bin[0] == '/') {
- if (test_dir(buf, ret, "/", bin) == 0)
- return (ret);
- return (NULL);
- }
-
- /* Second approach: relative path. */
- if (strchr(bin, '/') != NULL) {
- if (getcwd(buf, PATH_MAX) == NULL)
- return (NULL);
- if (test_dir(buf, ret, buf, bin) == 0)
- return (ret);
- return (NULL);
- }
-
- /* Third approach: $PATH */
- if ((pv = getenv("PATH")) == NULL)
- return (NULL);
- s = pv = strdup(pv);
- if (pv == NULL)
- return (NULL);
- while ((t = strsep(&s, ":")) != NULL) {
- if (test_dir(buf, ret, t, bin) == 0) {
- free(pv);
- return (ret);
- }
- }
- free(pv);
- return (NULL);
-}
-#endif // __FreeBSD__ || __NetBSD__
-
-/// GetMainExecutable - Return the path to the main executable, given the
-/// value of argv[0] from program startup.
-Path Path::GetMainExecutable(const char *argv0, void *MainAddr) {
-#if defined(__APPLE__)
- // On OS X the executable path is saved to the stack by dyld. Reading it
- // from there is much faster than calling dladdr, especially for large
- // binaries with symbols.
- char exe_path[MAXPATHLEN];
- uint32_t size = sizeof(exe_path);
- if (_NSGetExecutablePath(exe_path, &size) == 0) {
- char link_path[MAXPATHLEN];
- if (realpath(exe_path, link_path))
- return Path(link_path);
- }
-#elif defined(__FreeBSD__) || defined (__NetBSD__) || defined(__minix)
- char exe_path[PATH_MAX];
-
- if (getprogpath(exe_path, argv0) != NULL)
- return Path(exe_path);
-#elif defined(__linux__) || defined(__CYGWIN__)
- char exe_path[MAXPATHLEN];
- ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path));
- if (len >= 0)
- return Path(StringRef(exe_path, len));
-#elif defined(HAVE_DLFCN_H)
- // Use dladdr to get executable path if available.
- Dl_info DLInfo;
- int err = dladdr(MainAddr, &DLInfo);
- if (err == 0)
- return Path();
-
- // If the filename is a symlink, we need to resolve and return the location of
- // the actual executable.
- char link_path[MAXPATHLEN];
- if (realpath(DLInfo.dli_fname, link_path))
- return Path(link_path);
-#else
-#error GetMainExecutable is not implemented on this host yet.
-#endif
- return Path();
-}
-
-
-StringRef Path::getDirname() const {
- return getDirnameCharSep(path, "/");
-}
-
-StringRef
-Path::getBasename() const {
- // Find the last slash
- std::string::size_type slash = path.rfind('/');
- if (slash == std::string::npos)
- slash = 0;
- else
- slash++;
-
- std::string::size_type dot = path.rfind('.');
- if (dot == std::string::npos || dot < slash)
- return StringRef(path).substr(slash);
- else
- return StringRef(path).substr(slash, dot - slash);
-}
-
-StringRef
-Path::getSuffix() const {
- // Find the last slash
- std::string::size_type slash = path.rfind('/');
- if (slash == std::string::npos)
- slash = 0;
- else
- slash++;
-
- std::string::size_type dot = path.rfind('.');
- if (dot == std::string::npos || dot < slash)
- return StringRef();
- else
- return StringRef(path).substr(dot + 1);
-}
-
-bool Path::getMagicNumber(std::string &Magic, unsigned len) const {
- assert(len < 1024 && "Request for magic string too long");
- char Buf[1025];
- int fd = ::open(path.c_str(), O_RDONLY);
- if (fd < 0)
- return false;
- ssize_t bytes_read = ::read(fd, Buf, len);
- ::close(fd);
- if (ssize_t(len) != bytes_read)
- return false;
- Magic.assign(Buf, len);
- return true;
-}
-
-bool
-Path::exists() const {
- return 0 == access(path.c_str(), F_OK );
-}
-
-bool
-Path::isDirectory() const {
- struct stat buf;
- if (0 != stat(path.c_str(), &buf))
- return false;
- return ((buf.st_mode & S_IFMT) == S_IFDIR) ? true : false;
-}
-
-bool
-Path::isSymLink() const {
- struct stat buf;
- if (0 != lstat(path.c_str(), &buf))
- return false;
- return S_ISLNK(buf.st_mode);
-}
-
-
-bool
-Path::canRead() const {
- return 0 == access(path.c_str(), R_OK);
-}
-
-bool
-Path::canWrite() const {
- return 0 == access(path.c_str(), W_OK);
-}
-
-bool
-Path::isRegularFile() const {
- // Get the status so we can determine if it's a file or directory
- struct stat buf;
-
- if (0 != stat(path.c_str(), &buf))
- return false;
-
- if (S_ISREG(buf.st_mode))
- return true;
-
- return false;
-}
-
-bool
-Path::canExecute() const {
- if (0 != access(path.c_str(), R_OK | X_OK ))
- return false;
- struct stat buf;
- if (0 != stat(path.c_str(), &buf))
- return false;
- if (!S_ISREG(buf.st_mode))
- return false;
- return true;
-}
-
-StringRef
-Path::getLast() const {
- // Find the last slash
- size_t pos = path.rfind('/');
-
- // Handle the corner cases
- if (pos == std::string::npos)
- return path;
-
- // If the last character is a slash
- if (pos == path.length()-1) {
- // Find the second to last slash
- size_t pos2 = path.rfind('/', pos-1);
- if (pos2 == std::string::npos)
- return StringRef(path).substr(0,pos);
- else
- return StringRef(path).substr(pos2+1,pos-pos2-1);
- }
- // Return everything after the last slash
- return StringRef(path).substr(pos+1);
-}
-
-const FileStatus *
-PathWithStatus::getFileStatus(bool update, std::string *ErrStr) const {
- if (!fsIsValid || update) {
- struct stat buf;
- if (0 != stat(path.c_str(), &buf)) {
- MakeErrMsg(ErrStr, path + ": can't get status of file");
- return 0;
- }
- status.fileSize = buf.st_size;
- status.modTime.fromEpochTime(buf.st_mtime);
- status.mode = buf.st_mode;
- status.user = buf.st_uid;
- status.group = buf.st_gid;
- status.uniqueID = uint64_t(buf.st_ino);
- status.isDir = S_ISDIR(buf.st_mode);
- status.isFile = S_ISREG(buf.st_mode);
- fsIsValid = true;
- }
- return &status;
-}
-
-static bool AddPermissionBits(const Path &File, int bits) {
- // Get the umask value from the operating system. We want to use it
- // when changing the file's permissions. Since calling umask() sets
- // the umask and returns its old value, we must call it a second
- // time to reset it to the user's preference.
- int mask = umask(0777); // The arg. to umask is arbitrary.
- umask(mask); // Restore the umask.
-
- // Get the file's current mode.
- struct stat buf;
- if (0 != stat(File.c_str(), &buf))
- return false;
- // Change the file to have whichever permissions bits from 'bits'
- // that the umask would not disable.
- if ((chmod(File.c_str(), (buf.st_mode | (bits & ~mask)))) == -1)
- return false;
- return true;
-}
-
-bool Path::makeReadableOnDisk(std::string* ErrMsg) {
- if (!AddPermissionBits(*this, 0444))
- return MakeErrMsg(ErrMsg, path + ": can't make file readable");
- return false;
-}
-
-bool Path::makeWriteableOnDisk(std::string* ErrMsg) {
- if (!AddPermissionBits(*this, 0222))
- return MakeErrMsg(ErrMsg, path + ": can't make file writable");
- return false;
-}
-
-bool Path::makeExecutableOnDisk(std::string* ErrMsg) {
- if (!AddPermissionBits(*this, 0111))
- return MakeErrMsg(ErrMsg, path + ": can't make file executable");
- return false;
-}
-
-bool
-Path::getDirectoryContents(std::set<Path>& result, std::string* ErrMsg) const {
- DIR* direntries = ::opendir(path.c_str());
- if (direntries == 0)
- return MakeErrMsg(ErrMsg, path + ": can't open directory");
-
- std::string dirPath = path;
- if (!lastIsSlash(dirPath))
- dirPath += '/';
-
- result.clear();
- struct dirent* de = ::readdir(direntries);
- for ( ; de != 0; de = ::readdir(direntries)) {
- if (de->d_name[0] != '.') {
- Path aPath(dirPath + (const char*)de->d_name);
- struct stat st;
- if (0 != lstat(aPath.path.c_str(), &st)) {
- if (S_ISLNK(st.st_mode))
- continue; // dangling symlink -- ignore
- return MakeErrMsg(ErrMsg,
- aPath.path + ": can't determine file object type");
- }
- result.insert(aPath);
- }
- }
-
- closedir(direntries);
- return false;
-}
-
-bool
-Path::set(StringRef a_path) {
- if (a_path.empty())
- return false;
- path = a_path;
- return true;
-}
-
-bool
-Path::appendComponent(StringRef name) {
- if (name.empty())
- return false;
- if (!lastIsSlash(path))
- path += '/';
- path += name;
- return true;
-}
-
-bool
-Path::eraseComponent() {
- size_t slashpos = path.rfind('/',path.size());
- if (slashpos == 0 || slashpos == std::string::npos) {
- path.erase();
- return true;
- }
- if (slashpos == path.size() - 1)
- slashpos = path.rfind('/',slashpos-1);
- if (slashpos == std::string::npos) {
- path.erase();
- return true;
- }
- path.erase(slashpos);
- return true;
-}
-
-bool
-Path::eraseSuffix() {
- size_t dotpos = path.rfind('.',path.size());
- size_t slashpos = path.rfind('/',path.size());
- if (dotpos != std::string::npos) {
- if (slashpos == std::string::npos || dotpos > slashpos+1) {
- path.erase(dotpos, path.size()-dotpos);
- return true;
- }
- }
- return false;
-}
-
-static bool createDirectoryHelper(char* beg, char* end, bool create_parents) {
-
- if (access(beg, R_OK | W_OK) == 0)
- return false;
-
- if (create_parents) {
-
- char* c = end;
-
- for (; c != beg; --c)
- if (*c == '/') {
-
- // Recurse to handling the parent directory.
- *c = '\0';
- bool x = createDirectoryHelper(beg, c, create_parents);
- *c = '/';
-
- // Return if we encountered an error.
- if (x)
- return true;
-
- break;
- }
- }
-
- return mkdir(beg, S_IRWXU | S_IRWXG) != 0;
-}
-
-bool
-Path::createDirectoryOnDisk( bool create_parents, std::string* ErrMsg ) {
- // Get a writeable copy of the path name
- std::string pathname(path);
-
- // Null-terminate the last component
- size_t lastchar = path.length() - 1 ;
-
- if (pathname[lastchar] != '/')
- ++lastchar;
-
- pathname[lastchar] = '\0';
-
- if (createDirectoryHelper(&pathname[0], &pathname[lastchar], create_parents))
- return MakeErrMsg(ErrMsg, pathname + ": can't create directory");
-
- return false;
-}
-
-bool
-Path::createFileOnDisk(std::string* ErrMsg) {
- // Create the file
- int fd = ::creat(path.c_str(), S_IRUSR | S_IWUSR);
- if (fd < 0)
- return MakeErrMsg(ErrMsg, path + ": can't create file");
- ::close(fd);
- return false;
-}
-
-bool
-Path::createTemporaryFileOnDisk(bool reuse_current, std::string* ErrMsg) {
- // Make this into a unique file name
- if (makeUnique( reuse_current, ErrMsg ))
- return true;
-
- // create the file
- int fd = ::open(path.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0666);
- if (fd < 0)
- return MakeErrMsg(ErrMsg, path + ": can't create temporary file");
- ::close(fd);
- return false;
-}
-
-bool
-Path::eraseFromDisk(bool remove_contents, std::string *ErrStr) const {
- // Get the status so we can determine if it's a file or directory.
- struct stat buf;
- if (0 != stat(path.c_str(), &buf)) {
- MakeErrMsg(ErrStr, path + ": can't get status of file");
- return true;
- }
-
- // Note: this check catches strange situations. In all cases, LLVM should
- // only be involved in the creation and deletion of regular files. This
- // check ensures that what we're trying to erase is a regular file. It
- // effectively prevents LLVM from erasing things like /dev/null, any block
- // special file, or other things that aren't "regular" files.
- if (S_ISREG(buf.st_mode)) {
- if (unlink(path.c_str()) != 0)
- return MakeErrMsg(ErrStr, path + ": can't destroy file");
- return false;
- }
-
- if (!S_ISDIR(buf.st_mode)) {
- if (ErrStr) *ErrStr = "not a file or directory";
- return true;
- }
-
- if (remove_contents) {
- // Recursively descend the directory to remove its contents.
- std::string cmd = "/bin/rm -rf " + path;
- if (system(cmd.c_str()) != 0) {
- MakeErrMsg(ErrStr, path + ": failed to recursively remove directory.");
- return true;
- }
- return false;
- }
-
- // Otherwise, try to just remove the one directory.
- std::string pathname(path);
- size_t lastchar = path.length() - 1;
- if (pathname[lastchar] == '/')
- pathname[lastchar] = '\0';
- else
- pathname[lastchar+1] = '\0';
-
- if (rmdir(pathname.c_str()) != 0)
- return MakeErrMsg(ErrStr, pathname + ": can't erase directory");
- return false;
-}
-
-bool
-Path::renamePathOnDisk(const Path& newName, std::string* ErrMsg) {
- if (0 != ::rename(path.c_str(), newName.c_str()))
- return MakeErrMsg(ErrMsg, std::string("can't rename '") + path + "' as '" +
- newName.str() + "'");
- return false;
-}
-
-bool
-Path::setStatusInfoOnDisk(const FileStatus &si, std::string *ErrStr) const {
- struct utimbuf utb;
- utb.actime = si.modTime.toPosixTime();
- utb.modtime = utb.actime;
- if (0 != ::utime(path.c_str(),&utb))
- return MakeErrMsg(ErrStr, path + ": can't set file modification time");
- if (0 != ::chmod(path.c_str(),si.mode))
- return MakeErrMsg(ErrStr, path + ": can't set mode");
- return false;
-}
-
-bool
-sys::CopyFile(const sys::Path &Dest, const sys::Path &Src, std::string* ErrMsg){
- int inFile = -1;
- int outFile = -1;
- inFile = ::open(Src.c_str(), O_RDONLY);
- if (inFile == -1)
- return MakeErrMsg(ErrMsg, Src.str() +
- ": can't open source file to copy");
-
- outFile = ::open(Dest.c_str(), O_WRONLY|O_CREAT, 0666);
- if (outFile == -1) {
- ::close(inFile);
- return MakeErrMsg(ErrMsg, Dest.str() +
- ": can't create destination file for copy");
- }
-
- char Buffer[16*1024];
- while (ssize_t Amt = ::read(inFile, Buffer, 16*1024)) {
- if (Amt == -1) {
- if (errno != EINTR && errno != EAGAIN) {
- ::close(inFile);
- ::close(outFile);
- return MakeErrMsg(ErrMsg, Src.str()+": can't read source file");
- }
- } else {
- char *BufPtr = Buffer;
- while (Amt) {
- ssize_t AmtWritten = ::write(outFile, BufPtr, Amt);
- if (AmtWritten == -1) {
- if (errno != EINTR && errno != EAGAIN) {
- ::close(inFile);
- ::close(outFile);
- return MakeErrMsg(ErrMsg, Dest.str() +
- ": can't write destination file");
- }
- } else {
- Amt -= AmtWritten;
- BufPtr += AmtWritten;
- }
- }
- }
- }
- ::close(inFile);
- ::close(outFile);
- return false;
-}
-
-bool
-Path::makeUnique(bool reuse_current, std::string* ErrMsg) {
- if (reuse_current && !exists())
- return false; // File doesn't exist already, just use it!
-
- // Append an XXXXXX pattern to the end of the file for use with mkstemp,
- // mktemp or our own implementation.
- // This uses std::vector instead of SmallVector to avoid a dependence on
- // libSupport. And performance isn't critical here.
- std::vector<char> Buf;
- Buf.resize(path.size()+8);
- char *FNBuffer = &Buf[0];
- path.copy(FNBuffer,path.size());
- if (isDirectory())
- strcpy(FNBuffer+path.size(), "/XXXXXX");
- else
- strcpy(FNBuffer+path.size(), "-XXXXXX");
-
-#if defined(HAVE_MKSTEMP)
- int TempFD;
- if ((TempFD = mkstemp(FNBuffer)) == -1)
- return MakeErrMsg(ErrMsg, path + ": can't make unique filename");
-
- // We don't need to hold the temp file descriptor... we will trust that no one
- // will overwrite/delete the file before we can open it again.
- close(TempFD);
-
- // Save the name
- path = FNBuffer;
-#elif defined(HAVE_MKTEMP)
- // If we don't have mkstemp, use the old and obsolete mktemp function.
- if (mktemp(FNBuffer) == 0)
- return MakeErrMsg(ErrMsg, path + ": can't make unique filename");
-
- // Save the name
- path = FNBuffer;
-#else
- // Okay, looks like we have to do it all by our lonesome.
- static unsigned FCounter = 0;
- // Try to initialize with unique value.
- if (FCounter == 0) FCounter = ((unsigned)getpid() & 0xFFFF) << 8;
- char* pos = strstr(FNBuffer, "XXXXXX");
- do {
- if (++FCounter > 0xFFFFFF) {
- return MakeErrMsg(ErrMsg,
- path + ": can't make unique filename: too many files");
- }
- sprintf(pos, "%06X", FCounter);
- path = FNBuffer;
- } while (exists());
- // POSSIBLE SECURITY BUG: An attacker can easily guess the name and exploit
- // LLVM.
-#endif
- return false;
-}
-
-const char *Path::MapInFilePages(int FD, uint64_t FileSize) {
- int Flags = MAP_PRIVATE;
-#ifdef MAP_FILE
- Flags |= MAP_FILE;
-#endif
- void *BasePtr = ::mmap(0, FileSize, PROT_READ, Flags, FD, 0);
- if (BasePtr == MAP_FAILED)
- return 0;
- return (const char*)BasePtr;
-}
-
-void Path::UnMapFilePages(const char *BasePtr, uint64_t FileSize) {
- ::munmap((void*)BasePtr, FileSize);
-}
-
-} // end llvm namespace
+++ /dev/null
-//===- Unix/Process.cpp - Unix Process Implementation --------- -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides the generic Unix implementation of the Process class.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Unix.h"
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#ifdef HAVE_SYS_RESOURCE_H
-#include <sys/resource.h>
-#endif
-// DragonFly BSD has deprecated <malloc.h> for <stdlib.h> instead,
-// Unix.h includes this for us already.
-#if defined(HAVE_MALLOC_H) && !defined(__DragonFly__)
-#include <malloc.h>
-#endif
-#ifdef HAVE_MALLOC_MALLOC_H
-#include <malloc/malloc.h>
-#endif
-#ifdef HAVE_SYS_IOCTL_H
-# include <sys/ioctl.h>
-#endif
-#ifdef HAVE_TERMIOS_H
-# include <termios.h>
-#endif
-
-//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only generic UNIX code that
-//=== is guaranteed to work on *all* UNIX variants.
-//===----------------------------------------------------------------------===//
-
-using namespace llvm;
-using namespace sys;
-
-unsigned
-Process::GetPageSize()
-{
-#if defined(__CYGWIN__)
- // On Cygwin, getpagesize() returns 64k but the page size for the purposes of
- // memory protection and mmap() is 4k.
- // See http://www.cygwin.com/ml/cygwin/2009-01/threads.html#00492
- const int page_size = 0x1000;
-#elif defined(HAVE_GETPAGESIZE)
- const int page_size = ::getpagesize();
-#elif defined(HAVE_SYSCONF)
- long page_size = ::sysconf(_SC_PAGE_SIZE);
-#else
-#warning Cannot get the page size on this machine
-#endif
- return static_cast<unsigned>(page_size);
-}
-
-size_t Process::GetMallocUsage() {
-#if defined(HAVE_MALLINFO)
- struct mallinfo mi;
- mi = ::mallinfo();
- return mi.uordblks;
-#elif defined(HAVE_MALLOC_ZONE_STATISTICS) && defined(HAVE_MALLOC_MALLOC_H)
- malloc_statistics_t Stats;
- malloc_zone_statistics(malloc_default_zone(), &Stats);
- return Stats.size_in_use; // darwin
-#elif defined(HAVE_SBRK)
- // Note this is only an approximation and more closely resembles
- // the value returned by mallinfo in the arena field.
- static char *StartOfMemory = reinterpret_cast<char*>(::sbrk(0));
- char *EndOfMemory = (char*)sbrk(0);
- if (EndOfMemory != ((char*)-1) && StartOfMemory != ((char*)-1))
- return EndOfMemory - StartOfMemory;
- else
- return 0;
-#else
-#warning Cannot get malloc info on this platform
- return 0;
-#endif
-}
-
-size_t
-Process::GetTotalMemoryUsage()
-{
-#if defined(HAVE_MALLINFO)
- struct mallinfo mi = ::mallinfo();
- return mi.uordblks + mi.hblkhd;
-#elif defined(HAVE_MALLOC_ZONE_STATISTICS) && defined(HAVE_MALLOC_MALLOC_H)
- malloc_statistics_t Stats;
- malloc_zone_statistics(malloc_default_zone(), &Stats);
- return Stats.size_allocated; // darwin
-#elif defined(HAVE_GETRUSAGE) && !defined(__HAIKU__)
- struct rusage usage;
- ::getrusage(RUSAGE_SELF, &usage);
- return usage.ru_maxrss;
-#else
-#warning Cannot get total memory size on this platform
- return 0;
-#endif
-}
-
-void
-Process::GetTimeUsage(TimeValue& elapsed, TimeValue& user_time,
- TimeValue& sys_time)
-{
- elapsed = TimeValue::now();
-#if defined(HAVE_GETRUSAGE)
- struct rusage usage;
- ::getrusage(RUSAGE_SELF, &usage);
- user_time = TimeValue(
- static_cast<TimeValue::SecondsType>( usage.ru_utime.tv_sec ),
- static_cast<TimeValue::NanoSecondsType>( usage.ru_utime.tv_usec *
- TimeValue::NANOSECONDS_PER_MICROSECOND ) );
- sys_time = TimeValue(
- static_cast<TimeValue::SecondsType>( usage.ru_stime.tv_sec ),
- static_cast<TimeValue::NanoSecondsType>( usage.ru_stime.tv_usec *
- TimeValue::NANOSECONDS_PER_MICROSECOND ) );
-#else
-#warning Cannot get usage times on this platform
- user_time.seconds(0);
- user_time.microseconds(0);
- sys_time.seconds(0);
- sys_time.microseconds(0);
-#endif
-}
-
-int Process::GetCurrentUserId() {
- return getuid();
-}
-
-int Process::GetCurrentGroupId() {
- return getgid();
-}
-
-#ifdef HAVE_MACH_MACH_H
-#include <mach/mach.h>
-#endif
-
-// Some LLVM programs such as bugpoint produce core files as a normal part of
-// their operation. To prevent the disk from filling up, this function
-// does what's necessary to prevent their generation.
-void Process::PreventCoreFiles() {
-#if HAVE_SETRLIMIT
- struct rlimit rlim;
- rlim.rlim_cur = rlim.rlim_max = 0;
- setrlimit(RLIMIT_CORE, &rlim);
-#endif
-
-#ifdef HAVE_MACH_MACH_H
- // Disable crash reporting on Mac OS X 10.0-10.4
-
- // get information about the original set of exception ports for the task
- mach_msg_type_number_t Count = 0;
- exception_mask_t OriginalMasks[EXC_TYPES_COUNT];
- exception_port_t OriginalPorts[EXC_TYPES_COUNT];
- exception_behavior_t OriginalBehaviors[EXC_TYPES_COUNT];
- thread_state_flavor_t OriginalFlavors[EXC_TYPES_COUNT];
- kern_return_t err =
- task_get_exception_ports(mach_task_self(), EXC_MASK_ALL, OriginalMasks,
- &Count, OriginalPorts, OriginalBehaviors,
- OriginalFlavors);
- if (err == KERN_SUCCESS) {
- // replace each with MACH_PORT_NULL.
- for (unsigned i = 0; i != Count; ++i)
- task_set_exception_ports(mach_task_self(), OriginalMasks[i],
- MACH_PORT_NULL, OriginalBehaviors[i],
- OriginalFlavors[i]);
- }
-
- // Disable crash reporting on Mac OS X 10.5
- signal(SIGABRT, _exit);
- signal(SIGILL, _exit);
- signal(SIGFPE, _exit);
- signal(SIGSEGV, _exit);
- signal(SIGBUS, _exit);
-#endif
-}
-
-bool Process::StandardInIsUserInput() {
- return FileDescriptorIsDisplayed(STDIN_FILENO);
-}
-
-bool Process::StandardOutIsDisplayed() {
- return FileDescriptorIsDisplayed(STDOUT_FILENO);
-}
-
-bool Process::StandardErrIsDisplayed() {
- return FileDescriptorIsDisplayed(STDERR_FILENO);
-}
-
-bool Process::FileDescriptorIsDisplayed(int fd) {
-#if HAVE_ISATTY
- return isatty(fd);
-#else
- // If we don't have isatty, just return false.
- return false;
-#endif
-}
-
-static unsigned getColumns(int FileID) {
- // If COLUMNS is defined in the environment, wrap to that many columns.
- if (const char *ColumnsStr = std::getenv("COLUMNS")) {
- int Columns = std::atoi(ColumnsStr);
- if (Columns > 0)
- return Columns;
- }
-
- unsigned Columns = 0;
-
-#if defined(HAVE_SYS_IOCTL_H) && defined(HAVE_TERMIOS_H)
- // Try to determine the width of the terminal.
- struct winsize ws;
- if (ioctl(FileID, TIOCGWINSZ, &ws) == 0)
- Columns = ws.ws_col;
-#endif
-
- return Columns;
-}
-
-unsigned Process::StandardOutColumns() {
- if (!StandardOutIsDisplayed())
- return 0;
-
- return getColumns(1);
-}
-
-unsigned Process::StandardErrColumns() {
- if (!StandardErrIsDisplayed())
- return 0;
-
- return getColumns(2);
-}
-
-static bool terminalHasColors() {
- if (const char *term = std::getenv("TERM")) {
- // Most modern terminals support ANSI escape sequences for colors.
- // We could check terminfo, or have a list of known terms that support
- // colors, but that would be overkill.
- // The user can always ask for no colors by setting TERM to dumb, or
- // using a commandline flag.
- return strcmp(term, "dumb") != 0;
- }
- return false;
-}
-
-bool Process::StandardOutHasColors() {
- if (!StandardOutIsDisplayed())
- return false;
- return terminalHasColors();
-}
-
-bool Process::StandardErrHasColors() {
- if (!StandardErrIsDisplayed())
- return false;
- return terminalHasColors();
-}
-
-bool Process::ColorNeedsFlush() {
- // No, we use ANSI escape sequences.
- return false;
-}
-
-#define COLOR(FGBG, CODE, BOLD) "\033[0;" BOLD FGBG CODE "m"
-
-#define ALLCOLORS(FGBG,BOLD) {\
- COLOR(FGBG, "0", BOLD),\
- COLOR(FGBG, "1", BOLD),\
- COLOR(FGBG, "2", BOLD),\
- COLOR(FGBG, "3", BOLD),\
- COLOR(FGBG, "4", BOLD),\
- COLOR(FGBG, "5", BOLD),\
- COLOR(FGBG, "6", BOLD),\
- COLOR(FGBG, "7", BOLD)\
- }
-
-static const char colorcodes[2][2][8][10] = {
- { ALLCOLORS("3",""), ALLCOLORS("3","1;") },
- { ALLCOLORS("4",""), ALLCOLORS("4","1;") }
-};
-
-const char *Process::OutputColor(char code, bool bold, bool bg) {
- return colorcodes[bg?1:0][bold?1:0][code&7];
-}
-
-const char *Process::OutputBold(bool bg) {
- return "\033[1m";
-}
-
-const char *Process::ResetColor() {
- return "\033[0m";
-}
+++ /dev/null
-//===- llvm/System/Unix/Program.cpp -----------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the Unix specific portion of the Program class.
-//
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only generic UNIX code that
-//=== is guaranteed to work on *all* UNIX variants.
-//===----------------------------------------------------------------------===//
-
-#include <llvm/Config/config.h>
-#include "Unix.h"
-#if HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#if HAVE_SYS_RESOURCE_H
-#include <sys/resource.h>
-#endif
-#if HAVE_SIGNAL_H
-#include <signal.h>
-#endif
-#if HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_POSIX_SPAWN
-#include <spawn.h>
-#if !defined(__APPLE__)
- extern char **environ;
-#else
-#include <crt_externs.h> // _NSGetEnviron
-#endif
-#endif
-
-namespace llvm {
-using namespace sys;
-
-Program::Program() : Data_(0) {}
-
-Program::~Program() {}
-
-unsigned Program::GetPid() const {
- uint64_t pid = reinterpret_cast<uint64_t>(Data_);
- return static_cast<unsigned>(pid);
-}
-
-// This function just uses the PATH environment variable to find the program.
-Path
-Program::FindProgramByName(const std::string& progName) {
-
- // Check some degenerate cases
- if (progName.length() == 0) // no program
- return Path();
- Path temp;
- if (!temp.set(progName)) // invalid name
- return Path();
- // Use the given path verbatim if it contains any slashes; this matches
- // the behavior of sh(1) and friends.
- if (progName.find('/') != std::string::npos)
- return temp;
-
- // At this point, the file name is valid and does not contain slashes. Search
- // for it through the directories specified in the PATH environment variable.
-
- // Get the path. If its empty, we can't do anything to find it.
- const char *PathStr = getenv("PATH");
- if (PathStr == 0)
- return Path();
-
- // Now we have a colon separated list of directories to search; try them.
- size_t PathLen = strlen(PathStr);
- while (PathLen) {
- // Find the first colon...
- const char *Colon = std::find(PathStr, PathStr+PathLen, ':');
-
- // Check to see if this first directory contains the executable...
- Path FilePath;
- if (FilePath.set(std::string(PathStr,Colon))) {
- FilePath.appendComponent(progName);
- if (FilePath.canExecute())
- return FilePath; // Found the executable!
- }
-
- // Nope it wasn't in this directory, check the next path in the list!
- PathLen -= Colon-PathStr;
- PathStr = Colon;
-
- // Advance past duplicate colons
- while (*PathStr == ':') {
- PathStr++;
- PathLen--;
- }
- }
- return Path();
-}
-
-static bool RedirectIO(const Path *Path, int FD, std::string* ErrMsg) {
- if (Path == 0) // Noop
- return false;
- const char *File;
- if (Path->isEmpty())
- // Redirect empty paths to /dev/null
- File = "/dev/null";
- else
- File = Path->c_str();
-
- // Open the file
- int InFD = open(File, FD == 0 ? O_RDONLY : O_WRONLY|O_CREAT, 0666);
- if (InFD == -1) {
- MakeErrMsg(ErrMsg, "Cannot open file '" + std::string(File) + "' for "
- + (FD == 0 ? "input" : "output"));
- return true;
- }
-
- // Install it as the requested FD
- if (dup2(InFD, FD) == -1) {
- MakeErrMsg(ErrMsg, "Cannot dup2");
- close(InFD);
- return true;
- }
- close(InFD); // Close the original FD
- return false;
-}
-
-#ifdef HAVE_POSIX_SPAWN
-static bool RedirectIO_PS(const Path *Path, int FD, std::string *ErrMsg,
- posix_spawn_file_actions_t &FileActions) {
- if (Path == 0) // Noop
- return false;
- const char *File;
- if (Path->isEmpty())
- // Redirect empty paths to /dev/null
- File = "/dev/null";
- else
- File = Path->c_str();
-
- if (int Err = posix_spawn_file_actions_addopen(&FileActions, FD,
- File, FD == 0 ? O_RDONLY : O_WRONLY|O_CREAT, 0666))
- return MakeErrMsg(ErrMsg, "Cannot dup2", Err);
- return false;
-}
-#endif
-
-static void TimeOutHandler(int Sig) {
-}
-
-static void SetMemoryLimits (unsigned size)
-{
-#if HAVE_SYS_RESOURCE_H && HAVE_GETRLIMIT && HAVE_SETRLIMIT
- struct rlimit r;
- __typeof__ (r.rlim_cur) limit = (__typeof__ (r.rlim_cur)) (size) * 1048576;
-
- // Heap size
- getrlimit (RLIMIT_DATA, &r);
- r.rlim_cur = limit;
- setrlimit (RLIMIT_DATA, &r);
-#ifdef RLIMIT_RSS
- // Resident set size.
- getrlimit (RLIMIT_RSS, &r);
- r.rlim_cur = limit;
- setrlimit (RLIMIT_RSS, &r);
-#endif
-#ifdef RLIMIT_AS // e.g. NetBSD doesn't have it.
- // Virtual memory.
- getrlimit (RLIMIT_AS, &r);
- r.rlim_cur = limit;
- setrlimit (RLIMIT_AS, &r);
-#endif
-#endif
-}
-
-bool
-Program::Execute(const Path &path, const char **args, const char **envp,
- const Path **redirects, unsigned memoryLimit,
- std::string *ErrMsg) {
- // If this OS has posix_spawn and there is no memory limit being implied, use
- // posix_spawn. It is more efficient than fork/exec.
-#ifdef HAVE_POSIX_SPAWN
- if (memoryLimit == 0) {
- posix_spawn_file_actions_t FileActions;
- posix_spawn_file_actions_init(&FileActions);
-
- if (redirects) {
- // Redirect stdin/stdout.
- if (RedirectIO_PS(redirects[0], 0, ErrMsg, FileActions) ||
- RedirectIO_PS(redirects[1], 1, ErrMsg, FileActions))
- return false;
- if (redirects[1] == 0 || redirects[2] == 0 ||
- *redirects[1] != *redirects[2]) {
- // Just redirect stderr
- if (RedirectIO_PS(redirects[2], 2, ErrMsg, FileActions)) return false;
- } else {
- // If stdout and stderr should go to the same place, redirect stderr
- // to the FD already open for stdout.
- if (int Err = posix_spawn_file_actions_adddup2(&FileActions, 1, 2))
- return !MakeErrMsg(ErrMsg, "Can't redirect stderr to stdout", Err);
- }
- }
-
- if (!envp)
-#if !defined(__APPLE__)
- envp = const_cast<const char **>(environ);
-#else
- // environ is missing in dylibs.
- envp = const_cast<const char **>(*_NSGetEnviron());
-#endif
-
- // Explicitly initialized to prevent what appears to be a valgrind false
- // positive.
- pid_t PID = 0;
- int Err = posix_spawn(&PID, path.c_str(), &FileActions, /*attrp*/0,
- const_cast<char **>(args), const_cast<char **>(envp));
-
- posix_spawn_file_actions_destroy(&FileActions);
-
- if (Err)
- return !MakeErrMsg(ErrMsg, "posix_spawn failed", Err);
-
- Data_ = reinterpret_cast<void*>(PID);
- return true;
- }
-#endif
-
- // Create a child process.
- int child = fork();
- switch (child) {
- // An error occured: Return to the caller.
- case -1:
- MakeErrMsg(ErrMsg, "Couldn't fork");
- return false;
-
- // Child process: Execute the program.
- case 0: {
- // Redirect file descriptors...
- if (redirects) {
- // Redirect stdin
- if (RedirectIO(redirects[0], 0, ErrMsg)) { return false; }
- // Redirect stdout
- if (RedirectIO(redirects[1], 1, ErrMsg)) { return false; }
- if (redirects[1] && redirects[2] &&
- *(redirects[1]) == *(redirects[2])) {
- // If stdout and stderr should go to the same place, redirect stderr
- // to the FD already open for stdout.
- if (-1 == dup2(1,2)) {
- MakeErrMsg(ErrMsg, "Can't redirect stderr to stdout");
- return false;
- }
- } else {
- // Just redirect stderr
- if (RedirectIO(redirects[2], 2, ErrMsg)) { return false; }
- }
- }
-
- // Set memory limits
- if (memoryLimit!=0) {
- SetMemoryLimits(memoryLimit);
- }
-
- // Execute!
- if (envp != 0)
- execve(path.c_str(),
- const_cast<char **>(args),
- const_cast<char **>(envp));
- else
- execv(path.c_str(),
- const_cast<char **>(args));
- // If the execve() failed, we should exit. Follow Unix protocol and
- // return 127 if the executable was not found, and 126 otherwise.
- // Use _exit rather than exit so that atexit functions and static
- // object destructors cloned from the parent process aren't
- // redundantly run, and so that any data buffered in stdio buffers
- // cloned from the parent aren't redundantly written out.
- _exit(errno == ENOENT ? 127 : 126);
- }
-
- // Parent process: Break out of the switch to do our processing.
- default:
- break;
- }
-
- Data_ = reinterpret_cast<void*>(child);
-
- return true;
-}
-
-int
-Program::Wait(const sys::Path &path,
- unsigned secondsToWait,
- std::string* ErrMsg)
-{
-#ifdef HAVE_SYS_WAIT_H
- struct sigaction Act, Old;
-
- if (Data_ == 0) {
- MakeErrMsg(ErrMsg, "Process not started!");
- return -1;
- }
-
- // Install a timeout handler. The handler itself does nothing, but the simple
- // fact of having a handler at all causes the wait below to return with EINTR,
- // unlike if we used SIG_IGN.
- if (secondsToWait) {
- memset(&Act, 0, sizeof(Act));
- Act.sa_handler = TimeOutHandler;
- sigemptyset(&Act.sa_mask);
- sigaction(SIGALRM, &Act, &Old);
- alarm(secondsToWait);
- }
-
- // Parent process: Wait for the child process to terminate.
- int status;
- uint64_t pid = reinterpret_cast<uint64_t>(Data_);
- pid_t child = static_cast<pid_t>(pid);
- while (waitpid(pid, &status, 0) != child)
- if (secondsToWait && errno == EINTR) {
- // Kill the child.
- kill(child, SIGKILL);
-
- // Turn off the alarm and restore the signal handler
- alarm(0);
- sigaction(SIGALRM, &Old, 0);
-
- // Wait for child to die
- if (wait(&status) != child)
- MakeErrMsg(ErrMsg, "Child timed out but wouldn't die");
- else
- MakeErrMsg(ErrMsg, "Child timed out", 0);
-
- return -1; // Timeout detected
- } else if (errno != EINTR) {
- MakeErrMsg(ErrMsg, "Error waiting for child process");
- return -1;
- }
-
- // We exited normally without timeout, so turn off the timer.
- if (secondsToWait) {
- alarm(0);
- sigaction(SIGALRM, &Old, 0);
- }
-
- // Return the proper exit status. Detect error conditions
- // so we can return -1 for them and set ErrMsg informatively.
- int result = 0;
- if (WIFEXITED(status)) {
- result = WEXITSTATUS(status);
-#ifdef HAVE_POSIX_SPAWN
- // The posix_spawn child process returns 127 on any kind of error.
- // Following the POSIX convention for command-line tools (which posix_spawn
- // itself apparently does not), check to see if the failure was due to some
- // reason other than the file not existing, and return 126 in this case.
- if (result == 127 && path.exists())
- result = 126;
-#endif
- if (result == 127) {
- if (ErrMsg)
- *ErrMsg = llvm::sys::StrError(ENOENT);
- return -1;
- }
- if (result == 126) {
- if (ErrMsg)
- *ErrMsg = "Program could not be executed";
- return -1;
- }
- } else if (WIFSIGNALED(status)) {
- if (ErrMsg) {
- *ErrMsg = strsignal(WTERMSIG(status));
-#ifdef WCOREDUMP
- if (WCOREDUMP(status))
- *ErrMsg += " (core dumped)";
-#endif
- }
- return -1;
- }
- return result;
-#else
- if (ErrMsg)
- *ErrMsg = "Program::Wait is not implemented on this platform yet!";
- return -1;
-#endif
-}
-
-bool
-Program::Kill(std::string* ErrMsg) {
- if (Data_ == 0) {
- MakeErrMsg(ErrMsg, "Process not started!");
- return true;
- }
-
- uint64_t pid64 = reinterpret_cast<uint64_t>(Data_);
- pid_t pid = static_cast<pid_t>(pid64);
-
- if (kill(pid, SIGKILL) != 0) {
- MakeErrMsg(ErrMsg, "The process couldn't be killed!");
- return true;
- }
-
- return false;
-}
-
-bool Program::ChangeStdinToBinary(){
- // Do nothing, as Unix doesn't differentiate between text and binary.
- return false;
-}
-
-bool Program::ChangeStdoutToBinary(){
- // Do nothing, as Unix doesn't differentiate between text and binary.
- return false;
-}
-
-bool Program::ChangeStderrToBinary(){
- // Do nothing, as Unix doesn't differentiate between text and binary.
- return false;
-}
-
-}
+++ /dev/null
-llvm/lib/System/Unix README
-===========================
-
-This directory provides implementations of the lib/System classes that
-are common to two or more variants of UNIX. For example, the directory
-structure underneath this directory could look like this:
-
-Unix - only code that is truly generic to all UNIX platforms
- Posix - code that is specific to Posix variants of UNIX
- SUS - code that is specific to the Single Unix Specification
- SysV - code that is specific to System V variants of UNIX
-
-As a rule, only those directories actually needing to be created should be
-created. Also, further subdirectories could be created to reflect versions of
-the various standards. For example, under SUS there could be v1, v2, and v3
-subdirectories to reflect the three major versions of SUS.
+++ /dev/null
-//= llvm/System/Unix/RWMutex.inc - Unix Reader/Writer Mutual Exclusion Lock =//
-//
-// 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 Unix specific (non-pthread) RWMutex class.
-//
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only generic UNIX code that
-//=== is guaranteed to work on *all* UNIX variants.
-//===----------------------------------------------------------------------===//
-
-namespace llvm {
-
-using namespace sys;
-
-RWMutexImpl::RWMutexImpl() { }
-
-RWMutexImpl::~RWMutexImpl() { }
-
-bool RWMutexImpl::reader_acquire() {
- return true;
-}
-
-bool RWMutexImpl::reader_release() {
- return true;
-}
-
-bool RWMutexImpl::writer_acquire() {
- return true;
-}
-
-bool RWMutexImpl::writer_release() {
- return true;
-}
-
-}
+++ /dev/null
-//===- Signals.cpp - Generic Unix Signals Implementation -----*- 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 some helpful functions for dealing with the possibility of
-// Unix signals occuring while your program is running.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Unix.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/System/Mutex.h"
-#include <vector>
-#include <algorithm>
-#if HAVE_EXECINFO_H
-# include <execinfo.h> // For backtrace().
-#endif
-#if HAVE_SIGNAL_H
-#include <signal.h>
-#endif
-#if HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#if HAVE_DLFCN_H && __GNUG__
-#include <dlfcn.h>
-#include <cxxabi.h>
-#endif
-using namespace llvm;
-
-static RETSIGTYPE SignalHandler(int Sig); // defined below.
-
-static SmartMutex<true> SignalsMutex;
-
-/// InterruptFunction - The function to call if ctrl-c is pressed.
-static void (*InterruptFunction)() = 0;
-
-static std::vector<sys::Path> FilesToRemove;
-static std::vector<std::pair<void(*)(void*), void*> > CallBacksToRun;
-
-// IntSigs - Signals that may interrupt the program at any time.
-static const int IntSigs[] = {
- SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGTERM, SIGUSR1, SIGUSR2
-};
-static const int *const IntSigsEnd =
- IntSigs + sizeof(IntSigs) / sizeof(IntSigs[0]);
-
-// KillSigs - Signals that are synchronous with the program that will cause it
-// to die.
-static const int KillSigs[] = {
- SIGILL, SIGTRAP, SIGABRT, SIGFPE, SIGBUS, SIGSEGV
-#ifdef SIGSYS
- , SIGSYS
-#endif
-#ifdef SIGXCPU
- , SIGXCPU
-#endif
-#ifdef SIGXFSZ
- , SIGXFSZ
-#endif
-#ifdef SIGEMT
- , SIGEMT
-#endif
-};
-static const int *const KillSigsEnd =
- KillSigs + sizeof(KillSigs) / sizeof(KillSigs[0]);
-
-static unsigned NumRegisteredSignals = 0;
-static struct {
- struct sigaction SA;
- int SigNo;
-} RegisteredSignalInfo[(sizeof(IntSigs)+sizeof(KillSigs))/sizeof(KillSigs[0])];
-
-
-static void RegisterHandler(int Signal) {
- assert(NumRegisteredSignals <
- sizeof(RegisteredSignalInfo)/sizeof(RegisteredSignalInfo[0]) &&
- "Out of space for signal handlers!");
-
- struct sigaction NewHandler;
-
- NewHandler.sa_handler = SignalHandler;
- NewHandler.sa_flags = SA_NODEFER|SA_RESETHAND;
- sigemptyset(&NewHandler.sa_mask);
-
- // Install the new handler, save the old one in RegisteredSignalInfo.
- sigaction(Signal, &NewHandler,
- &RegisteredSignalInfo[NumRegisteredSignals].SA);
- RegisteredSignalInfo[NumRegisteredSignals].SigNo = Signal;
- ++NumRegisteredSignals;
-}
-
-static void RegisterHandlers() {
- // If the handlers are already registered, we're done.
- if (NumRegisteredSignals != 0) return;
-
- std::for_each(IntSigs, IntSigsEnd, RegisterHandler);
- std::for_each(KillSigs, KillSigsEnd, RegisterHandler);
-}
-
-static void UnregisterHandlers() {
- // Restore all of the signal handlers to how they were before we showed up.
- for (unsigned i = 0, e = NumRegisteredSignals; i != e; ++i)
- sigaction(RegisteredSignalInfo[i].SigNo,
- &RegisteredSignalInfo[i].SA, 0);
- NumRegisteredSignals = 0;
-}
-
-
-/// RemoveFilesToRemove - Process the FilesToRemove list. This function
-/// should be called with the SignalsMutex lock held.
-static void RemoveFilesToRemove() {
- while (!FilesToRemove.empty()) {
- FilesToRemove.back().eraseFromDisk(true);
- FilesToRemove.pop_back();
- }
-}
-
-// SignalHandler - The signal handler that runs.
-static RETSIGTYPE SignalHandler(int Sig) {
- // Restore the signal behavior to default, so that the program actually
- // crashes when we return and the signal reissues. This also ensures that if
- // we crash in our signal handler that the program will terminate immediately
- // instead of recursing in the signal handler.
- UnregisterHandlers();
-
- // Unmask all potentially blocked kill signals.
- sigset_t SigMask;
- sigfillset(&SigMask);
- sigprocmask(SIG_UNBLOCK, &SigMask, 0);
-
- SignalsMutex.acquire();
- RemoveFilesToRemove();
-
- if (std::find(IntSigs, IntSigsEnd, Sig) != IntSigsEnd) {
- if (InterruptFunction) {
- void (*IF)() = InterruptFunction;
- SignalsMutex.release();
- InterruptFunction = 0;
- IF(); // run the interrupt function.
- return;
- }
-
- SignalsMutex.release();
- raise(Sig); // Execute the default handler.
- return;
- }
-
- SignalsMutex.release();
-
- // Otherwise if it is a fault (like SEGV) run any handler.
- for (unsigned i = 0, e = CallBacksToRun.size(); i != e; ++i)
- CallBacksToRun[i].first(CallBacksToRun[i].second);
-}
-
-void llvm::sys::RunInterruptHandlers() {
- SignalsMutex.acquire();
- RemoveFilesToRemove();
- SignalsMutex.release();
-}
-
-void llvm::sys::SetInterruptFunction(void (*IF)()) {
- SignalsMutex.acquire();
- InterruptFunction = IF;
- SignalsMutex.release();
- RegisterHandlers();
-}
-
-// RemoveFileOnSignal - The public API
-bool llvm::sys::RemoveFileOnSignal(const sys::Path &Filename,
- std::string* ErrMsg) {
- SignalsMutex.acquire();
- FilesToRemove.push_back(Filename);
-
- SignalsMutex.release();
-
- RegisterHandlers();
- return false;
-}
-
-// DontRemoveFileOnSignal - The public API
-void llvm::sys::DontRemoveFileOnSignal(const sys::Path &Filename) {
- SignalsMutex.acquire();
- std::vector<sys::Path>::reverse_iterator I =
- std::find(FilesToRemove.rbegin(), FilesToRemove.rend(), Filename);
- if (I != FilesToRemove.rend())
- FilesToRemove.erase(I.base()-1);
- SignalsMutex.release();
-}
-
-/// AddSignalHandler - Add a function to be called when a signal is delivered
-/// to the process. The handler can have a cookie passed to it to identify
-/// what instance of the handler it is.
-void llvm::sys::AddSignalHandler(void (*FnPtr)(void *), void *Cookie) {
- CallBacksToRun.push_back(std::make_pair(FnPtr, Cookie));
- RegisterHandlers();
-}
-
-
-// PrintStackTrace - In the case of a program crash or fault, print out a stack
-// trace so that the user has an indication of why and where we died.
-//
-// On glibc systems we have the 'backtrace' function, which works nicely, but
-// doesn't demangle symbols.
-static void PrintStackTrace(void *) {
-#ifdef HAVE_BACKTRACE
- static void* StackTrace[256];
- // Use backtrace() to output a backtrace on Linux systems with glibc.
- int depth = backtrace(StackTrace,
- static_cast<int>(array_lengthof(StackTrace)));
-#if HAVE_DLFCN_H && __GNUG__
- int width = 0;
- for (int i = 0; i < depth; ++i) {
- Dl_info dlinfo;
- dladdr(StackTrace[i], &dlinfo);
- const char* name = strrchr(dlinfo.dli_fname, '/');
-
- int nwidth;
- if (name == NULL) nwidth = strlen(dlinfo.dli_fname);
- else nwidth = strlen(name) - 1;
-
- if (nwidth > width) width = nwidth;
- }
-
- for (int i = 0; i < depth; ++i) {
- Dl_info dlinfo;
- dladdr(StackTrace[i], &dlinfo);
-
- fprintf(stderr, "%-2d", i);
-
- const char* name = strrchr(dlinfo.dli_fname, '/');
- if (name == NULL) fprintf(stderr, " %-*s", width, dlinfo.dli_fname);
- else fprintf(stderr, " %-*s", width, name+1);
-
- fprintf(stderr, " %#0*lx",
- (int)(sizeof(void*) * 2) + 2, (unsigned long)StackTrace[i]);
-
- if (dlinfo.dli_sname != NULL) {
- int res;
- fputc(' ', stderr);
- char* d = abi::__cxa_demangle(dlinfo.dli_sname, NULL, NULL, &res);
- if (d == NULL) fputs(dlinfo.dli_sname, stderr);
- else fputs(d, stderr);
- free(d);
-
- fprintf(stderr, " + %tu",(char*)StackTrace[i]-(char*)dlinfo.dli_saddr);
- }
- fputc('\n', stderr);
- }
-#else
- backtrace_symbols_fd(StackTrace, depth, STDERR_FILENO);
-#endif
-#endif
-}
-
-/// PrintStackTraceOnErrorSignal - When an error signal (such as SIBABRT or
-/// SIGSEGV) is delivered to the process, print a stack trace and then exit.
-void llvm::sys::PrintStackTraceOnErrorSignal() {
- AddSignalHandler(PrintStackTrace, 0);
-}
-
-
-/***/
-
-// On Darwin, raise sends a signal to the main thread instead of the current
-// thread. This has the unfortunate effect that assert() and abort() will end up
-// bypassing our crash recovery attempts. We work around this for anything in
-// the same linkage unit by just defining our own versions of the assert handler
-// and abort.
-
-#ifdef __APPLE__
-
-int raise(int sig) {
- return pthread_kill(pthread_self(), sig);
-}
-
-void __assert_rtn(const char *func,
- const char *file,
- int line,
- const char *expr) {
- if (func)
- fprintf(stderr, "Assertion failed: (%s), function %s, file %s, line %d.\n",
- expr, func, file, line);
- else
- fprintf(stderr, "Assertion failed: (%s), file %s, line %d.\n",
- expr, file, line);
- abort();
-}
-
-#include <signal.h>
-#include <pthread.h>
-
-void abort() {
- raise(SIGABRT);
- usleep(1000);
- __builtin_trap();
-}
-
-#endif
+++ /dev/null
-//=== llvm/System/Unix/ThreadLocal.inc - Unix Thread Local Data -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the Unix specific (non-pthread) ThreadLocal class.
-//
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only generic UNIX code that
-//=== is guaranteed to work on *all* UNIX variants.
-//===----------------------------------------------------------------------===//
-
-namespace llvm {
-using namespace sys;
-ThreadLocalImpl::ThreadLocalImpl() { }
-ThreadLocalImpl::~ThreadLocalImpl() { }
-void ThreadLocalImpl::setInstance(const void* d) { data = const_cast<void*>(d);}
-const void* ThreadLocalImpl::getInstance() { return data; }
-void ThreadLocalImpl::removeInstance() { setInstance(0); }
-}
+++ /dev/null
-//===- Unix/TimeValue.cpp - Unix TimeValue Implementation -------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the Unix specific portion of the TimeValue class.
-//
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only generic UNIX code that
-//=== is guaranteed to work on *all* UNIX variants.
-//===----------------------------------------------------------------------===//
-
-#include "Unix.h"
-
-namespace llvm {
- using namespace sys;
-
-std::string TimeValue::str() const {
- char buffer[32];
-
- time_t ourTime = time_t(this->toEpochTime());
-#ifdef __hpux
-// note that the following line needs -D_REENTRANT on HP-UX to be picked up
- asctime_r(localtime(&ourTime), buffer);
-#else
- ::asctime_r(::localtime(&ourTime), buffer);
-#endif
-
- std::string result(buffer);
- return result.substr(0,24);
-}
-
-TimeValue TimeValue::now() {
- struct timeval the_time;
- timerclear(&the_time);
- if (0 != ::gettimeofday(&the_time,0)) {
- // This is *really* unlikely to occur because the only gettimeofday
- // errors concern the timezone parameter which we're passing in as 0.
- // In the unlikely case it does happen, just return MinTime, no error
- // message needed.
- return MinTime;
- }
-
- return TimeValue(
- static_cast<TimeValue::SecondsType>( the_time.tv_sec + PosixZeroTime.seconds_ ),
- static_cast<TimeValue::NanoSecondsType>( the_time.tv_usec *
- NANOSECONDS_PER_MICROSECOND ) );
-}
-
-}
+++ /dev/null
-//===- llvm/System/Unix/Unix.h - Common Unix Include File -------*- 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 things specific to Unix implementations.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SYSTEM_UNIX_UNIX_H
-#define LLVM_SYSTEM_UNIX_UNIX_H
-
-//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only generic UNIX code that
-//=== is guaranteed to work on all UNIX variants.
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Config/config.h" // Get autoconf configuration settings
-#include "llvm/System/Errno.h"
-#include <cstdlib>
-#include <cstdio>
-#include <cstring>
-#include <cerrno>
-#include <string>
-#include <algorithm>
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-
-#ifdef HAVE_ASSERT_H
-#include <assert.h>
-#endif
-
-#ifdef TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# ifdef HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
-
-#ifdef HAVE_SYS_WAIT_H
-# include <sys/wait.h>
-#endif
-
-#ifndef WEXITSTATUS
-# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
-#endif
-
-#ifndef WIFEXITED
-# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
-#endif
-
-/// This function builds an error message into \p ErrMsg using the \p prefix
-/// string and the Unix error number given by \p errnum. If errnum is -1, the
-/// default then the value of errno is used.
-/// @brief Make an error message
-///
-/// If the error number can be converted to a string, it will be
-/// separated from prefix by ": ".
-static inline bool MakeErrMsg(
- std::string* ErrMsg, const std::string& prefix, int errnum = -1) {
- if (!ErrMsg)
- return true;
- if (errnum == -1)
- errnum = errno;
- *ErrMsg = prefix + ": " + llvm::sys::StrError(errnum);
- return true;
-}
-
-#endif
+++ /dev/null
-//===- llvm/System/Unix/system_error.inc - Unix error_code ------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides the Unix specific implementation of the error_code
-// and error_condition classes.
-//
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only generic UNIX code that
-//=== is guaranteed to work on *all* UNIX variants.
-//===----------------------------------------------------------------------===//
-
-using namespace llvm;
-
-std::string
-_system_error_category::message(int ev) const {
- return _do_message::message(ev);
-}
-
-error_condition
-_system_error_category::default_error_condition(int ev) const {
-#ifdef ELAST
- if (ev > ELAST)
- return error_condition(ev, system_category());
-#endif // ELAST
- return error_condition(ev, generic_category());
-}
+++ /dev/null
-//===-- Valgrind.cpp - Implement Valgrind communication ---------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Defines Valgrind communication methods, if HAVE_VALGRIND_VALGRIND_H is
-// defined. If we have valgrind.h but valgrind isn't running, its macros are
-// no-ops.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/System/Valgrind.h"
-#include "llvm/Config/config.h"
-
-#if HAVE_VALGRIND_VALGRIND_H
-#include <valgrind/valgrind.h>
-
-static bool InitNotUnderValgrind() {
- return !RUNNING_ON_VALGRIND;
-}
-
-// This bool is negated from what we'd expect because code may run before it
-// gets initialized. If that happens, it will appear to be 0 (false), and we
-// want that to cause the rest of the code in this file to run the
-// Valgrind-provided macros.
-static const bool NotUnderValgrind = InitNotUnderValgrind();
-
-bool llvm::sys::RunningOnValgrind() {
- if (NotUnderValgrind)
- return false;
- return RUNNING_ON_VALGRIND;
-}
-
-void llvm::sys::ValgrindDiscardTranslations(const void *Addr, size_t Len) {
- if (NotUnderValgrind)
- return;
-
- VALGRIND_DISCARD_TRANSLATIONS(Addr, Len);
-}
-
-#else // !HAVE_VALGRIND_VALGRIND_H
-
-bool llvm::sys::RunningOnValgrind() {
- return false;
-}
-
-void llvm::sys::ValgrindDiscardTranslations(const void *Addr, size_t Len) {
-}
-
-#endif // !HAVE_VALGRIND_VALGRIND_H
+++ /dev/null
-//===-- Alarm.inc - Implement Win32 Alarm Support ---------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the Win32 Alarm support.
-//
-//===----------------------------------------------------------------------===//
-
-#include <cassert>
-using namespace llvm;
-
-/// NestedSOI - Sanity check. Alarms cannot be nested or run in parallel.
-/// This ensures that they never do.
-static bool NestedSOI = false;
-
-void sys::SetupAlarm(unsigned seconds) {
- assert(!NestedSOI && "sys::SetupAlarm calls cannot be nested!");
- NestedSOI = true;
- // FIXME: Implement for Win32
-}
-
-void sys::TerminateAlarm() {
- assert(NestedSOI && "sys::TerminateAlarm called without sys::SetupAlarm!");
- // FIXME: Implement for Win32
- NestedSOI = false;
-}
-
-int sys::AlarmStatus() {
- // FIXME: Implement for Win32
- return 0;
-}
-
-// Don't pull in all of the Windows headers.
-extern "C" void __stdcall Sleep(unsigned long);
-
-void sys::Sleep(unsigned n) {
- ::Sleep(n*1000);
-}
+++ /dev/null
-//===- Win32/DynamicLibrary.cpp - Win32 DL Implementation -------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides the Win32 specific implementation of DynamicLibrary.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Win32.h"
-
-#ifdef __MINGW32__
- #include <imagehlp.h>
-#else
- #include <dbghelp.h>
-#endif
-
-#ifdef _MSC_VER
- #include <ntverp.h>
-#endif
-
-#ifdef __MINGW32__
- #if (HAVE_LIBIMAGEHLP != 1)
- #error "libimagehlp.a should be present"
- #endif
-#else
- #pragma comment(lib, "dbghelp.lib")
-#endif
-
-namespace llvm {
-using namespace sys;
-
-//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only Win32 specific code
-//=== and must not be UNIX code.
-//===----------------------------------------------------------------------===//
-
-static std::vector<HMODULE> OpenedHandles;
-
-#ifdef _WIN64
- typedef DWORD64 ModuleBaseType;
-#else
- typedef ULONG ModuleBaseType;
-#endif
-
-extern "C" {
-// Use old callback if:
-// - Not using Visual Studio
-// - Visual Studio 2005 or earlier but only if we are not using the Windows SDK
-// or Windows SDK version is older than 6.0
-// Use new callback if:
-// - Newer Visual Studio (comes with newer SDK).
-// - Visual Studio 2005 with Windows SDK 6.0+
-#if !defined(_MSC_VER) || _MSC_VER < 1500 && (!defined(VER_PRODUCTBUILD) || VER_PRODUCTBUILD < 6000)
- static BOOL CALLBACK ELM_Callback(PSTR ModuleName,
- ModuleBaseType ModuleBase,
- ULONG ModuleSize,
- PVOID UserContext)
-#else
- static BOOL CALLBACK ELM_Callback(PCSTR ModuleName,
- ModuleBaseType ModuleBase,
- ULONG ModuleSize,
- PVOID UserContext)
-#endif
- {
- // Ignore VC++ runtimes prior to 7.1. Somehow some of them get loaded
- // into the process.
- if (stricmp(ModuleName, "msvci70") != 0 &&
- stricmp(ModuleName, "msvcirt") != 0 &&
- stricmp(ModuleName, "msvcp50") != 0 &&
- stricmp(ModuleName, "msvcp60") != 0 &&
- stricmp(ModuleName, "msvcp70") != 0 &&
- stricmp(ModuleName, "msvcr70") != 0 &&
-#ifndef __MINGW32__
- // Mingw32 uses msvcrt.dll by default. Don't ignore it.
- // Otherwise, user should be aware, what he's doing :)
- stricmp(ModuleName, "msvcrt") != 0 &&
-#endif
- stricmp(ModuleName, "msvcrt20") != 0 &&
- stricmp(ModuleName, "msvcrt40") != 0) {
- OpenedHandles.push_back((HMODULE)ModuleBase);
- }
- return TRUE;
- }
-}
-
-bool DynamicLibrary::LoadLibraryPermanently(const char *filename,
- std::string *ErrMsg) {
- if (filename) {
- HMODULE a_handle = LoadLibrary(filename);
-
- if (a_handle == 0)
- return MakeErrMsg(ErrMsg, std::string(filename) + ": Can't open : ");
-
- OpenedHandles.push_back(a_handle);
- } else {
- // When no file is specified, enumerate all DLLs and EXEs in the
- // process.
- EnumerateLoadedModules(GetCurrentProcess(), ELM_Callback, 0);
- }
-
- // Because we don't remember the handle, we will never free it; hence,
- // it is loaded permanently.
- return false;
-}
-
-// Stack probing routines are in the support library (e.g. libgcc), but we don't
-// have dynamic linking on windows. Provide a hook.
-#if defined(__MINGW32__) || defined (_MSC_VER)
- #define EXPLICIT_SYMBOL(SYM) \
- if (!strcmp(symbolName, #SYM)) return (void*)&SYM
- #define EXPLICIT_SYMBOL2(SYMFROM, SYMTO) \
- if (!strcmp(symbolName, #SYMFROM)) return (void*)&SYMTO
- #define EXPLICIT_SYMBOL_DEF(SYM) \
- extern "C" { extern void *SYM; }
-
- #if defined(__MINGW32__)
- EXPLICIT_SYMBOL_DEF(_alloca)
- EXPLICIT_SYMBOL_DEF(__main)
- EXPLICIT_SYMBOL_DEF(__ashldi3)
- EXPLICIT_SYMBOL_DEF(__ashrdi3)
- EXPLICIT_SYMBOL_DEF(__cmpdi2)
- EXPLICIT_SYMBOL_DEF(__divdi3)
- EXPLICIT_SYMBOL_DEF(__fixdfdi)
- EXPLICIT_SYMBOL_DEF(__fixsfdi)
- EXPLICIT_SYMBOL_DEF(__fixunsdfdi)
- EXPLICIT_SYMBOL_DEF(__fixunssfdi)
- EXPLICIT_SYMBOL_DEF(__floatdidf)
- EXPLICIT_SYMBOL_DEF(__floatdisf)
- EXPLICIT_SYMBOL_DEF(__lshrdi3)
- EXPLICIT_SYMBOL_DEF(__moddi3)
- EXPLICIT_SYMBOL_DEF(__udivdi3)
- EXPLICIT_SYMBOL_DEF(__umoddi3)
- #elif defined(_MSC_VER)
- EXPLICIT_SYMBOL_DEF(_alloca_probe)
- #endif
-#endif
-
-void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) {
- // First check symbols added via AddSymbol().
- if (ExplicitSymbols) {
- std::map<std::string, void *>::iterator I =
- ExplicitSymbols->find(symbolName);
- std::map<std::string, void *>::iterator E = ExplicitSymbols->end();
- if (I != E)
- return I->second;
- }
-
- // Now search the libraries.
- for (std::vector<HMODULE>::iterator I = OpenedHandles.begin(),
- E = OpenedHandles.end(); I != E; ++I) {
- FARPROC ptr = GetProcAddress((HMODULE)*I, symbolName);
- if (ptr) {
- return (void *) ptr;
- }
- }
-
-#if defined(__MINGW32__)
- {
- EXPLICIT_SYMBOL(_alloca);
- EXPLICIT_SYMBOL(__main);
- EXPLICIT_SYMBOL(__ashldi3);
- EXPLICIT_SYMBOL(__ashrdi3);
- EXPLICIT_SYMBOL(__cmpdi2);
- EXPLICIT_SYMBOL(__divdi3);
- EXPLICIT_SYMBOL(__fixdfdi);
- EXPLICIT_SYMBOL(__fixsfdi);
- EXPLICIT_SYMBOL(__fixunsdfdi);
- EXPLICIT_SYMBOL(__fixunssfdi);
- EXPLICIT_SYMBOL(__floatdidf);
- EXPLICIT_SYMBOL(__floatdisf);
- EXPLICIT_SYMBOL(__lshrdi3);
- EXPLICIT_SYMBOL(__moddi3);
- EXPLICIT_SYMBOL(__udivdi3);
- EXPLICIT_SYMBOL(__umoddi3);
-
- EXPLICIT_SYMBOL2(alloca, _alloca);
-#undef EXPLICIT_SYMBOL
-#undef EXPLICIT_SYMBOL2
-#undef EXPLICIT_SYMBOL_DEF
- }
-#elif defined(_MSC_VER)
- {
- EXPLICIT_SYMBOL2(alloca, _alloca_probe);
- EXPLICIT_SYMBOL2(_alloca, _alloca_probe);
-#undef EXPLICIT_SYMBOL
-#undef EXPLICIT_SYMBOL2
-#undef EXPLICIT_SYMBOL_DEF
- }
-#endif
-
- return 0;
-}
-
-}
-
+++ /dev/null
-//===- llvm/System/Win32/Host.inc -------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the Win32 Host support.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Win32.h"
-#include <cstdio>
-#include <string>
-
-using namespace llvm;
-
-std::string sys::getHostTriple() {
- // FIXME: Adapt to running version.
- return LLVM_HOSTTRIPLE;
-}
+++ /dev/null
-//===- Win32/Memory.cpp - Win32 Memory Implementation -----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides the Win32 specific implementation of various Memory
-// management utilities
-//
-//===----------------------------------------------------------------------===//
-
-#include "Win32.h"
-#include "llvm/System/DataTypes.h"
-#include "llvm/System/Process.h"
-
-namespace llvm {
-using namespace sys;
-
-//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only Win32 specific code
-//=== and must not be UNIX code
-//===----------------------------------------------------------------------===//
-
-MemoryBlock Memory::AllocateRWX(size_t NumBytes,
- const MemoryBlock *NearBlock,
- std::string *ErrMsg) {
- if (NumBytes == 0) return MemoryBlock();
-
- static const size_t pageSize = Process::GetPageSize();
- size_t NumPages = (NumBytes+pageSize-1)/pageSize;
-
- //FIXME: support NearBlock if ever needed on Win64.
-
- void *pa = VirtualAlloc(NULL, NumPages*pageSize, MEM_COMMIT,
- PAGE_EXECUTE_READWRITE);
- if (pa == NULL) {
- MakeErrMsg(ErrMsg, "Can't allocate RWX Memory: ");
- return MemoryBlock();
- }
-
- MemoryBlock result;
- result.Address = pa;
- result.Size = NumPages*pageSize;
- return result;
-}
-
-bool Memory::ReleaseRWX(MemoryBlock &M, std::string *ErrMsg) {
- if (M.Address == 0 || M.Size == 0) return false;
- if (!VirtualFree(M.Address, 0, MEM_RELEASE))
- return MakeErrMsg(ErrMsg, "Can't release RWX Memory: ");
- return false;
-}
-
-bool Memory::setWritable(MemoryBlock &M, std::string *ErrMsg) {
- return true;
-}
-
-bool Memory::setExecutable(MemoryBlock &M, std::string *ErrMsg) {
- return false;
-}
-
-bool Memory::setRangeWritable(const void *Addr, size_t Size) {
- return true;
-}
-
-bool Memory::setRangeExecutable(const void *Addr, size_t Size) {
- return false;
-}
-
-}
+++ /dev/null
-//===- llvm/System/Win32/Mutex.inc - Win32 Mutex Implementation -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the Win32 specific (non-pthread) Mutex class.
-//
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only generic Win32 code that
-//=== is guaranteed to work on *all* Win32 variants.
-//===----------------------------------------------------------------------===//
-
-#include "Win32.h"
-#include "llvm/System/Mutex.h"
-
-namespace llvm {
-using namespace sys;
-
-MutexImpl::MutexImpl(bool /*recursive*/)
-{
- data_ = new CRITICAL_SECTION;
- InitializeCriticalSection((LPCRITICAL_SECTION)data_);
-}
-
-MutexImpl::~MutexImpl()
-{
- DeleteCriticalSection((LPCRITICAL_SECTION)data_);
- delete (LPCRITICAL_SECTION)data_;
- data_ = 0;
-}
-
-bool
-MutexImpl::acquire()
-{
- EnterCriticalSection((LPCRITICAL_SECTION)data_);
- return true;
-}
-
-bool
-MutexImpl::release()
-{
- LeaveCriticalSection((LPCRITICAL_SECTION)data_);
- return true;
-}
-
-bool
-MutexImpl::tryacquire()
-{
- return TryEnterCriticalSection((LPCRITICAL_SECTION)data_);
-}
-
-}
+++ /dev/null
-//===- llvm/System/Win32/Path.cpp - Win32 Path Implementation ---*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides the Win32 specific implementation of the Path class.
-//
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only generic Win32 code that
-//=== is guaranteed to work on *all* Win32 variants.
-//===----------------------------------------------------------------------===//
-
-#include "Win32.h"
-#include <malloc.h>
-#include <cstdio>
-
-// We need to undo a macro defined in Windows.h, otherwise we won't compile:
-#undef CopyFile
-#undef GetCurrentDirectory
-
-// Windows happily accepts either forward or backward slashes, though any path
-// returned by a Win32 API will have backward slashes. As LLVM code basically
-// assumes forward slashes are used, backward slashs are converted where they
-// can be introduced into a path.
-//
-// Another invariant is that a path ends with a slash if and only if the path
-// is a root directory. Any other use of a trailing slash is stripped. Unlike
-// in Unix, Windows has a rather complicated notion of a root path and this
-// invariant helps simply the code.
-
-static void FlipBackSlashes(std::string& s) {
- for (size_t i = 0; i < s.size(); i++)
- if (s[i] == '\\')
- s[i] = '/';
-}
-
-namespace llvm {
-namespace sys {
-
-const char PathSeparator = ';';
-
-StringRef Path::GetEXESuffix() {
- return "exe";
-}
-
-Path::Path(llvm::StringRef p)
- : path(p) {
- FlipBackSlashes(path);
-}
-
-Path::Path(const char *StrStart, unsigned StrLen)
- : path(StrStart, StrLen) {
- FlipBackSlashes(path);
-}
-
-Path&
-Path::operator=(StringRef that) {
- path.assign(that.data(), that.size());
- FlipBackSlashes(path);
- return *this;
-}
-
-// push_back 0 on create, and pop_back on delete.
-struct ScopedNullTerminator {
- std::string &str;
- ScopedNullTerminator(std::string &s) : str(s) { str.push_back(0); }
- ~ScopedNullTerminator() {
- // str.pop_back(); But wait, C++03 doesn't have this...
- assert(!str.empty() && str[str.size() - 1] == 0
- && "Null char not present!");
- str.resize(str.size() - 1);
- }
-};
-
-bool
-Path::isValid() const {
- if (path.empty())
- return false;
-
- // If there is a colon, it must be the second character, preceded by a letter
- // and followed by something.
- size_t len = path.size();
- // This code assumes that path is null terminated, so make sure it is.
- ScopedNullTerminator snt(path);
- size_t pos = path.rfind(':',len);
- size_t rootslash = 0;
- if (pos != std::string::npos) {
- if (pos != 1 || !isalpha(path[0]) || len < 3)
- return false;
- rootslash = 2;
- }
-
- // Look for a UNC path, and if found adjust our notion of the root slash.
- if (len > 3 && path[0] == '/' && path[1] == '/') {
- rootslash = path.find('/', 2);
- if (rootslash == std::string::npos)
- rootslash = 0;
- }
-
- // Check for illegal characters.
- if (path.find_first_of("\\<>\"|\001\002\003\004\005\006\007\010\011\012"
- "\013\014\015\016\017\020\021\022\023\024\025\026"
- "\027\030\031\032\033\034\035\036\037")
- != std::string::npos)
- return false;
-
- // Remove trailing slash, unless it's a root slash.
- if (len > rootslash+1 && path[len-1] == '/')
- path.erase(--len);
-
- // Check each component for legality.
- for (pos = 0; pos < len; ++pos) {
- // A component may not end in a space.
- if (path[pos] == ' ') {
- if (path[pos+1] == '/' || path[pos+1] == '\0')
- return false;
- }
-
- // A component may not end in a period.
- if (path[pos] == '.') {
- if (path[pos+1] == '/' || path[pos+1] == '\0') {
- // Unless it is the pseudo-directory "."...
- if (pos == 0 || path[pos-1] == '/' || path[pos-1] == ':')
- return true;
- // or "..".
- if (pos > 0 && path[pos-1] == '.') {
- if (pos == 1 || path[pos-2] == '/' || path[pos-2] == ':')
- return true;
- }
- return false;
- }
- }
- }
-
- return true;
-}
-
-void Path::makeAbsolute() {
- TCHAR FullPath[MAX_PATH + 1] = {0};
- LPTSTR FilePart = NULL;
-
- DWORD RetLength = ::GetFullPathNameA(path.c_str(),
- sizeof(FullPath)/sizeof(FullPath[0]),
- FullPath, &FilePart);
-
- if (0 == RetLength) {
- // FIXME: Report the error GetLastError()
- assert(0 && "Unable to make absolute path!");
- } else if (RetLength > MAX_PATH) {
- // FIXME: Report too small buffer (needed RetLength bytes).
- assert(0 && "Unable to make absolute path!");
- } else {
- path = FullPath;
- }
-}
-
-bool
-Path::isAbsolute(const char *NameStart, unsigned NameLen) {
- assert(NameStart);
- // FIXME: This does not handle correctly an absolute path starting from
- // a drive letter or in UNC format.
- switch (NameLen) {
- case 0:
- return false;
- case 1:
- case 2:
- return NameStart[0] == '/';
- default:
- return
- (NameStart[0] == '/' || (NameStart[1] == ':' && NameStart[2] == '/')) ||
- (NameStart[0] == '\\' || (NameStart[1] == ':' && NameStart[2] == '\\'));
- }
-}
-
-bool
-Path::isAbsolute() const {
- // FIXME: This does not handle correctly an absolute path starting from
- // a drive letter or in UNC format.
- switch (path.length()) {
- case 0:
- return false;
- case 1:
- case 2:
- return path[0] == '/';
- default:
- return path[0] == '/' || (path[1] == ':' && path[2] == '/');
- }
-}
-
-static Path *TempDirectory;
-
-Path
-Path::GetTemporaryDirectory(std::string* ErrMsg) {
- if (TempDirectory)
- return *TempDirectory;
-
- char pathname[MAX_PATH];
- if (!GetTempPath(MAX_PATH, pathname)) {
- if (ErrMsg)
- *ErrMsg = "Can't determine temporary directory";
- return Path();
- }
-
- Path result;
- result.set(pathname);
-
- // Append a subdirectory passed on our process id so multiple LLVMs don't
- // step on each other's toes.
-#ifdef __MINGW32__
- // Mingw's Win32 header files are broken.
- sprintf(pathname, "LLVM_%u", unsigned(GetCurrentProcessId()));
-#else
- sprintf(pathname, "LLVM_%u", GetCurrentProcessId());
-#endif
- result.appendComponent(pathname);
-
- // If there's a directory left over from a previous LLVM execution that
- // happened to have the same process id, get rid of it.
- result.eraseFromDisk(true);
-
- // And finally (re-)create the empty directory.
- result.createDirectoryOnDisk(false);
- TempDirectory = new Path(result);
- return *TempDirectory;
-}
-
-// FIXME: the following set of functions don't map to Windows very well.
-Path
-Path::GetRootDirectory() {
- // This is the only notion that that Windows has of a root directory. Nothing
- // is here except for drives.
- return Path("file:///");
-}
-
-void
-Path::GetSystemLibraryPaths(std::vector<sys::Path>& Paths) {
- char buff[MAX_PATH];
- // Generic form of C:\Windows\System32
- HRESULT res = SHGetFolderPathA(NULL,
- CSIDL_FLAG_CREATE | CSIDL_SYSTEM,
- NULL,
- SHGFP_TYPE_CURRENT,
- buff);
- if (res != S_OK) {
- assert(0 && "Failed to get system directory");
- return;
- }
- Paths.push_back(sys::Path(buff));
-
- // Reset buff.
- buff[0] = 0;
- // Generic form of C:\Windows
- res = SHGetFolderPathA(NULL,
- CSIDL_FLAG_CREATE | CSIDL_WINDOWS,
- NULL,
- SHGFP_TYPE_CURRENT,
- buff);
- if (res != S_OK) {
- assert(0 && "Failed to get windows directory");
- return;
- }
- Paths.push_back(sys::Path(buff));
-}
-
-void
-Path::GetBitcodeLibraryPaths(std::vector<sys::Path>& Paths) {
- char * env_var = getenv("LLVM_LIB_SEARCH_PATH");
- if (env_var != 0) {
- getPathList(env_var,Paths);
- }
-#ifdef LLVM_LIBDIR
- {
- Path tmpPath;
- if (tmpPath.set(LLVM_LIBDIR))
- if (tmpPath.canRead())
- Paths.push_back(tmpPath);
- }
-#endif
- GetSystemLibraryPaths(Paths);
-}
-
-Path
-Path::GetLLVMDefaultConfigDir() {
- Path ret = GetUserHomeDirectory();
- if (!ret.appendComponent(".llvm"))
- assert(0 && "Failed to append .llvm");
- return ret;
-}
-
-Path
-Path::GetUserHomeDirectory() {
- char buff[MAX_PATH];
- HRESULT res = SHGetFolderPathA(NULL,
- CSIDL_FLAG_CREATE | CSIDL_APPDATA,
- NULL,
- SHGFP_TYPE_CURRENT,
- buff);
- if (res != S_OK)
- assert(0 && "Failed to get user home directory");
- return Path(buff);
-}
-
-Path
-Path::GetCurrentDirectory() {
- char pathname[MAX_PATH];
- ::GetCurrentDirectoryA(MAX_PATH,pathname);
- return Path(pathname);
-}
-
-/// GetMainExecutable - Return the path to the main executable, given the
-/// value of argv[0] from program startup.
-Path Path::GetMainExecutable(const char *argv0, void *MainAddr) {
- char pathname[MAX_PATH];
- DWORD ret = ::GetModuleFileNameA(NULL, pathname, MAX_PATH);
- return ret != MAX_PATH ? Path(pathname) : Path();
-}
-
-
-// FIXME: the above set of functions don't map to Windows very well.
-
-
-StringRef Path::getDirname() const {
- return getDirnameCharSep(path, "/");
-}
-
-StringRef
-Path::getBasename() const {
- // Find the last slash
- size_t slash = path.rfind('/');
- if (slash == std::string::npos)
- slash = 0;
- else
- slash++;
-
- size_t dot = path.rfind('.');
- if (dot == std::string::npos || dot < slash)
- return StringRef(path).substr(slash);
- else
- return StringRef(path).substr(slash, dot - slash);
-}
-
-StringRef
-Path::getSuffix() const {
- // Find the last slash
- size_t slash = path.rfind('/');
- if (slash == std::string::npos)
- slash = 0;
- else
- slash++;
-
- size_t dot = path.rfind('.');
- if (dot == std::string::npos || dot < slash)
- return StringRef("");
- else
- return StringRef(path).substr(dot + 1);
-}
-
-bool
-Path::exists() const {
- DWORD attr = GetFileAttributes(path.c_str());
- return attr != INVALID_FILE_ATTRIBUTES;
-}
-
-bool
-Path::isDirectory() const {
- DWORD attr = GetFileAttributes(path.c_str());
- return (attr != INVALID_FILE_ATTRIBUTES) &&
- (attr & FILE_ATTRIBUTE_DIRECTORY);
-}
-
-bool
-Path::isSymLink() const {
- DWORD attributes = GetFileAttributes(path.c_str());
-
- if (attributes == INVALID_FILE_ATTRIBUTES)
- // There's no sane way to report this :(.
- assert(0 && "GetFileAttributes returned INVALID_FILE_ATTRIBUTES");
-
- // This isn't exactly what defines a NTFS symlink, but it is only true for
- // paths that act like a symlink.
- return attributes & FILE_ATTRIBUTE_REPARSE_POINT;
-}
-
-bool
-Path::canRead() const {
- // FIXME: take security attributes into account.
- DWORD attr = GetFileAttributes(path.c_str());
- return attr != INVALID_FILE_ATTRIBUTES;
-}
-
-bool
-Path::canWrite() const {
- // FIXME: take security attributes into account.
- DWORD attr = GetFileAttributes(path.c_str());
- return (attr != INVALID_FILE_ATTRIBUTES) && !(attr & FILE_ATTRIBUTE_READONLY);
-}
-
-bool
-Path::canExecute() const {
- // FIXME: take security attributes into account.
- DWORD attr = GetFileAttributes(path.c_str());
- return attr != INVALID_FILE_ATTRIBUTES;
-}
-
-bool
-Path::isRegularFile() const {
- if (isDirectory())
- return false;
- return true;
-}
-
-StringRef
-Path::getLast() const {
- // Find the last slash
- size_t pos = path.rfind('/');
-
- // Handle the corner cases
- if (pos == std::string::npos)
- return path;
-
- // If the last character is a slash, we have a root directory
- if (pos == path.length()-1)
- return path;
-
- // Return everything after the last slash
- return StringRef(path).substr(pos+1);
-}
-
-const FileStatus *
-PathWithStatus::getFileStatus(bool update, std::string *ErrStr) const {
- if (!fsIsValid || update) {
- WIN32_FILE_ATTRIBUTE_DATA fi;
- if (!GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &fi)) {
- MakeErrMsg(ErrStr, "getStatusInfo():" + std::string(path) +
- ": Can't get status: ");
- return 0;
- }
-
- status.fileSize = fi.nFileSizeHigh;
- status.fileSize <<= sizeof(fi.nFileSizeHigh)*8;
- status.fileSize += fi.nFileSizeLow;
-
- status.mode = fi.dwFileAttributes & FILE_ATTRIBUTE_READONLY ? 0555 : 0777;
- status.user = 9999; // Not applicable to Windows, so...
- status.group = 9999; // Not applicable to Windows, so...
-
- // FIXME: this is only unique if the file is accessed by the same file path.
- // How do we do this for C:\dir\file and ..\dir\file ? Unix has inode
- // numbers, but the concept doesn't exist in Windows.
- status.uniqueID = 0;
- for (unsigned i = 0; i < path.length(); ++i)
- status.uniqueID += path[i];
-
- ULARGE_INTEGER ui;
- ui.LowPart = fi.ftLastWriteTime.dwLowDateTime;
- ui.HighPart = fi.ftLastWriteTime.dwHighDateTime;
- status.modTime.fromWin32Time(ui.QuadPart);
-
- status.isDir = fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
- fsIsValid = true;
- }
- return &status;
-}
-
-bool Path::makeReadableOnDisk(std::string* ErrMsg) {
- // All files are readable on Windows (ignoring security attributes).
- return false;
-}
-
-bool Path::makeWriteableOnDisk(std::string* ErrMsg) {
- DWORD attr = GetFileAttributes(path.c_str());
-
- // If it doesn't exist, we're done.
- if (attr == INVALID_FILE_ATTRIBUTES)
- return false;
-
- if (attr & FILE_ATTRIBUTE_READONLY) {
- if (!SetFileAttributes(path.c_str(), attr & ~FILE_ATTRIBUTE_READONLY)) {
- MakeErrMsg(ErrMsg, std::string(path) + ": Can't make file writable: ");
- return true;
- }
- }
- return false;
-}
-
-bool Path::makeExecutableOnDisk(std::string* ErrMsg) {
- // All files are executable on Windows (ignoring security attributes).
- return false;
-}
-
-bool
-Path::getDirectoryContents(std::set<Path>& result, std::string* ErrMsg) const {
- WIN32_FILE_ATTRIBUTE_DATA fi;
- if (!GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &fi)) {
- MakeErrMsg(ErrMsg, path + ": can't get status of file");
- return true;
- }
-
- if (!(fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
- if (ErrMsg)
- *ErrMsg = path + ": not a directory";
- return true;
- }
-
- result.clear();
- WIN32_FIND_DATA fd;
- std::string searchpath = path;
- if (path.size() == 0 || searchpath[path.size()-1] == '/')
- searchpath += "*";
- else
- searchpath += "/*";
-
- HANDLE h = FindFirstFile(searchpath.c_str(), &fd);
- if (h == INVALID_HANDLE_VALUE) {
- if (GetLastError() == ERROR_FILE_NOT_FOUND)
- return true; // not really an error, now is it?
- MakeErrMsg(ErrMsg, path + ": Can't read directory: ");
- return true;
- }
-
- do {
- if (fd.cFileName[0] == '.')
- continue;
- Path aPath(path);
- aPath.appendComponent(&fd.cFileName[0]);
- result.insert(aPath);
- } while (FindNextFile(h, &fd));
-
- DWORD err = GetLastError();
- FindClose(h);
- if (err != ERROR_NO_MORE_FILES) {
- SetLastError(err);
- MakeErrMsg(ErrMsg, path + ": Can't read directory: ");
- return true;
- }
- return false;
-}
-
-bool
-Path::set(StringRef a_path) {
- if (a_path.empty())
- return false;
- std::string save(path);
- path = a_path;
- FlipBackSlashes(path);
- if (!isValid()) {
- path = save;
- return false;
- }
- return true;
-}
-
-bool
-Path::appendComponent(StringRef name) {
- if (name.empty())
- return false;
- std::string save(path);
- if (!path.empty()) {
- size_t last = path.size() - 1;
- if (path[last] != '/')
- path += '/';
- }
- path += name;
- if (!isValid()) {
- path = save;
- return false;
- }
- return true;
-}
-
-bool
-Path::eraseComponent() {
- size_t slashpos = path.rfind('/',path.size());
- if (slashpos == path.size() - 1 || slashpos == std::string::npos)
- return false;
- std::string save(path);
- path.erase(slashpos);
- if (!isValid()) {
- path = save;
- return false;
- }
- return true;
-}
-
-bool
-Path::eraseSuffix() {
- size_t dotpos = path.rfind('.',path.size());
- size_t slashpos = path.rfind('/',path.size());
- if (dotpos != std::string::npos) {
- if (slashpos == std::string::npos || dotpos > slashpos+1) {
- std::string save(path);
- path.erase(dotpos, path.size()-dotpos);
- if (!isValid()) {
- path = save;
- return false;
- }
- return true;
- }
- }
- return false;
-}
-
-inline bool PathMsg(std::string* ErrMsg, const char* pathname, const char*msg) {
- if (ErrMsg)
- *ErrMsg = std::string(pathname) + ": " + std::string(msg);
- return true;
-}
-
-bool
-Path::createDirectoryOnDisk(bool create_parents, std::string* ErrMsg) {
- // Get a writeable copy of the path name
- size_t len = path.length();
- char *pathname = reinterpret_cast<char *>(_alloca(len+2));
- path.copy(pathname, len);
- pathname[len] = 0;
-
- // Make sure it ends with a slash.
- if (len == 0 || pathname[len - 1] != '/') {
- pathname[len] = '/';
- pathname[++len] = 0;
- }
-
- // Determine starting point for initial / search.
- char *next = pathname;
- if (pathname[0] == '/' && pathname[1] == '/') {
- // Skip host name.
- next = strchr(pathname+2, '/');
- if (next == NULL)
- return PathMsg(ErrMsg, pathname, "badly formed remote directory");
-
- // Skip share name.
- next = strchr(next+1, '/');
- if (next == NULL)
- return PathMsg(ErrMsg, pathname,"badly formed remote directory");
-
- next++;
- if (*next == 0)
- return PathMsg(ErrMsg, pathname, "badly formed remote directory");
-
- } else {
- if (pathname[1] == ':')
- next += 2; // skip drive letter
- if (*next == '/')
- next++; // skip root directory
- }
-
- // If we're supposed to create intermediate directories
- if (create_parents) {
- // Loop through the directory components until we're done
- while (*next) {
- next = strchr(next, '/');
- *next = 0;
- if (!CreateDirectory(pathname, NULL) &&
- GetLastError() != ERROR_ALREADY_EXISTS)
- return MakeErrMsg(ErrMsg,
- std::string(pathname) + ": Can't create directory: ");
- *next++ = '/';
- }
- } else {
- // Drop trailing slash.
- pathname[len-1] = 0;
- if (!CreateDirectory(pathname, NULL) &&
- GetLastError() != ERROR_ALREADY_EXISTS) {
- return MakeErrMsg(ErrMsg, std::string(pathname) +
- ": Can't create directory: ");
- }
- }
- return false;
-}
-
-bool
-Path::createFileOnDisk(std::string* ErrMsg) {
- // Create the file
- HANDLE h = CreateFile(path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_NEW,
- FILE_ATTRIBUTE_NORMAL, NULL);
- if (h == INVALID_HANDLE_VALUE)
- return MakeErrMsg(ErrMsg, path + ": Can't create file: ");
-
- CloseHandle(h);
- return false;
-}
-
-bool
-Path::eraseFromDisk(bool remove_contents, std::string *ErrStr) const {
- WIN32_FILE_ATTRIBUTE_DATA fi;
- if (!GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &fi))
- return true;
-
- if (fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
- // If it doesn't exist, we're done.
- if (!exists())
- return false;
-
- char *pathname = reinterpret_cast<char *>(_alloca(path.length()+3));
- int lastchar = path.length() - 1 ;
- path.copy(pathname, lastchar+1);
-
- // Make path end with '/*'.
- if (pathname[lastchar] != '/')
- pathname[++lastchar] = '/';
- pathname[lastchar+1] = '*';
- pathname[lastchar+2] = 0;
-
- if (remove_contents) {
- WIN32_FIND_DATA fd;
- HANDLE h = FindFirstFile(pathname, &fd);
-
- // It's a bad idea to alter the contents of a directory while enumerating
- // its contents. So build a list of its contents first, then destroy them.
-
- if (h != INVALID_HANDLE_VALUE) {
- std::vector<Path> list;
-
- do {
- if (strcmp(fd.cFileName, ".") == 0)
- continue;
- if (strcmp(fd.cFileName, "..") == 0)
- continue;
-
- Path aPath(path);
- aPath.appendComponent(&fd.cFileName[0]);
- list.push_back(aPath);
- } while (FindNextFile(h, &fd));
-
- DWORD err = GetLastError();
- FindClose(h);
- if (err != ERROR_NO_MORE_FILES) {
- SetLastError(err);
- return MakeErrMsg(ErrStr, path + ": Can't read directory: ");
- }
-
- for (std::vector<Path>::iterator I = list.begin(); I != list.end();
- ++I) {
- Path &aPath = *I;
- aPath.eraseFromDisk(true);
- }
- } else {
- if (GetLastError() != ERROR_FILE_NOT_FOUND)
- return MakeErrMsg(ErrStr, path + ": Can't read directory: ");
- }
- }
-
- pathname[lastchar] = 0;
- if (!RemoveDirectory(pathname))
- return MakeErrMsg(ErrStr,
- std::string(pathname) + ": Can't destroy directory: ");
- return false;
- } else {
- // Read-only files cannot be deleted on Windows. Must remove the read-only
- // attribute first.
- if (fi.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
- if (!SetFileAttributes(path.c_str(),
- fi.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY))
- return MakeErrMsg(ErrStr, path + ": Can't destroy file: ");
- }
-
- if (!DeleteFile(path.c_str()))
- return MakeErrMsg(ErrStr, path + ": Can't destroy file: ");
- return false;
- }
-}
-
-bool Path::getMagicNumber(std::string& Magic, unsigned len) const {
- assert(len < 1024 && "Request for magic string too long");
- char* buf = reinterpret_cast<char*>(alloca(len));
-
- HANDLE h = CreateFile(path.c_str(),
- GENERIC_READ,
- FILE_SHARE_READ,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
- if (h == INVALID_HANDLE_VALUE)
- return false;
-
- DWORD nRead = 0;
- BOOL ret = ReadFile(h, buf, len, &nRead, NULL);
- CloseHandle(h);
-
- if (!ret || nRead != len)
- return false;
-
- Magic = std::string(buf, len);
- return true;
-}
-
-bool
-Path::renamePathOnDisk(const Path& newName, std::string* ErrMsg) {
- if (!MoveFileEx(path.c_str(), newName.c_str(), MOVEFILE_REPLACE_EXISTING))
- return MakeErrMsg(ErrMsg, "Can't move '" + path + "' to '" + newName.path
- + "': ");
- return false;
-}
-
-bool
-Path::setStatusInfoOnDisk(const FileStatus &si, std::string *ErrMsg) const {
- // FIXME: should work on directories also.
- if (!si.isFile) {
- return true;
- }
-
- HANDLE h = CreateFile(path.c_str(),
- FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
- if (h == INVALID_HANDLE_VALUE)
- return true;
-
- BY_HANDLE_FILE_INFORMATION bhfi;
- if (!GetFileInformationByHandle(h, &bhfi)) {
- DWORD err = GetLastError();
- CloseHandle(h);
- SetLastError(err);
- return MakeErrMsg(ErrMsg, path + ": GetFileInformationByHandle: ");
- }
-
- ULARGE_INTEGER ui;
- ui.QuadPart = si.modTime.toWin32Time();
- FILETIME ft;
- ft.dwLowDateTime = ui.LowPart;
- ft.dwHighDateTime = ui.HighPart;
- BOOL ret = SetFileTime(h, NULL, &ft, &ft);
- DWORD err = GetLastError();
- CloseHandle(h);
- if (!ret) {
- SetLastError(err);
- return MakeErrMsg(ErrMsg, path + ": SetFileTime: ");
- }
-
- // Best we can do with Unix permission bits is to interpret the owner
- // writable bit.
- if (si.mode & 0200) {
- if (bhfi.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
- if (!SetFileAttributes(path.c_str(),
- bhfi.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY))
- return MakeErrMsg(ErrMsg, path + ": SetFileAttributes: ");
- }
- } else {
- if (!(bhfi.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) {
- if (!SetFileAttributes(path.c_str(),
- bhfi.dwFileAttributes | FILE_ATTRIBUTE_READONLY))
- return MakeErrMsg(ErrMsg, path + ": SetFileAttributes: ");
- }
- }
-
- return false;
-}
-
-bool
-CopyFile(const sys::Path &Dest, const sys::Path &Src, std::string* ErrMsg) {
- // Can't use CopyFile macro defined in Windows.h because it would mess up the
- // above line. We use the expansion it would have in a non-UNICODE build.
- if (!::CopyFileA(Src.c_str(), Dest.c_str(), false))
- return MakeErrMsg(ErrMsg, "Can't copy '" + Src.str() +
- "' to '" + Dest.str() + "': ");
- return false;
-}
-
-bool
-Path::makeUnique(bool reuse_current, std::string* ErrMsg) {
- if (reuse_current && !exists())
- return false; // File doesn't exist already, just use it!
-
- // Reserve space for -XXXXXX at the end.
- char *FNBuffer = (char*) alloca(path.size()+8);
- unsigned offset = path.size();
- path.copy(FNBuffer, offset);
-
- // Find a numeric suffix that isn't used by an existing file. Assume there
- // won't be more than 1 million files with the same prefix. Probably a safe
- // bet.
- static unsigned FCounter = 0;
- do {
- sprintf(FNBuffer+offset, "-%06u", FCounter);
- if (++FCounter > 999999)
- FCounter = 0;
- path = FNBuffer;
- } while (exists());
- return false;
-}
-
-bool
-Path::createTemporaryFileOnDisk(bool reuse_current, std::string* ErrMsg) {
- // Make this into a unique file name
- makeUnique(reuse_current, ErrMsg);
-
- // Now go and create it
- HANDLE h = CreateFile(path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_NEW,
- FILE_ATTRIBUTE_NORMAL, NULL);
- if (h == INVALID_HANDLE_VALUE)
- return MakeErrMsg(ErrMsg, path + ": can't create file");
-
- CloseHandle(h);
- return false;
-}
-
-/// MapInFilePages - Not yet implemented on win32.
-const char *Path::MapInFilePages(int FD, uint64_t FileSize) {
- return 0;
-}
-
-/// MapInFilePages - Not yet implemented on win32.
-void Path::UnMapFilePages(const char *Base, uint64_t FileSize) {
- assert(0 && "NOT IMPLEMENTED");
-}
-
-}
-}
+++ /dev/null
-//===- Win32/Process.cpp - Win32 Process Implementation ------- -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides the Win32 specific implementation of the Process class.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Win32.h"
-#include <psapi.h>
-#include <malloc.h>
-#include <io.h>
-
-#ifdef __MINGW32__
- #if (HAVE_LIBPSAPI != 1)
- #error "libpsapi.a should be present"
- #endif
-#else
- #pragma comment(lib, "psapi.lib")
-#endif
-
-//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only Win32 specific code
-//=== and must not be UNIX code
-//===----------------------------------------------------------------------===//
-
-#ifdef __MINGW32__
-// This ban should be lifted when MinGW 1.0+ has defined this value.
-# define _HEAPOK (-2)
-#endif
-
-namespace llvm {
-using namespace sys;
-
-// This function retrieves the page size using GetSystemInfo and is present
-// solely so it can be called once in Process::GetPageSize to initialize the
-// static variable PageSize.
-inline unsigned GetPageSizeOnce() {
- // NOTE: A 32-bit application running under WOW64 is supposed to use
- // GetNativeSystemInfo. However, this interface is not present prior
- // to Windows XP so to use it requires dynamic linking. It is not clear
- // how this affects the reported page size, if at all. One could argue
- // that LLVM ought to run as 64-bits on a 64-bit system, anyway.
- SYSTEM_INFO info;
- GetSystemInfo(&info);
- return static_cast<unsigned>(info.dwPageSize);
-}
-
-unsigned
-Process::GetPageSize() {
- static const unsigned PageSize = GetPageSizeOnce();
- return PageSize;
-}
-
-size_t
-Process::GetMallocUsage()
-{
- _HEAPINFO hinfo;
- hinfo._pentry = NULL;
-
- size_t size = 0;
-
- while (_heapwalk(&hinfo) == _HEAPOK)
- size += hinfo._size;
-
- return size;
-}
-
-size_t
-Process::GetTotalMemoryUsage()
-{
- PROCESS_MEMORY_COUNTERS pmc;
- GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc));
- return pmc.PagefileUsage;
-}
-
-void
-Process::GetTimeUsage(
- TimeValue& elapsed, TimeValue& user_time, TimeValue& sys_time)
-{
- elapsed = TimeValue::now();
-
- uint64_t ProcCreate, ProcExit, KernelTime, UserTime;
- GetProcessTimes(GetCurrentProcess(), (FILETIME*)&ProcCreate,
- (FILETIME*)&ProcExit, (FILETIME*)&KernelTime,
- (FILETIME*)&UserTime);
-
- // FILETIME's are # of 100 nanosecond ticks (1/10th of a microsecond)
- user_time.seconds( UserTime / 10000000 );
- user_time.nanoseconds( unsigned(UserTime % 10000000) * 100 );
- sys_time.seconds( KernelTime / 10000000 );
- sys_time.nanoseconds( unsigned(KernelTime % 10000000) * 100 );
-}
-
-int Process::GetCurrentUserId()
-{
- return 65536;
-}
-
-int Process::GetCurrentGroupId()
-{
- return 65536;
-}
-
-// Some LLVM programs such as bugpoint produce core files as a normal part of
-// their operation. To prevent the disk from filling up, this configuration item
-// does what's necessary to prevent their generation.
-void Process::PreventCoreFiles() {
- // Windows doesn't do core files, but it does do modal pop-up message
- // boxes. As this method is used by bugpoint, preventing these pop-ups
- // is the moral equivalent of suppressing core files.
- SetErrorMode(SEM_FAILCRITICALERRORS |
- SEM_NOGPFAULTERRORBOX |
- SEM_NOOPENFILEERRORBOX);
-}
-
-bool Process::StandardInIsUserInput() {
- return FileDescriptorIsDisplayed(0);
-}
-
-bool Process::StandardOutIsDisplayed() {
- return FileDescriptorIsDisplayed(1);
-}
-
-bool Process::StandardErrIsDisplayed() {
- return FileDescriptorIsDisplayed(2);
-}
-
-bool Process::FileDescriptorIsDisplayed(int fd) {
- DWORD Mode; // Unused
- return (GetConsoleMode((HANDLE)_get_osfhandle(fd), &Mode) != 0);
-}
-
-unsigned Process::StandardOutColumns() {
- unsigned Columns = 0;
- CONSOLE_SCREEN_BUFFER_INFO csbi;
- if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi))
- Columns = csbi.dwSize.X;
- return Columns;
-}
-
-unsigned Process::StandardErrColumns() {
- unsigned Columns = 0;
- CONSOLE_SCREEN_BUFFER_INFO csbi;
- if (GetConsoleScreenBufferInfo(GetStdHandle(STD_ERROR_HANDLE), &csbi))
- Columns = csbi.dwSize.X;
- return Columns;
-}
-
-// It always has colors.
-bool Process::StandardErrHasColors() {
- return StandardErrIsDisplayed();
-}
-
-bool Process::StandardOutHasColors() {
- return StandardOutIsDisplayed();
-}
-
-namespace {
-class DefaultColors
-{
- private:
- WORD defaultColor;
- public:
- DefaultColors()
- :defaultColor(GetCurrentColor()) {}
- static unsigned GetCurrentColor() {
- CONSOLE_SCREEN_BUFFER_INFO csbi;
- if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi))
- return csbi.wAttributes;
- return 0;
- }
- WORD operator()() const { return defaultColor; }
-};
-
-DefaultColors defaultColors;
-}
-
-bool Process::ColorNeedsFlush() {
- return true;
-}
-
-const char *Process::OutputBold(bool bg) {
- WORD colors = DefaultColors::GetCurrentColor();
- if (bg)
- colors |= BACKGROUND_INTENSITY;
- else
- colors |= FOREGROUND_INTENSITY;
- SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), colors);
- return 0;
-}
-
-const char *Process::OutputColor(char code, bool bold, bool bg) {
- WORD colors;
- if (bg) {
- colors = ((code&1) ? BACKGROUND_RED : 0) |
- ((code&2) ? BACKGROUND_GREEN : 0 ) |
- ((code&4) ? BACKGROUND_BLUE : 0);
- if (bold)
- colors |= BACKGROUND_INTENSITY;
- } else {
- colors = ((code&1) ? FOREGROUND_RED : 0) |
- ((code&2) ? FOREGROUND_GREEN : 0 ) |
- ((code&4) ? FOREGROUND_BLUE : 0);
- if (bold)
- colors |= FOREGROUND_INTENSITY;
- }
- SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), colors);
- return 0;
-}
-
-const char *Process::ResetColor() {
- SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), defaultColors());
- return 0;
-}
-
-}
+++ /dev/null
-//===- Win32/Program.cpp - Win32 Program Implementation ------- -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides the Win32 specific implementation of the Program class.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Win32.h"
-#include <cstdio>
-#include <malloc.h>
-#include <io.h>
-#include <fcntl.h>
-
-//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only Win32 specific code
-//=== and must not be UNIX code
-//===----------------------------------------------------------------------===//
-
-#ifdef __MINGW32__
-// Ancient mingw32's w32api might not have this declaration.
-extern "C"
-BOOL WINAPI SetInformationJobObject(HANDLE hJob,
- JOBOBJECTINFOCLASS JobObjectInfoClass,
- LPVOID lpJobObjectInfo,
- DWORD cbJobObjectInfoLength);
-#endif
-
-namespace {
- struct Win32ProcessInfo {
- HANDLE hProcess;
- DWORD dwProcessId;
- };
-}
-
-namespace llvm {
-using namespace sys;
-
-Program::Program() : Data_(0) {}
-
-Program::~Program() {
- if (Data_) {
- Win32ProcessInfo* wpi = reinterpret_cast<Win32ProcessInfo*>(Data_);
- CloseHandle(wpi->hProcess);
- delete wpi;
- Data_ = 0;
- }
-}
-
-unsigned Program::GetPid() const {
- Win32ProcessInfo* wpi = reinterpret_cast<Win32ProcessInfo*>(Data_);
- return wpi->dwProcessId;
-}
-
-// This function just uses the PATH environment variable to find the program.
-Path
-Program::FindProgramByName(const std::string& progName) {
-
- // Check some degenerate cases
- if (progName.length() == 0) // no program
- return Path();
- Path temp;
- if (!temp.set(progName)) // invalid name
- return Path();
- // Return paths with slashes verbatim.
- if (progName.find('\\') != std::string::npos ||
- progName.find('/') != std::string::npos)
- return temp;
-
- // At this point, the file name is valid and does not contain slashes.
- // Let Windows search for it.
- char buffer[MAX_PATH];
- char *dummy = NULL;
- DWORD len = SearchPath(NULL, progName.c_str(), ".exe", MAX_PATH,
- buffer, &dummy);
-
- // See if it wasn't found.
- if (len == 0)
- return Path();
-
- // See if we got the entire path.
- if (len < MAX_PATH)
- return Path(buffer);
-
- // Buffer was too small; grow and retry.
- while (true) {
- char *b = reinterpret_cast<char *>(_alloca(len+1));
- DWORD len2 = SearchPath(NULL, progName.c_str(), ".exe", len+1, b, &dummy);
-
- // It is unlikely the search failed, but it's always possible some file
- // was added or removed since the last search, so be paranoid...
- if (len2 == 0)
- return Path();
- else if (len2 <= len)
- return Path(b);
-
- len = len2;
- }
-}
-
-static HANDLE RedirectIO(const Path *path, int fd, std::string* ErrMsg) {
- HANDLE h;
- if (path == 0) {
- DuplicateHandle(GetCurrentProcess(), (HANDLE)_get_osfhandle(fd),
- GetCurrentProcess(), &h,
- 0, TRUE, DUPLICATE_SAME_ACCESS);
- return h;
- }
-
- const char *fname;
- if (path->isEmpty())
- fname = "NUL";
- else
- fname = path->c_str();
-
- SECURITY_ATTRIBUTES sa;
- sa.nLength = sizeof(sa);
- sa.lpSecurityDescriptor = 0;
- sa.bInheritHandle = TRUE;
-
- h = CreateFile(fname, fd ? GENERIC_WRITE : GENERIC_READ, FILE_SHARE_READ,
- &sa, fd == 0 ? OPEN_EXISTING : CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL, NULL);
- if (h == INVALID_HANDLE_VALUE) {
- MakeErrMsg(ErrMsg, std::string(fname) + ": Can't open file for " +
- (fd ? "input: " : "output: "));
- }
-
- return h;
-}
-
-/// ArgNeedsQuotes - Check whether argument needs to be quoted when calling
-/// CreateProcess.
-static bool ArgNeedsQuotes(const char *Str) {
- return Str[0] == '\0' || strchr(Str, ' ') != 0;
-}
-
-
-/// ArgLenWithQuotes - Check whether argument needs to be quoted when calling
-/// CreateProcess and returns length of quoted arg with escaped quotes
-static unsigned int ArgLenWithQuotes(const char *Str) {
- unsigned int len = ArgNeedsQuotes(Str) ? 2 : 0;
-
- while (*Str != '\0') {
- if (*Str == '\"')
- ++len;
-
- ++len;
- ++Str;
- }
-
- return len;
-}
-
-
-bool
-Program::Execute(const Path& path,
- const char** args,
- const char** envp,
- const Path** redirects,
- unsigned memoryLimit,
- std::string* ErrMsg) {
- if (Data_) {
- Win32ProcessInfo* wpi = reinterpret_cast<Win32ProcessInfo*>(Data_);
- CloseHandle(wpi->hProcess);
- delete wpi;
- Data_ = 0;
- }
-
- if (!path.canExecute()) {
- if (ErrMsg)
- *ErrMsg = "program not executable";
- return false;
- }
-
- // Windows wants a command line, not an array of args, to pass to the new
- // process. We have to concatenate them all, while quoting the args that
- // have embedded spaces (or are empty).
-
- // First, determine the length of the command line.
- unsigned len = 0;
- for (unsigned i = 0; args[i]; i++) {
- len += ArgLenWithQuotes(args[i]) + 1;
- }
-
- // Now build the command line.
- char *command = reinterpret_cast<char *>(_alloca(len+1));
- char *p = command;
-
- for (unsigned i = 0; args[i]; i++) {
- const char *arg = args[i];
-
- bool needsQuoting = ArgNeedsQuotes(arg);
- if (needsQuoting)
- *p++ = '"';
-
- while (*arg != '\0') {
- if (*arg == '\"')
- *p++ = '\\';
-
- *p++ = *arg++;
- }
-
- if (needsQuoting)
- *p++ = '"';
- *p++ = ' ';
- }
-
- *p = 0;
-
- // The pointer to the environment block for the new process.
- char *envblock = 0;
-
- if (envp) {
- // An environment block consists of a null-terminated block of
- // null-terminated strings. Convert the array of environment variables to
- // an environment block by concatenating them.
-
- // First, determine the length of the environment block.
- len = 0;
- for (unsigned i = 0; envp[i]; i++)
- len += strlen(envp[i]) + 1;
-
- // Now build the environment block.
- envblock = reinterpret_cast<char *>(_alloca(len+1));
- p = envblock;
-
- for (unsigned i = 0; envp[i]; i++) {
- const char *ev = envp[i];
- size_t len = strlen(ev) + 1;
- memcpy(p, ev, len);
- p += len;
- }
-
- *p = 0;
- }
-
- // Create a child process.
- STARTUPINFO si;
- memset(&si, 0, sizeof(si));
- si.cb = sizeof(si);
- si.hStdInput = INVALID_HANDLE_VALUE;
- si.hStdOutput = INVALID_HANDLE_VALUE;
- si.hStdError = INVALID_HANDLE_VALUE;
-
- if (redirects) {
- si.dwFlags = STARTF_USESTDHANDLES;
-
- si.hStdInput = RedirectIO(redirects[0], 0, ErrMsg);
- if (si.hStdInput == INVALID_HANDLE_VALUE) {
- MakeErrMsg(ErrMsg, "can't redirect stdin");
- return false;
- }
- si.hStdOutput = RedirectIO(redirects[1], 1, ErrMsg);
- if (si.hStdOutput == INVALID_HANDLE_VALUE) {
- CloseHandle(si.hStdInput);
- MakeErrMsg(ErrMsg, "can't redirect stdout");
- return false;
- }
- if (redirects[1] && redirects[2] && *(redirects[1]) == *(redirects[2])) {
- // If stdout and stderr should go to the same place, redirect stderr
- // to the handle already open for stdout.
- DuplicateHandle(GetCurrentProcess(), si.hStdOutput,
- GetCurrentProcess(), &si.hStdError,
- 0, TRUE, DUPLICATE_SAME_ACCESS);
- } else {
- // Just redirect stderr
- si.hStdError = RedirectIO(redirects[2], 2, ErrMsg);
- if (si.hStdError == INVALID_HANDLE_VALUE) {
- CloseHandle(si.hStdInput);
- CloseHandle(si.hStdOutput);
- MakeErrMsg(ErrMsg, "can't redirect stderr");
- return false;
- }
- }
- }
-
- PROCESS_INFORMATION pi;
- memset(&pi, 0, sizeof(pi));
-
- fflush(stdout);
- fflush(stderr);
- BOOL rc = CreateProcess(path.c_str(), command, NULL, NULL, TRUE, 0,
- envblock, NULL, &si, &pi);
- DWORD err = GetLastError();
-
- // Regardless of whether the process got created or not, we are done with
- // the handles we created for it to inherit.
- CloseHandle(si.hStdInput);
- CloseHandle(si.hStdOutput);
- CloseHandle(si.hStdError);
-
- // Now return an error if the process didn't get created.
- if (!rc) {
- SetLastError(err);
- MakeErrMsg(ErrMsg, std::string("Couldn't execute program '") +
- path.str() + "'");
- return false;
- }
- Win32ProcessInfo* wpi = new Win32ProcessInfo;
- wpi->hProcess = pi.hProcess;
- wpi->dwProcessId = pi.dwProcessId;
- Data_ = wpi;
-
- // Make sure these get closed no matter what.
- AutoHandle hThread(pi.hThread);
-
- // Assign the process to a job if a memory limit is defined.
- AutoHandle hJob(0);
- if (memoryLimit != 0) {
- hJob = CreateJobObject(0, 0);
- bool success = false;
- if (hJob != 0) {
- JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli;
- memset(&jeli, 0, sizeof(jeli));
- jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_PROCESS_MEMORY;
- jeli.ProcessMemoryLimit = uintptr_t(memoryLimit) * 1048576;
- if (SetInformationJobObject(hJob, JobObjectExtendedLimitInformation,
- &jeli, sizeof(jeli))) {
- if (AssignProcessToJobObject(hJob, pi.hProcess))
- success = true;
- }
- }
- if (!success) {
- SetLastError(GetLastError());
- MakeErrMsg(ErrMsg, std::string("Unable to set memory limit"));
- TerminateProcess(pi.hProcess, 1);
- WaitForSingleObject(pi.hProcess, INFINITE);
- return false;
- }
- }
-
- return true;
-}
-
-int
-Program::Wait(const Path &path,
- unsigned secondsToWait,
- std::string* ErrMsg) {
- if (Data_ == 0) {
- MakeErrMsg(ErrMsg, "Process not started!");
- return -1;
- }
-
- Win32ProcessInfo* wpi = reinterpret_cast<Win32ProcessInfo*>(Data_);
- HANDLE hProcess = wpi->hProcess;
-
- // Wait for the process to terminate.
- DWORD millisecondsToWait = INFINITE;
- if (secondsToWait > 0)
- millisecondsToWait = secondsToWait * 1000;
-
- if (WaitForSingleObject(hProcess, millisecondsToWait) == WAIT_TIMEOUT) {
- if (!TerminateProcess(hProcess, 1)) {
- MakeErrMsg(ErrMsg, "Failed to terminate timed-out program.");
- return -1;
- }
- WaitForSingleObject(hProcess, INFINITE);
- }
-
- // Get its exit status.
- DWORD status;
- BOOL rc = GetExitCodeProcess(hProcess, &status);
- DWORD err = GetLastError();
-
- if (!rc) {
- SetLastError(err);
- MakeErrMsg(ErrMsg, "Failed getting status for program.");
- return -1;
- }
-
- return status;
-}
-
-bool
-Program::Kill(std::string* ErrMsg) {
- if (Data_ == 0) {
- MakeErrMsg(ErrMsg, "Process not started!");
- return true;
- }
-
- Win32ProcessInfo* wpi = reinterpret_cast<Win32ProcessInfo*>(Data_);
- HANDLE hProcess = wpi->hProcess;
- if (TerminateProcess(hProcess, 1) == 0) {
- MakeErrMsg(ErrMsg, "The process couldn't be killed!");
- return true;
- }
-
- return false;
-}
-
-bool Program::ChangeStdinToBinary(){
- int result = _setmode( _fileno(stdin), _O_BINARY );
- return result == -1;
-}
-
-bool Program::ChangeStdoutToBinary(){
- int result = _setmode( _fileno(stdout), _O_BINARY );
- return result == -1;
-}
-
-bool Program::ChangeStderrToBinary(){
- int result = _setmode( _fileno(stderr), _O_BINARY );
- return result == -1;
-}
-
-}
+++ /dev/null
-//= llvm/System/Win32/Mutex.inc - Win32 Reader/Writer Mutual Exclusion Lock =//
-//
-// 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 Win32 specific (non-pthread) RWMutex class.
-//
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only generic Win32 code that
-//=== is guaranteed to work on *all* Win32 variants.
-//===----------------------------------------------------------------------===//
-
-#include "Win32.h"
-
-// FIXME: Windows does not have reader-writer locks pre-Vista. If you want
-// real reader-writer locks, you a pthreads implementation for Windows.
-
-namespace llvm {
-using namespace sys;
-
-RWMutexImpl::RWMutexImpl() {
- data_ = calloc(1, sizeof(CRITICAL_SECTION));
- InitializeCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
-}
-
-RWMutexImpl::~RWMutexImpl() {
- DeleteCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
- free(data_);
-}
-
-bool RWMutexImpl::reader_acquire() {
- EnterCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
- return true;
-}
-
-bool RWMutexImpl::reader_release() {
- LeaveCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
- return true;
-}
-
-bool RWMutexImpl::writer_acquire() {
- EnterCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
- return true;
-}
-
-bool RWMutexImpl::writer_release() {
- LeaveCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
- return true;
-}
-
-
-}
+++ /dev/null
-//===- Win32/Signals.cpp - Win32 Signals Implementation ---------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides the Win32 specific implementation of the Signals class.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Win32.h"
-#include <stdio.h>
-#include <vector>
-#include <algorithm>
-
-#ifdef __MINGW32__
- #include <imagehlp.h>
-#else
- #include <dbghelp.h>
-#endif
-#include <psapi.h>
-
-#ifdef __MINGW32__
- #if ((HAVE_LIBIMAGEHLP != 1) || (HAVE_LIBPSAPI != 1))
- #error "libimagehlp.a & libpsapi.a should be present"
- #endif
-#else
- #pragma comment(lib, "psapi.lib")
- #pragma comment(lib, "dbghelp.lib")
-#endif
-
-// Forward declare.
-static LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep);
-static BOOL WINAPI LLVMConsoleCtrlHandler(DWORD dwCtrlType);
-
-// InterruptFunction - The function to call if ctrl-c is pressed.
-static void (*InterruptFunction)() = 0;
-
-static std::vector<llvm::sys::Path> *FilesToRemove = NULL;
-static std::vector<std::pair<void(*)(void*), void*> > *CallBacksToRun = 0;
-static bool RegisteredUnhandledExceptionFilter = false;
-static bool CleanupExecuted = false;
-static bool ExitOnUnhandledExceptions = false;
-static PTOP_LEVEL_EXCEPTION_FILTER OldFilter = NULL;
-
-// Windows creates a new thread to execute the console handler when an event
-// (such as CTRL/C) occurs. This causes concurrency issues with the above
-// globals which this critical section addresses.
-static CRITICAL_SECTION CriticalSection;
-
-namespace llvm {
-
-//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only Win32 specific code
-//=== and must not be UNIX code
-//===----------------------------------------------------------------------===//
-
-#ifdef _MSC_VER
-/// CRTReportHook - Function called on a CRT debugging event.
-static int CRTReportHook(int ReportType, char *Message, int *Return) {
- // Don't cause a DebugBreak() on return.
- if (Return)
- *Return = 0;
-
- switch (ReportType) {
- default:
- case _CRT_ASSERT:
- fprintf(stderr, "CRT assert: %s\n", Message);
- // FIXME: Is there a way to just crash? Perhaps throw to the unhandled
- // exception code? Perhaps SetErrorMode() handles this.
- _exit(3);
- break;
- case _CRT_ERROR:
- fprintf(stderr, "CRT error: %s\n", Message);
- // FIXME: Is there a way to just crash? Perhaps throw to the unhandled
- // exception code? Perhaps SetErrorMode() handles this.
- _exit(3);
- break;
- case _CRT_WARN:
- fprintf(stderr, "CRT warn: %s\n", Message);
- break;
- }
-
- // Don't call _CrtDbgReport.
- return TRUE;
-}
-#endif
-
-static void RegisterHandler() {
- if (RegisteredUnhandledExceptionFilter) {
- EnterCriticalSection(&CriticalSection);
- return;
- }
-
- // Now's the time to create the critical section. This is the first time
- // through here, and there's only one thread.
- InitializeCriticalSection(&CriticalSection);
-
- // Enter it immediately. Now if someone hits CTRL/C, the console handler
- // can't proceed until the globals are updated.
- EnterCriticalSection(&CriticalSection);
-
- RegisteredUnhandledExceptionFilter = true;
- OldFilter = SetUnhandledExceptionFilter(LLVMUnhandledExceptionFilter);
- SetConsoleCtrlHandler(LLVMConsoleCtrlHandler, TRUE);
-
- // Environment variable to disable any kind of crash dialog.
- if (getenv("LLVM_DISABLE_CRT_DEBUG")) {
-#ifdef _MSC_VER
- _CrtSetReportHook(CRTReportHook);
-#endif
- ExitOnUnhandledExceptions = true;
- }
-
- // IMPORTANT NOTE: Caller must call LeaveCriticalSection(&CriticalSection) or
- // else multi-threading problems will ensue.
-}
-
-// RemoveFileOnSignal - The public API
-bool sys::RemoveFileOnSignal(const sys::Path &Filename, std::string* ErrMsg) {
- RegisterHandler();
-
- if (CleanupExecuted) {
- if (ErrMsg)
- *ErrMsg = "Process terminating -- cannot register for removal";
- return true;
- }
-
- if (FilesToRemove == NULL)
- FilesToRemove = new std::vector<sys::Path>;
-
- FilesToRemove->push_back(Filename);
-
- LeaveCriticalSection(&CriticalSection);
- return false;
-}
-
-// DontRemoveFileOnSignal - The public API
-void sys::DontRemoveFileOnSignal(const sys::Path &Filename) {
- if (FilesToRemove == NULL)
- return;
-
- RegisterHandler();
-
- FilesToRemove->push_back(Filename);
- std::vector<sys::Path>::reverse_iterator I =
- std::find(FilesToRemove->rbegin(), FilesToRemove->rend(), Filename);
- if (I != FilesToRemove->rend())
- FilesToRemove->erase(I.base()-1);
-
- LeaveCriticalSection(&CriticalSection);
-}
-
-/// PrintStackTraceOnErrorSignal - When an error signal (such as SIBABRT or
-/// SIGSEGV) is delivered to the process, print a stack trace and then exit.
-void sys::PrintStackTraceOnErrorSignal() {
- RegisterHandler();
- LeaveCriticalSection(&CriticalSection);
-}
-
-
-void sys::SetInterruptFunction(void (*IF)()) {
- RegisterHandler();
- InterruptFunction = IF;
- LeaveCriticalSection(&CriticalSection);
-}
-
-
-/// AddSignalHandler - Add a function to be called when a signal is delivered
-/// to the process. The handler can have a cookie passed to it to identify
-/// what instance of the handler it is.
-void sys::AddSignalHandler(void (*FnPtr)(void *), void *Cookie) {
- if (CallBacksToRun == 0)
- CallBacksToRun = new std::vector<std::pair<void(*)(void*), void*> >();
- CallBacksToRun->push_back(std::make_pair(FnPtr, Cookie));
- RegisterHandler();
- LeaveCriticalSection(&CriticalSection);
-}
-}
-
-static void Cleanup() {
- EnterCriticalSection(&CriticalSection);
-
- // Prevent other thread from registering new files and directories for
- // removal, should we be executing because of the console handler callback.
- CleanupExecuted = true;
-
- // FIXME: open files cannot be deleted.
-
- if (FilesToRemove != NULL)
- while (!FilesToRemove->empty()) {
- FilesToRemove->back().eraseFromDisk();
- FilesToRemove->pop_back();
- }
-
- if (CallBacksToRun)
- for (unsigned i = 0, e = CallBacksToRun->size(); i != e; ++i)
- (*CallBacksToRun)[i].first((*CallBacksToRun)[i].second);
-
- LeaveCriticalSection(&CriticalSection);
-}
-
-void llvm::sys::RunInterruptHandlers() {
- Cleanup();
-}
-
-static LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep) {
- Cleanup();
-
-#ifdef _WIN64
- // TODO: provide a x64 friendly version of the following
-#else
-
- // Initialize the STACKFRAME structure.
- STACKFRAME StackFrame;
- memset(&StackFrame, 0, sizeof(StackFrame));
-
- StackFrame.AddrPC.Offset = ep->ContextRecord->Eip;
- StackFrame.AddrPC.Mode = AddrModeFlat;
- StackFrame.AddrStack.Offset = ep->ContextRecord->Esp;
- StackFrame.AddrStack.Mode = AddrModeFlat;
- StackFrame.AddrFrame.Offset = ep->ContextRecord->Ebp;
- StackFrame.AddrFrame.Mode = AddrModeFlat;
-
- HANDLE hProcess = GetCurrentProcess();
- HANDLE hThread = GetCurrentThread();
-
- // Initialize the symbol handler.
- SymSetOptions(SYMOPT_DEFERRED_LOADS|SYMOPT_LOAD_LINES);
- SymInitialize(hProcess, NULL, TRUE);
-
- while (true) {
- if (!StackWalk(IMAGE_FILE_MACHINE_I386, hProcess, hThread, &StackFrame,
- ep->ContextRecord, NULL, SymFunctionTableAccess,
- SymGetModuleBase, NULL)) {
- break;
- }
-
- if (StackFrame.AddrFrame.Offset == 0)
- break;
-
- // Print the PC in hexadecimal.
- DWORD PC = StackFrame.AddrPC.Offset;
- fprintf(stderr, "%08lX", PC);
-
- // Print the parameters. Assume there are four.
- fprintf(stderr, " (0x%08lX 0x%08lX 0x%08lX 0x%08lX)",
- StackFrame.Params[0],
- StackFrame.Params[1], StackFrame.Params[2], StackFrame.Params[3]);
-
- // Verify the PC belongs to a module in this process.
- if (!SymGetModuleBase(hProcess, PC)) {
- fputs(" <unknown module>\n", stderr);
- continue;
- }
-
- // Print the symbol name.
- char buffer[512];
- IMAGEHLP_SYMBOL *symbol = reinterpret_cast<IMAGEHLP_SYMBOL *>(buffer);
- memset(symbol, 0, sizeof(IMAGEHLP_SYMBOL));
- symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
- symbol->MaxNameLength = 512 - sizeof(IMAGEHLP_SYMBOL);
-
- DWORD dwDisp;
- if (!SymGetSymFromAddr(hProcess, PC, &dwDisp, symbol)) {
- fputc('\n', stderr);
- continue;
- }
-
- buffer[511] = 0;
- if (dwDisp > 0)
- fprintf(stderr, ", %s()+%04lu bytes(s)", symbol->Name, dwDisp);
- else
- fprintf(stderr, ", %s", symbol->Name);
-
- // Print the source file and line number information.
- IMAGEHLP_LINE line;
- memset(&line, 0, sizeof(line));
- line.SizeOfStruct = sizeof(line);
- if (SymGetLineFromAddr(hProcess, PC, &dwDisp, &line)) {
- fprintf(stderr, ", %s, line %lu", line.FileName, line.LineNumber);
- if (dwDisp > 0)
- fprintf(stderr, "+%04lu byte(s)", dwDisp);
- }
-
- fputc('\n', stderr);
- }
-
-#endif
-
- if (ExitOnUnhandledExceptions)
- _exit(-3);
-
- // Allow dialog box to pop up allowing choice to start debugger.
- if (OldFilter)
- return (*OldFilter)(ep);
- else
- return EXCEPTION_CONTINUE_SEARCH;
-}
-
-static BOOL WINAPI LLVMConsoleCtrlHandler(DWORD dwCtrlType) {
- // We are running in our very own thread, courtesy of Windows.
- EnterCriticalSection(&CriticalSection);
- Cleanup();
-
- // If an interrupt function has been set, go and run one it; otherwise,
- // the process dies.
- void (*IF)() = InterruptFunction;
- InterruptFunction = 0; // Don't run it on another CTRL-C.
-
- if (IF) {
- // Note: if the interrupt function throws an exception, there is nothing
- // to catch it in this thread so it will kill the process.
- IF(); // Run it now.
- LeaveCriticalSection(&CriticalSection);
- return TRUE; // Don't kill the process.
- }
-
- // Allow normal processing to take place; i.e., the process dies.
- LeaveCriticalSection(&CriticalSection);
- return FALSE;
-}
-
+++ /dev/null
-//= llvm/System/Win32/ThreadLocal.inc - Win32 Thread Local Data -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the Win32 specific (non-pthread) ThreadLocal class.
-//
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only generic Win32 code that
-//=== is guaranteed to work on *all* Win32 variants.
-//===----------------------------------------------------------------------===//
-
-#include "Win32.h"
-#include "llvm/System/ThreadLocal.h"
-
-namespace llvm {
-using namespace sys;
-
-ThreadLocalImpl::ThreadLocalImpl() {
- DWORD* tls = new DWORD;
- *tls = TlsAlloc();
- assert(*tls != TLS_OUT_OF_INDEXES);
- data = tls;
-}
-
-ThreadLocalImpl::~ThreadLocalImpl() {
- DWORD* tls = static_cast<DWORD*>(data);
- TlsFree(*tls);
- delete tls;
-}
-
-const void* ThreadLocalImpl::getInstance() {
- DWORD* tls = static_cast<DWORD*>(data);
- return TlsGetValue(*tls);
-}
-
-void ThreadLocalImpl::setInstance(const void* d){
- DWORD* tls = static_cast<DWORD*>(data);
- int errorcode = TlsSetValue(*tls, const_cast<void*>(d));
- assert(errorcode != 0);
- (void)errorcode;
-}
-
-void ThreadLocalImpl::removeInstance() {
- setInstance(0);
-}
-
-}
+++ /dev/null
-//===- Win32/TimeValue.cpp - Win32 TimeValue Implementation -----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides the Win32 implementation of the TimeValue class.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Win32.h"
-#include <time.h>
-
-namespace llvm {
-using namespace sys;
-
-//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only Win32 specific code.
-//===----------------------------------------------------------------------===//
-
-TimeValue TimeValue::now() {
- uint64_t ft;
- GetSystemTimeAsFileTime(reinterpret_cast<FILETIME *>(&ft));
-
- TimeValue t(0, 0);
- t.fromWin32Time(ft);
- return t;
-}
-
-std::string TimeValue::str() const {
-#ifdef __MINGW32__
- // This ban may be lifted by either:
- // (i) a future MinGW version other than 1.0 inherents the __time64_t type, or
- // (ii) configure tests for either the time_t or __time64_t type.
- time_t ourTime = time_t(this->toEpochTime());
- struct tm *lt = ::localtime(&ourTime);
-#else
- __time64_t ourTime = this->toEpochTime();
- struct tm *lt = ::_localtime64(&ourTime);
-#endif
-
- char buffer[25];
- strftime(buffer, 25, "%a %b %d %H:%M:%S %Y", lt);
- return std::string(buffer);
-}
-
-
-}
+++ /dev/null
-//===- Win32/Win32.h - Common Win32 Include File ----------------*- 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 things specific to Win32 implementations.
-//
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only generic Win32 code that
-//=== is guaranteed to work on *all* Win32 variants.
-//===----------------------------------------------------------------------===//
-
-// Require at least Windows 2000 API.
-#define _WIN32_WINNT 0x0500
-#define _WIN32_IE 0x0500 // MinGW at it again.
-#define WIN32_LEAN_AND_MEAN
-
-#include "llvm/Config/config.h" // Get build system configuration settings
-#include <Windows.h>
-#include <ShlObj.h>
-#include <cassert>
-#include <string>
-
-inline bool MakeErrMsg(std::string* ErrMsg, const std::string& prefix) {
- if (!ErrMsg)
- return true;
- char *buffer = NULL;
- FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
- NULL, GetLastError(), 0, (LPSTR)&buffer, 1, NULL);
- *ErrMsg = prefix + buffer;
- LocalFree(buffer);
- return true;
-}
-
-class AutoHandle {
- HANDLE handle;
-
-public:
- AutoHandle(HANDLE h) : handle(h) {}
-
- ~AutoHandle() {
- if (handle)
- CloseHandle(handle);
- }
-
- operator HANDLE() {
- return handle;
- }
-
- AutoHandle &operator=(HANDLE h) {
- handle = h;
- return *this;
- }
-};
+++ /dev/null
-//===- llvm/System/Win32/system_error.inc - Windows error_code --*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides the Windows specific implementation of the error_code
-// and error_condition classes.
-//
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only generic Windows code that
-//=== is guaranteed to work on *all* Windows variants.
-//===----------------------------------------------------------------------===//
-
-#include <Windows.h>
-#include <WinError.h>
-
-using namespace llvm;
-
-std::string
-_system_error_category::message(int ev) const {
- LPVOID lpMsgBuf = 0;
- DWORD retval = ::FormatMessageA(
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- ev,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
- (LPSTR) &lpMsgBuf,
- 0,
- NULL);
- if (retval == 0) {
- ::LocalFree(lpMsgBuf);
- return std::string("Unknown error");
- }
-
- std::string str( static_cast<LPCSTR>(lpMsgBuf) );
- ::LocalFree(lpMsgBuf);
-
- while (str.size()
- && (str[str.size()-1] == '\n' || str[str.size()-1] == '\r'))
- str.erase( str.size()-1 );
- if (str.size() && str[str.size()-1] == '.')
- str.erase( str.size()-1 );
- return str;
-}
-
-// I'd rather not double the line count of the following.
-#define MAP_ERR_TO_COND(x, y) case x: return make_error_condition(errc::y)
-
-error_condition
-_system_error_category::default_error_condition(int ev) const {
- switch (ev) {
- MAP_ERR_TO_COND(0, success);
- // Windows system -> posix_errno decode table ---------------------------//
- // see WinError.h comments for descriptions of errors
- MAP_ERR_TO_COND(ERROR_ACCESS_DENIED, permission_denied);
- MAP_ERR_TO_COND(ERROR_ALREADY_EXISTS, file_exists);
- MAP_ERR_TO_COND(ERROR_BAD_UNIT, no_such_device);
- MAP_ERR_TO_COND(ERROR_BUFFER_OVERFLOW, filename_too_long);
- MAP_ERR_TO_COND(ERROR_BUSY, device_or_resource_busy);
- MAP_ERR_TO_COND(ERROR_BUSY_DRIVE, device_or_resource_busy);
- MAP_ERR_TO_COND(ERROR_CANNOT_MAKE, permission_denied);
- MAP_ERR_TO_COND(ERROR_CANTOPEN, io_error);
- MAP_ERR_TO_COND(ERROR_CANTREAD, io_error);
- MAP_ERR_TO_COND(ERROR_CANTWRITE, io_error);
- MAP_ERR_TO_COND(ERROR_CURRENT_DIRECTORY, permission_denied);
- MAP_ERR_TO_COND(ERROR_DEV_NOT_EXIST, no_such_device);
- MAP_ERR_TO_COND(ERROR_DEVICE_IN_USE, device_or_resource_busy);
- MAP_ERR_TO_COND(ERROR_DIR_NOT_EMPTY, directory_not_empty);
- MAP_ERR_TO_COND(ERROR_DIRECTORY, invalid_argument);
- MAP_ERR_TO_COND(ERROR_DISK_FULL, no_space_on_device);
- MAP_ERR_TO_COND(ERROR_FILE_EXISTS, file_exists);
- MAP_ERR_TO_COND(ERROR_FILE_NOT_FOUND, no_such_file_or_directory);
- MAP_ERR_TO_COND(ERROR_HANDLE_DISK_FULL, no_space_on_device);
- MAP_ERR_TO_COND(ERROR_INVALID_ACCESS, permission_denied);
- MAP_ERR_TO_COND(ERROR_INVALID_DRIVE, no_such_device);
- MAP_ERR_TO_COND(ERROR_INVALID_FUNCTION, function_not_supported);
- MAP_ERR_TO_COND(ERROR_INVALID_HANDLE, invalid_argument);
- MAP_ERR_TO_COND(ERROR_INVALID_NAME, invalid_argument);
- MAP_ERR_TO_COND(ERROR_LOCK_VIOLATION, no_lock_available);
- MAP_ERR_TO_COND(ERROR_LOCKED, no_lock_available);
- MAP_ERR_TO_COND(ERROR_NEGATIVE_SEEK, invalid_argument);
- MAP_ERR_TO_COND(ERROR_NOACCESS, permission_denied);
- MAP_ERR_TO_COND(ERROR_NOT_ENOUGH_MEMORY, not_enough_memory);
- MAP_ERR_TO_COND(ERROR_NOT_READY, resource_unavailable_try_again);
- MAP_ERR_TO_COND(ERROR_NOT_SAME_DEVICE, cross_device_link);
- MAP_ERR_TO_COND(ERROR_OPEN_FAILED, io_error);
- MAP_ERR_TO_COND(ERROR_OPEN_FILES, device_or_resource_busy);
- MAP_ERR_TO_COND(ERROR_OPERATION_ABORTED, operation_canceled);
- MAP_ERR_TO_COND(ERROR_OUTOFMEMORY, not_enough_memory);
- MAP_ERR_TO_COND(ERROR_PATH_NOT_FOUND, no_such_file_or_directory);
- MAP_ERR_TO_COND(ERROR_READ_FAULT, io_error);
- MAP_ERR_TO_COND(ERROR_RETRY, resource_unavailable_try_again);
- MAP_ERR_TO_COND(ERROR_SEEK, io_error);
- MAP_ERR_TO_COND(ERROR_SHARING_VIOLATION, permission_denied);
- MAP_ERR_TO_COND(ERROR_TOO_MANY_OPEN_FILES, too_many_files_open);
- MAP_ERR_TO_COND(ERROR_WRITE_FAULT, io_error);
- MAP_ERR_TO_COND(ERROR_WRITE_PROTECT, permission_denied);
- MAP_ERR_TO_COND(ERROR_SEM_TIMEOUT, timed_out);
- MAP_ERR_TO_COND(WSAEACCES, permission_denied);
- MAP_ERR_TO_COND(WSAEADDRINUSE, address_in_use);
- MAP_ERR_TO_COND(WSAEADDRNOTAVAIL, address_not_available);
- MAP_ERR_TO_COND(WSAEAFNOSUPPORT, address_family_not_supported);
- MAP_ERR_TO_COND(WSAEALREADY, connection_already_in_progress);
- MAP_ERR_TO_COND(WSAEBADF, bad_file_descriptor);
- MAP_ERR_TO_COND(WSAECONNABORTED, connection_aborted);
- MAP_ERR_TO_COND(WSAECONNREFUSED, connection_refused);
- MAP_ERR_TO_COND(WSAECONNRESET, connection_reset);
- MAP_ERR_TO_COND(WSAEDESTADDRREQ, destination_address_required);
- MAP_ERR_TO_COND(WSAEFAULT, bad_address);
- MAP_ERR_TO_COND(WSAEHOSTUNREACH, host_unreachable);
- MAP_ERR_TO_COND(WSAEINPROGRESS, operation_in_progress);
- MAP_ERR_TO_COND(WSAEINTR, interrupted);
- MAP_ERR_TO_COND(WSAEINVAL, invalid_argument);
- MAP_ERR_TO_COND(WSAEISCONN, already_connected);
- MAP_ERR_TO_COND(WSAEMFILE, too_many_files_open);
- MAP_ERR_TO_COND(WSAEMSGSIZE, message_size);
- MAP_ERR_TO_COND(WSAENAMETOOLONG, filename_too_long);
- MAP_ERR_TO_COND(WSAENETDOWN, network_down);
- MAP_ERR_TO_COND(WSAENETRESET, network_reset);
- MAP_ERR_TO_COND(WSAENETUNREACH, network_unreachable);
- MAP_ERR_TO_COND(WSAENOBUFS, no_buffer_space);
- MAP_ERR_TO_COND(WSAENOPROTOOPT, no_protocol_option);
- MAP_ERR_TO_COND(WSAENOTCONN, not_connected);
- MAP_ERR_TO_COND(WSAENOTSOCK, not_a_socket);
- MAP_ERR_TO_COND(WSAEOPNOTSUPP, operation_not_supported);
- MAP_ERR_TO_COND(WSAEPROTONOSUPPORT, protocol_not_supported);
- MAP_ERR_TO_COND(WSAEPROTOTYPE, wrong_protocol_type);
- MAP_ERR_TO_COND(WSAETIMEDOUT, timed_out);
- MAP_ERR_TO_COND(WSAEWOULDBLOCK, operation_would_block);
- default: return error_condition(ev, system_category());
- }
-}
+++ /dev/null
-//===---------------------- system_error.cpp ------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This was lifted from libc++ and modified for C++03.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/System/system_error.h"
-#include "llvm/System/Errno.h"
-#include <string>
-#include <cstring>
-
-namespace llvm {
-
-// class error_category
-
-error_category::error_category() {
-}
-
-error_category::~error_category() {
-}
-
-error_condition
-error_category::default_error_condition(int ev) const {
- return error_condition(ev, *this);
-}
-
-bool
-error_category::equivalent(int code, const error_condition& condition) const {
- return default_error_condition(code) == condition;
-}
-
-bool
-error_category::equivalent(const error_code& code, int condition) const {
- return *this == code.category() && code.value() == condition;
-}
-
-std::string
-_do_message::message(int ev) const {
- return std::string(sys::StrError(ev));
-}
-
-class _generic_error_category : public _do_message {
-public:
- virtual const char* name() const;
- virtual std::string message(int ev) const;
-};
-
-const char*
-_generic_error_category::name() const {
- return "generic";
-}
-
-std::string
-_generic_error_category::message(int ev) const {
-#ifdef ELAST
- if (ev > ELAST)
- return std::string("unspecified generic_category error");
-#endif // ELAST
- return _do_message::message(ev);
-}
-
-const error_category&
-generic_category() {
- static _generic_error_category s;
- return s;
-}
-
-class _system_error_category : public _do_message {
-public:
- virtual const char* name() const;
- virtual std::string message(int ev) const;
- virtual error_condition default_error_condition(int ev) const;
-};
-
-const char*
-_system_error_category::name() const {
- return "system";
-}
-
-// std::string _system_error_category::message(int ev) const {
-// Is in Platform/system_error.inc
-
-// error_condition _system_error_category::default_error_condition(int ev) const
-// Is in Platform/system_error.inc
-
-const error_category&
-system_category() {
- static _system_error_category s;
- return s;
-}
-
-// error_condition
-
-std::string
-error_condition::message() const {
- return _cat_->message(_val_);
-}
-
-// error_code
-
-std::string
-error_code::message() const {
- return _cat_->message(_val_);
-}
-
-} // end namespace llvm
-
-// Include the truly platform-specific parts of this class.
-#if defined(LLVM_ON_UNIX)
-#include "Unix/system_error.inc"
-#endif
-#if defined(LLVM_ON_WIN32)
-#include "Win32/system_error.inc"
-#endif
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Mutex.h"
+#include "llvm/Support/Mutex.h"
#include "llvm/ADT/DenseMap.h"
#include <algorithm>
#include <cstdlib>
#ifndef X86DISASSEMBLERDECODERCOMMON_H
#define X86DISASSEMBLERDECODERCOMMON_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#define INSTRUCTIONS_SYM x86DisassemblerInstrSpecifiers
#define CONTEXTS_SYM x86DisassemblerContexts
#include "llvm/Function.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/System/Valgrind.h"
+#include "llvm/Support/Valgrind.h"
#include <cstdlib>
#include <cstring>
using namespace llvm;
#include "llvm/GlobalValue.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Host.h"
+#include "llvm/Support/Host.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Type.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/FoldingSet.h"
-#include "llvm/System/Atomic.h"
-#include "llvm/System/Mutex.h"
+#include "llvm/Support/Atomic.h"
+#include "llvm/Support/Mutex.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/LeakDetector.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/StringPool.h"
-#include "llvm/System/RWMutex.h"
-#include "llvm/System/Threading.h"
+#include "llvm/Support/RWMutex.h"
+#include "llvm/Support/Threading.h"
#include "SymbolTableListTraitsImpl.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ManagedStatic.h"
-#include "llvm/System/Mutex.h"
-#include "llvm/System/Threading.h"
+#include "llvm/Support/Mutex.h"
+#include "llvm/Support/Threading.h"
#include "llvm/Value.h"
using namespace llvm;
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PassNameParser.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Mutex.h"
+#include "llvm/Support/Mutex.h"
#include <algorithm>
#include <cstdio>
#include <map>
#include "llvm/PassSupport.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ManagedStatic.h"
-#include "llvm/System/Mutex.h"
+#include "llvm/Support/Mutex.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Threading.h"
+#include "llvm/Support/Threading.h"
#include <algorithm>
#include <cstdarg>
using namespace llvm;
#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Host.h"
+#include "llvm/Support/Host.h"
#include <memory>
using namespace llvm;
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/ToolOutputFile.h"
-#include "llvm/System/Path.h"
-#include "llvm/System/Signals.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Signals.h"
#include <set>
using namespace llvm;
#include "llvm/Support/SystemUtils.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ToolOutputFile.h"
-#include "llvm/System/Path.h"
-#include "llvm/System/Program.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Program.h"
#define DONT_GET_PLUGIN_LOADER_OPTION
#include "llvm/Support/PluginLoader.h"
#define DEBUG_TYPE "toolrunner"
#include "ToolRunner.h"
-#include "llvm/System/Program.h"
+#include "llvm/Support/Program.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/SystemUtils.h"
-#include "llvm/System/Path.h"
+#include "llvm/Support/Path.h"
#include <exception>
#include <vector>
#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/Support/Process.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/Valgrind.h"
#include "llvm/LinkAllVMCore.h"
using namespace llvm;
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/ToolOutputFile.h"
-#include "llvm/System/Host.h"
-#include "llvm/System/Signals.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/Signals.h"
#include "llvm/Target/SubtargetFeature.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.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/Support/Process.h"
+#include "llvm/Support/Signals.h"
#include "llvm/Target/TargetSelect.h"
#include <cerrno>
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Signals.h"
+#include "llvm/Support/Signals.h"
#include <iostream>
#include <algorithm>
#include <iomanip>
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/SystemUtils.h"
#include "llvm/Support/ToolOutputFile.h"
-#include "llvm/System/Signals.h"
+#include "llvm/Support/Signals.h"
#include <memory>
using namespace llvm;
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Signals.h"
+#include "llvm/Support/Signals.h"
#include <cstdio>
#include <map>
#include <algorithm>
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/ToolOutputFile.h"
-#include "llvm/System/Signals.h"
+#include "llvm/Support/Signals.h"
using namespace llvm;
static cl::opt<std::string>
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/SystemUtils.h"
-#include "llvm/System/Signals.h"
+#include "llvm/Support/Signals.h"
#include "llvm/ADT/SmallPtrSet.h"
#include <memory>
using namespace llvm;
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/StandardPasses.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/DynamicLibrary.h"
+#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/PassNameParser.h"
#include "llvm/LinkAllVMCore.h"
#include "llvm/Linker.h"
#include "llvm/LLVMContext.h"
-#include "llvm/System/Program.h"
+#include "llvm/Support/Program.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/SystemUtils.h"
#include "llvm/Support/ToolOutputFile.h"
-#include "llvm/System/Signals.h"
+#include "llvm/Support/Signals.h"
#include "llvm/Config/config.h"
#include <memory>
#include <cstring>
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/SystemUtils.h"
#include "llvm/Support/IRReader.h"
-#include "llvm/System/Signals.h"
-#include "llvm/System/Path.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/Path.h"
#include <memory>
using namespace llvm;
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/ToolOutputFile.h"
-#include "llvm/System/Host.h"
-#include "llvm/System/Signals.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/Signals.h"
#include "Disassembler.h"
using namespace llvm;
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Signals.h"
+#include "llvm/Support/Signals.h"
#include <algorithm>
#include <cctype>
#include <cerrno>
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Format.h"
-#include "llvm/System/Signals.h"
+#include "llvm/Support/Signals.h"
#include <algorithm>
#include <iomanip>
#include <map>
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Signals.h"
+#include "llvm/Support/Signals.h"
#include <iostream>
#include <iomanip>
#include <memory>
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/PassNameParser.h"
-#include "llvm/System/Signals.h"
+#include "llvm/Support/Signals.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/IRReader.h"
#include "llvm/Support/ManagedStatic.h"
#include "gtest/gtest.h"
#include "llvm/ADT/StringMap.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
using namespace llvm;
namespace {
BitReader
AsmParser
Core
- System
Support
)
add_llvm_unittest(VMCore ${VMCoreSources})
set(LLVM_LINK_COMPONENTS
- System
Support
Core
)
)
set(LLVM_LINK_COMPONENTS
- System
+ Support
)
add_llvm_unittest(System
LEVEL = ..
-PARALLEL_DIRS = ADT ExecutionEngine Support System Transforms VMCore Analysis
+PARALLEL_DIRS = ADT ExecutionEngine Support Transforms VMCore Analysis
include $(LEVEL)/Makefile.common
#include "gtest/gtest.h"
#include "llvm/Support/Endian.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include <cstdlib>
#include <ctime>
using namespace llvm;
//===----------------------------------------------------------------------===//
#include "gtest/gtest.h"
-#include "llvm/System/SwapByteOrder.h"
+#include "llvm/Support/SwapByteOrder.h"
#include <cstdlib>
#include <ctime>
using namespace llvm;
LEVEL = ../..
TESTNAME = System
-LINK_COMPONENTS := system support
+LINK_COMPONENTS := support
include $(LEVEL)/Makefile.config
include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
//===----------------------------------------------------------------------===//
// For now, just test that the header file parses.
-#include "llvm/System/PathV2.h"
+#include "llvm/Support/PathV2.h"
#include "gtest/gtest.h"
//===----------------------------------------------------------------------===//
#include "gtest/gtest.h"
-#include "llvm/System/TimeValue.h"
+#include "llvm/Support/TimeValue.h"
#include <time.h>
using namespace llvm;
FileCheck.cpp
)
-target_link_libraries(FileCheck LLVMSupport LLVMSystem)
+target_link_libraries(FileCheck LLVMSupport)
if( MINGW )
target_link_libraries(FileCheck imagehlp psapi)
endif( MINGW )
#include "llvm/Support/Regex.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Signals.h"
+#include "llvm/Support/Signals.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringMap.h"
#include <algorithm>
##===- utils/FileCheck/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 = FileCheck
-USEDLIBS = LLVMSupport.a LLVMSystem.a
+USEDLIBS = LLVMSupport.a
# This tool has no plugins, optimize startup time.
TOOL_NO_EXPORTS = 1
FileUpdate.cpp
)
-target_link_libraries(FileUpdate LLVMSupport LLVMSystem)
+target_link_libraries(FileUpdate LLVMSupport)
if( MINGW )
target_link_libraries(FileUpdate imagehlp psapi)
endif( MINGW )
##===- utils/FileUpdate/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 = FileUpdate
-USEDLIBS = LLVMSupport.a LLVMSystem.a
+USEDLIBS = LLVMSupport.a
# This tool has no plugins, optimize startup time.
TOOL_NO_EXPORTS = 1
KillTheDoctor.cpp
)
-target_link_libraries(KillTheDoctor LLVMSupport LLVMSystem)
+target_link_libraries(KillTheDoctor LLVMSupport)
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/type_traits.h"
-#include "llvm/System/Signals.h"
-#include "llvm/System/system_error.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/system_error.h"
#include <algorithm>
#include <cerrno>
#include <cstdlib>
assert(0 && "Unreachable code!");
}
- o << "#include \"llvm/System/DataTypes.h\"\n";
+ o << "#include \"llvm/Support/DataTypes.h\"\n";
o << "#include <assert.h>\n";
o << '\n';
o << "namespace llvm {\n\n";
X86RecognizableInstr.cpp
)
-target_link_libraries(tblgen LLVMSupport LLVMSystem)
+target_link_libraries(tblgen LLVMSupport)
if( MINGW )
target_link_libraries(tblgen imagehlp psapi)
endif( MINGW )
LEVEL = ../..
TOOLNAME = tblgen
-USEDLIBS = LLVMSupport.a LLVMSystem.a
+USEDLIBS = LLVMSupport.a
REQUIRES_EH := 1
REQUIRES_RTTI := 1
//===----------------------------------------------------------------------===//
#include "Record.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/Support/Format.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/ToolOutputFile.h"
-#include "llvm/System/Signals.h"
+#include "llvm/Support/Signals.h"
#include <algorithm>
#include <cstdio>
using namespace llvm;
##===- utils/fpcmp/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 = fpcmp
-USEDLIBS = LLVMSupport.a LLVMSystem.a
+USEDLIBS = LLVMSupport.a
NO_INSTALL = 1
include $(LEVEL)/Makefile.common
not.cpp
)
-target_link_libraries(not LLVMSupport LLVMSystem)
+target_link_libraries(not LLVMSupport)
if( MINGW )
target_link_libraries(not imagehlp psapi)
endif( MINGW )
##===- utils/not/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 = not
-USEDLIBS = LLVMSupport.a LLVMSystem.a
+USEDLIBS = LLVMSupport.a
# This tool has no plugins, optimize startup time.
TOOL_NO_EXPORTS = 1
//
//===----------------------------------------------------------------------===//
-#include "llvm/System/Path.h"
-#include "llvm/System/Program.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Program.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
//===----------------------------------------------------------------------===//
#include "llvm/Config/config.h"
-#include "llvm/System/Signals.h"
+#include "llvm/Support/Signals.h"
#include "gtest/gtest.h"