summaryrefslogtreecommitdiffstats
path: root/include/llvm/Support
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/Support')
-rw-r--r--include/llvm/Support/BlockFrequency.h2
-rw-r--r--include/llvm/Support/BranchProbability.h31
-rw-r--r--include/llvm/Support/CFG.h8
-rw-r--r--include/llvm/Support/COFF.h294
-rw-r--r--include/llvm/Support/CallSite.h10
-rw-r--r--include/llvm/Support/Capacity.h2
-rw-r--r--include/llvm/Support/CodeGen.h20
-rw-r--r--include/llvm/Support/CommandLine.h154
-rw-r--r--include/llvm/Support/Compiler.h27
-rw-r--r--include/llvm/Support/DOTGraphTraits.h30
-rw-r--r--include/llvm/Support/DataStream.h38
-rw-r--r--include/llvm/Support/DataTypes.h.cmake18
-rw-r--r--include/llvm/Support/DataTypes.h.in15
-rw-r--r--include/llvm/Support/Debug.h6
-rw-r--r--include/llvm/Support/Dwarf.h6
-rw-r--r--include/llvm/Support/DynamicLibrary.h3
-rw-r--r--include/llvm/Support/ELF.h50
-rw-r--r--include/llvm/Support/Endian.h12
-rw-r--r--include/llvm/Support/FileSystem.h228
-rw-r--r--include/llvm/Support/GraphWriter.h14
-rw-r--r--include/llvm/Support/Host.h6
-rw-r--r--include/llvm/Support/IRReader.h10
-rw-r--r--include/llvm/Support/InstVisitor.h105
-rw-r--r--include/llvm/Support/JSONParser.h448
-rw-r--r--include/llvm/Support/LockFileManager.h74
-rw-r--r--include/llvm/Support/MachO.h7
-rw-r--r--include/llvm/Support/ManagedStatic.h5
-rw-r--r--include/llvm/Support/MathExtras.h14
-rw-r--r--include/llvm/Support/MemoryObject.h11
-rw-r--r--include/llvm/Support/PathV1.h14
-rw-r--r--include/llvm/Support/PatternMatch.h91
-rw-r--r--include/llvm/Support/Process.h3
-rw-r--r--include/llvm/Support/Program.h13
-rw-r--r--include/llvm/Support/Recycler.h3
-rw-r--r--include/llvm/Support/SMLoc.h22
-rw-r--r--include/llvm/Support/SaveAndRestore.h47
-rw-r--r--include/llvm/Support/SourceMgr.h52
-rw-r--r--include/llvm/Support/StreamableMemoryObject.h181
-rw-r--r--include/llvm/Support/TargetRegistry.h50
-rw-r--r--include/llvm/Support/TargetSelect.h12
-rw-r--r--include/llvm/Support/Valgrind.h43
-rw-r--r--include/llvm/Support/ValueHandle.h43
-rw-r--r--include/llvm/Support/YAMLParser.h549
-rw-r--r--include/llvm/Support/system_error.h15
-rw-r--r--include/llvm/Support/type_traits.h95
45 files changed, 2543 insertions, 338 deletions
diff --git a/include/llvm/Support/BlockFrequency.h b/include/llvm/Support/BlockFrequency.h
index 554b784..839cf93 100644
--- a/include/llvm/Support/BlockFrequency.h
+++ b/include/llvm/Support/BlockFrequency.h
@@ -14,6 +14,8 @@
#ifndef LLVM_SUPPORT_BLOCKFREQUENCY_H
#define LLVM_SUPPORT_BLOCKFREQUENCY_H
+#include "llvm/Support/DataTypes.h"
+
namespace llvm {
class raw_ostream;
diff --git a/include/llvm/Support/BranchProbability.h b/include/llvm/Support/BranchProbability.h
index 05c24d4..eedf692 100644
--- a/include/llvm/Support/BranchProbability.h
+++ b/include/llvm/Support/BranchProbability.h
@@ -15,6 +15,7 @@
#define LLVM_SUPPORT_BRANCHPROBABILITY_H
#include "llvm/Support/DataTypes.h"
+#include <cassert>
namespace llvm {
@@ -22,7 +23,6 @@ class raw_ostream;
// This class represents Branch Probability as a non-negative fraction.
class BranchProbability {
-
// Numerator
uint32_t N;
@@ -30,19 +30,44 @@ class BranchProbability {
uint32_t D;
public:
- BranchProbability(uint32_t n, uint32_t d);
+ BranchProbability(uint32_t n, uint32_t d) : N(n), D(d) {
+ assert(d > 0 && "Denomiator cannot be 0!");
+ assert(n <= d && "Probability cannot be bigger than 1!");
+ }
+
+ static BranchProbability getZero() { return BranchProbability(0, 1); }
+ static BranchProbability getOne() { return BranchProbability(1, 1); }
uint32_t getNumerator() const { return N; }
uint32_t getDenominator() const { return D; }
// Return (1 - Probability).
- BranchProbability getCompl() {
+ BranchProbability getCompl() const {
return BranchProbability(D - N, D);
}
void print(raw_ostream &OS) const;
void dump() const;
+
+ bool operator==(BranchProbability RHS) const {
+ return (uint64_t)N * RHS.D == (uint64_t)D * RHS.N;
+ }
+ bool operator!=(BranchProbability RHS) const {
+ return !(*this == RHS);
+ }
+ bool operator<(BranchProbability RHS) const {
+ return (uint64_t)N * RHS.D < (uint64_t)D * RHS.N;
+ }
+ bool operator>(BranchProbability RHS) const {
+ return RHS < *this;
+ }
+ bool operator<=(BranchProbability RHS) const {
+ return (uint64_t)N * RHS.D <= (uint64_t)D * RHS.N;
+ }
+ bool operator>=(BranchProbability RHS) const {
+ return RHS <= *this;
+ }
};
raw_ostream &operator<<(raw_ostream &OS, const BranchProbability &Prob);
diff --git a/include/llvm/Support/CFG.h b/include/llvm/Support/CFG.h
index 29313ef..f5dc8ea 100644
--- a/include/llvm/Support/CFG.h
+++ b/include/llvm/Support/CFG.h
@@ -71,6 +71,12 @@ public:
unsigned getOperandNo() const {
return It.getOperandNo();
}
+
+ /// getUse - Return the operand Use in the predecessor's terminator
+ /// of the successor.
+ Use &getUse() const {
+ return It.getUse();
+ }
};
typedef PredIterator<BasicBlock, Value::use_iterator> pred_iterator;
@@ -314,6 +320,7 @@ template <> struct GraphTraits<Function*> : public GraphTraits<BasicBlock*> {
typedef Function::iterator nodes_iterator;
static nodes_iterator nodes_begin(Function *F) { return F->begin(); }
static nodes_iterator nodes_end (Function *F) { return F->end(); }
+ static unsigned size (Function *F) { return F->size(); }
};
template <> struct GraphTraits<const Function*> :
public GraphTraits<const BasicBlock*> {
@@ -323,6 +330,7 @@ template <> struct GraphTraits<const Function*> :
typedef Function::const_iterator nodes_iterator;
static nodes_iterator nodes_begin(const Function *F) { return F->begin(); }
static nodes_iterator nodes_end (const Function *F) { return F->end(); }
+ static unsigned size (const Function *F) { return F->size(); }
};
diff --git a/include/llvm/Support/COFF.h b/include/llvm/Support/COFF.h
index 6739255..88c60ba 100644
--- a/include/llvm/Support/COFF.h
+++ b/include/llvm/Support/COFF.h
@@ -24,6 +24,7 @@
#define LLVM_SUPPORT_WIN_COFF_H
#include "llvm/Support/DataTypes.h"
+#include <cassert>
#include <cstring>
namespace llvm {
@@ -49,8 +50,65 @@ namespace COFF {
};
enum MachineTypes {
- IMAGE_FILE_MACHINE_I386 = 0x14C,
- IMAGE_FILE_MACHINE_AMD64 = 0x8664
+ IMAGE_FILE_MACHINE_UNKNOWN = 0x0,
+ IMAGE_FILE_MACHINE_AM33 = 0x13,
+ IMAGE_FILE_MACHINE_AMD64 = 0x8664,
+ IMAGE_FILE_MACHINE_ARM = 0x1C0,
+ IMAGE_FILE_MACHINE_ARMV7 = 0x1C4,
+ IMAGE_FILE_MACHINE_EBC = 0xEBC,
+ IMAGE_FILE_MACHINE_I386 = 0x14C,
+ IMAGE_FILE_MACHINE_IA64 = 0x200,
+ IMAGE_FILE_MACHINE_M32R = 0x9041,
+ IMAGE_FILE_MACHINE_MIPS16 = 0x266,
+ IMAGE_FILE_MACHINE_MIPSFPU = 0x366,
+ IMAGE_FILE_MACHINE_MIPSFPU16 = 0x466,
+ IMAGE_FILE_MACHINE_POWERPC = 0x1F0,
+ IMAGE_FILE_MACHINE_POWERPCFP = 0x1F1,
+ IMAGE_FILE_MACHINE_R4000 = 0x166,
+ IMAGE_FILE_MACHINE_SH3 = 0x1A2,
+ IMAGE_FILE_MACHINE_SH3DSP = 0x1A3,
+ IMAGE_FILE_MACHINE_SH4 = 0x1A6,
+ IMAGE_FILE_MACHINE_SH5 = 0x1A8,
+ IMAGE_FILE_MACHINE_THUMB = 0x1C2,
+ IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x169
+ };
+
+ enum Characteristics {
+ /// The file does not contain base relocations and must be loaded at its
+ /// preferred base. If this cannot be done, the loader will error.
+ IMAGE_FILE_RELOCS_STRIPPED = 0x0001,
+ /// The file is valid and can be run.
+ IMAGE_FILE_EXECUTABLE_IMAGE = 0x0002,
+ /// COFF line numbers have been stripped. This is deprecated and should be
+ /// 0.
+ IMAGE_FILE_LINE_NUMS_STRIPPED = 0x0004,
+ /// COFF symbol table entries for local symbols have been removed. This is
+ /// deprecated and should be 0.
+ IMAGE_FILE_LOCAL_SYMS_STRIPPED = 0x0008,
+ /// Aggressively trim working set. This is deprecated and must be 0.
+ IMAGE_FILE_AGGRESSIVE_WS_TRIM = 0x0010,
+ /// Image can handle > 2GiB addresses.
+ IMAGE_FILE_LARGE_ADDRESS_AWARE = 0x0020,
+ /// Little endian: the LSB precedes the MSB in memory. This is deprecated
+ /// and should be 0.
+ IMAGE_FILE_BYTES_REVERSED_LO = 0x0080,
+ /// Machine is based on a 32bit word architecture.
+ IMAGE_FILE_32BIT_MACHINE = 0x0100,
+ /// Debugging info has been removed.
+ IMAGE_FILE_DEBUG_STRIPPED = 0x0200,
+ /// If the image is on removable media, fully load it and copy it to swap.
+ IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP = 0x0400,
+ /// If the image is on network media, fully load it and copy it to swap.
+ IMAGE_FILE_NET_RUN_FROM_SWAP = 0x0800,
+ /// The image file is a system file, not a user program.
+ IMAGE_FILE_SYSTEM = 0x1000,
+ /// The image file is a DLL.
+ IMAGE_FILE_DLL = 0x2000,
+ /// This file should only be run on a uniprocessor machine.
+ IMAGE_FILE_UP_SYSTEM_ONLY = 0x4000,
+ /// Big endian: the MSB precedes the LSB in memory. This is deprecated
+ /// and should be 0.
+ IMAGE_FILE_BYTES_REVERSED_HI = 0x8000
};
struct symbol {
@@ -231,6 +289,24 @@ namespace COFF {
IMAGE_REL_AMD64_SSPAN32 = 0x0010
};
+ enum RelocationTypesARM {
+ IMAGE_REL_ARM_ABSOLUTE = 0x0000,
+ IMAGE_REL_ARM_ADDR32 = 0x0001,
+ IMAGE_REL_ARM_ADDR32NB = 0x0002,
+ IMAGE_REL_ARM_BRANCH24 = 0x0003,
+ IMAGE_REL_ARM_BRANCH11 = 0x0004,
+ IMAGE_REL_ARM_TOKEN = 0x0005,
+ IMAGE_REL_ARM_BLX24 = 0x0008,
+ IMAGE_REL_ARM_BLX11 = 0x0009,
+ IMAGE_REL_ARM_SECTION = 0x000E,
+ IMAGE_REL_ARM_SECREL = 0x000F,
+ IMAGE_REL_ARM_MOV32A = 0x0010,
+ IMAGE_REL_ARM_MOV32T = 0x0011,
+ IMAGE_REL_ARM_BRANCH20T = 0x0012,
+ IMAGE_REL_ARM_BRANCH24T = 0x0014,
+ IMAGE_REL_ARM_BLX23T = 0x0015
+ };
+
enum COMDATType {
IMAGE_COMDAT_SELECT_NODUPLICATES = 1,
IMAGE_COMDAT_SELECT_ANY,
@@ -292,7 +368,219 @@ namespace COFF {
AuxiliarySectionDefinition SectionDefinition;
};
-} // End namespace llvm.
+ /// @brief The Import Directory Table.
+ ///
+ /// There is a single array of these and one entry per imported DLL.
+ struct ImportDirectoryTableEntry {
+ uint32_t ImportLookupTableRVA;
+ uint32_t TimeDateStamp;
+ uint32_t ForwarderChain;
+ uint32_t NameRVA;
+ uint32_t ImportAddressTableRVA;
+ };
+
+ /// @brief The PE32 Import Lookup Table.
+ ///
+ /// There is an array of these for each imported DLL. It represents either
+ /// the ordinal to import from the target DLL, or a name to lookup and import
+ /// from the target DLL.
+ ///
+ /// This also happens to be the same format used by the Import Address Table
+ /// when it is initially written out to the image.
+ struct ImportLookupTableEntry32 {
+ uint32_t data;
+
+ /// @brief Is this entry specified by ordinal, or name?
+ bool isOrdinal() const { return data & 0x80000000; }
+
+ /// @brief Get the ordinal value of this entry. isOrdinal must be true.
+ uint16_t getOrdinal() const {
+ assert(isOrdinal() && "ILT entry is not an ordinal!");
+ return data & 0xFFFF;
+ }
+
+ /// @brief Set the ordinal value and set isOrdinal to true.
+ void setOrdinal(uint16_t o) {
+ data = o;
+ data |= 0x80000000;
+ }
+
+ /// @brief Get the Hint/Name entry RVA. isOrdinal must be false.
+ uint32_t getHintNameRVA() const {
+ assert(!isOrdinal() && "ILT entry is not a Hint/Name RVA!");
+ return data;
+ }
+
+ /// @brief Set the Hint/Name entry RVA and set isOrdinal to false.
+ void setHintNameRVA(uint32_t rva) { data = rva; }
+ };
+
+ /// @brief The DOS compatible header at the front of all PEs.
+ struct DOSHeader {
+ uint16_t Magic;
+ uint16_t UsedBytesInTheLastPage;
+ uint16_t FileSizeInPages;
+ uint16_t NumberOfRelocationItems;
+ uint16_t HeaderSizeInParagraphs;
+ uint16_t MinimumExtraParagraphs;
+ uint16_t MaximumExtraParagraphs;
+ uint16_t InitialRelativeSS;
+ uint16_t InitialSP;
+ uint16_t Checksum;
+ uint16_t InitialIP;
+ uint16_t InitialRelativeCS;
+ uint16_t AddressOfRelocationTable;
+ uint16_t OverlayNumber;
+ uint16_t Reserved[4];
+ uint16_t OEMid;
+ uint16_t OEMinfo;
+ uint16_t Reserved2[10];
+ uint32_t AddressOfNewExeHeader;
+ };
+
+ struct PEHeader {
+ uint32_t Signature;
+ header COFFHeader;
+ uint16_t Magic;
+ uint8_t MajorLinkerVersion;
+ uint8_t MinorLinkerVersion;
+ uint32_t SizeOfCode;
+ uint32_t SizeOfInitializedData;
+ uint32_t SizeOfUninitializedData;
+ uint32_t AddressOfEntryPoint; // RVA
+ uint32_t BaseOfCode; // RVA
+ uint32_t BaseOfData; // RVA
+ uint64_t ImageBase;
+ uint32_t SectionAlignment;
+ uint32_t FileAlignment;
+ uint16_t MajorOperatingSystemVersion;
+ uint16_t MinorOperatingSystemVersion;
+ uint16_t MajorImageVersion;
+ uint16_t MinorImageVersion;
+ uint16_t MajorSubsystemVersion;
+ uint16_t MinorSubsystemVersion;
+ uint32_t Win32VersionValue;
+ uint32_t SizeOfImage;
+ uint32_t SizeOfHeaders;
+ uint32_t CheckSum;
+ uint16_t Subsystem;
+ uint16_t DLLCharacteristics;
+ uint64_t SizeOfStackReserve;
+ uint64_t SizeOfStackCommit;
+ uint64_t SizeOfHeapReserve;
+ uint64_t SizeOfHeapCommit;
+ uint32_t LoaderFlags;
+ uint32_t NumberOfRvaAndSize;
+ };
+
+ struct DataDirectory {
+ uint32_t RelativeVirtualAddress;
+ uint32_t Size;
+ };
+
+ enum WindowsSubsystem {
+ IMAGE_SUBSYSTEM_UNKNOWN = 0, ///< An unknown subsystem.
+ IMAGE_SUBSYSTEM_NATIVE = 1, ///< Device drivers and native Windows processes
+ IMAGE_SUBSYSTEM_WINDOWS_GUI = 2, ///< The Windows GUI subsystem.
+ IMAGE_SUBSYSTEM_WINDOWS_CUI = 3, ///< The Windows character subsystem.
+ IMAGE_SUBSYSTEM_POSIX_CUI = 7, ///< The POSIX character subsystem.
+ IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9, ///< Windows CE.
+ IMAGE_SUBSYSTEM_EFI_APPLICATION = 10, ///< An EFI application.
+ IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11, ///< An EFI driver with boot
+ /// services.
+ IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12, ///< An EFI driver with run-time
+ /// services.
+ IMAGE_SUBSYSTEM_EFI_ROM = 13, ///< An EFI ROM image.
+ IMAGE_SUBSYSTEM_XBOX = 14 ///< XBOX.
+ };
+
+ enum DLLCharacteristics {
+ /// DLL can be relocated at load time.
+ IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040,
+ /// Code integrity checks are enforced.
+ IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY = 0x0080,
+ IMAGE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100, ///< Image is NX compatible.
+ /// Isolation aware, but do not isolate the image.
+ IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION = 0x0200,
+ /// Does not use structured exception handling (SEH). No SEH handler may be
+ /// called in this image.
+ IMAGE_DLL_CHARACTERISTICS_NO_SEH = 0x0400,
+ /// Do not bind the image.
+ IMAGE_DLL_CHARACTERISTICS_NO_BIND = 0x0800,
+ IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER = 0x2000, ///< A WDM driver.
+ /// Terminal Server aware.
+ IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000
+ };
+
+ enum DebugType {
+ IMAGE_DEBUG_TYPE_UNKNOWN = 0,
+ IMAGE_DEBUG_TYPE_COFF = 1,
+ IMAGE_DEBUG_TYPE_CODEVIEW = 2,
+ IMAGE_DEBUG_TYPE_FPO = 3,
+ IMAGE_DEBUG_TYPE_MISC = 4,
+ IMAGE_DEBUG_TYPE_EXCEPTION = 5,
+ IMAGE_DEBUG_TYPE_FIXUP = 6,
+ IMAGE_DEBUG_TYPE_OMAP_TO_SRC = 7,
+ IMAGE_DEBUG_TYPE_OMAP_FROM_SRC = 8,
+ IMAGE_DEBUG_TYPE_BORLAND = 9,
+ IMAGE_DEBUG_TYPE_CLSID = 11
+ };
+
+ enum BaseRelocationType {
+ IMAGE_REL_BASED_ABSOLUTE = 0,
+ IMAGE_REL_BASED_HIGH = 1,
+ IMAGE_REL_BASED_LOW = 2,
+ IMAGE_REL_BASED_HIGHLOW = 3,
+ IMAGE_REL_BASED_HIGHADJ = 4,
+ IMAGE_REL_BASED_MIPS_JMPADDR = 5,
+ IMAGE_REL_BASED_ARM_MOV32A = 5,
+ IMAGE_REL_BASED_ARM_MOV32T = 7,
+ IMAGE_REL_BASED_MIPS_JMPADDR16 = 9,
+ IMAGE_REL_BASED_DIR64 = 10
+ };
+
+ enum ImportType {
+ IMPORT_CODE = 0,
+ IMPORT_DATA = 1,
+ IMPORT_CONST = 2
+ };
+
+ enum ImportNameType {
+ /// Import is by ordinal. This indicates that the value in the Ordinal/Hint
+ /// field of the import header is the import's ordinal. If this constant is
+ /// not specified, then the Ordinal/Hint field should always be interpreted
+ /// as the import's hint.
+ IMPORT_ORDINAL = 0,
+ /// The import name is identical to the public symbol name
+ IMPORT_NAME = 1,
+ /// The import name is the public symbol name, but skipping the leading ?,
+ /// @, or optionally _.
+ IMPORT_NAME_NOPREFIX = 2,
+ /// The import name is the public symbol name, but skipping the leading ?,
+ /// @, or optionally _, and truncating at the first @.
+ IMPORT_NAME_UNDECORATE = 3
+ };
+
+ struct ImportHeader {
+ uint16_t Sig1; ///< Must be IMAGE_FILE_MACHINE_UNKNOWN (0).
+ uint16_t Sig2; ///< Must be 0xFFFF.
+ uint16_t Version;
+ uint16_t Machine;
+ uint32_t TimeDateStamp;
+ uint32_t SizeOfData;
+ uint16_t OrdinalHint;
+ uint16_t TypeInfo;
+
+ ImportType getType() const {
+ return static_cast<ImportType>(TypeInfo & 0x3);
+ }
+
+ ImportNameType getNameType() const {
+ return static_cast<ImportNameType>((TypeInfo & 0x1C) >> 3);
+ }
+ };
+
} // End namespace COFF.
+} // End namespace llvm.
#endif
diff --git a/include/llvm/Support/CallSite.h b/include/llvm/Support/CallSite.h
index 04b8c4e..20634ed 100644
--- a/include/llvm/Support/CallSite.h
+++ b/include/llvm/Support/CallSite.h
@@ -237,6 +237,16 @@ public:
#undef CALLSITE_DELEGATE_GETTER
#undef CALLSITE_DELEGATE_SETTER
+ /// @brief Determine whether this argument is not captured.
+ bool doesNotCapture(unsigned ArgNo) const {
+ return paramHasAttr(ArgNo + 1, Attribute::NoCapture);
+ }
+
+ /// @brief Determine whether this argument is passed by value.
+ bool isByValArgument(unsigned ArgNo) const {
+ return paramHasAttr(ArgNo + 1, Attribute::ByVal);
+ }
+
/// hasArgument - Returns true if this CallSite passes the given Value* as an
/// argument to the called function.
bool hasArgument(const Value *Arg) const {
diff --git a/include/llvm/Support/Capacity.h b/include/llvm/Support/Capacity.h
index d8cda43..7460f98 100644
--- a/include/llvm/Support/Capacity.h
+++ b/include/llvm/Support/Capacity.h
@@ -15,6 +15,8 @@
#ifndef LLVM_SUPPORT_CAPACITY_H
#define LLVM_SUPPORT_CAPACITY_H
+#include <cstddef>
+
namespace llvm {
template <typename T>
diff --git a/include/llvm/Support/CodeGen.h b/include/llvm/Support/CodeGen.h
index 41351dc..1b66c94 100644
--- a/include/llvm/Support/CodeGen.h
+++ b/include/llvm/Support/CodeGen.h
@@ -27,6 +27,26 @@ namespace llvm {
enum Model { Default, JITDefault, Small, Kernel, Medium, Large };
}
+ // TLS models.
+ namespace TLSModel {
+ enum Model {
+ GeneralDynamic,
+ LocalDynamic,
+ InitialExec,
+ LocalExec
+ };
+ }
+
+ // Code generation optimization level.
+ namespace CodeGenOpt {
+ enum Level {
+ None, // -O0
+ Less, // -O1
+ Default, // -O2, -Os
+ Aggressive // -O3
+ };
+ }
+
} // end llvm namespace
#endif
diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h
index c6b62a8..c212d2d 100644
--- a/include/llvm/Support/CommandLine.h
+++ b/include/llvm/Support/CommandLine.h
@@ -40,7 +40,7 @@ namespace cl {
//===----------------------------------------------------------------------===//
// ParseCommandLineOptions - Command line option processing entry point.
//
-void ParseCommandLineOptions(int argc, char **argv,
+void ParseCommandLineOptions(int argc, const char * const *argv,
const char *Overview = 0,
bool ReadResponseFiles = false);
@@ -83,10 +83,10 @@ void MarkOptionsChanged();
//
enum NumOccurrencesFlag { // Flags for the number of occurrences allowed
- Optional = 0x01, // Zero or One occurrence
- ZeroOrMore = 0x02, // Zero or more occurrences allowed
- Required = 0x03, // One occurrence required
- OneOrMore = 0x04, // One or more occurrences required
+ Optional = 0x00, // Zero or One occurrence
+ ZeroOrMore = 0x01, // Zero or more occurrences allowed
+ Required = 0x02, // One occurrence required
+ OneOrMore = 0x03, // One or more occurrences required
// ConsumeAfter - Indicates that this option is fed anything that follows the
// last positional argument required by the application (it is an error if
@@ -95,23 +95,20 @@ enum NumOccurrencesFlag { // Flags for the number of occurrences allowed
// found. Once a filename is found, all of the succeeding arguments are
// passed, unprocessed, to the ConsumeAfter option.
//
- ConsumeAfter = 0x05,
-
- OccurrencesMask = 0x07
+ ConsumeAfter = 0x04
};
enum ValueExpected { // Is a value required for the option?
- ValueOptional = 0x08, // The value can appear... or not
- ValueRequired = 0x10, // The value is required to appear!
- ValueDisallowed = 0x18, // A value may not be specified (for flags)
- ValueMask = 0x18
+ // zero reserved for the unspecified value
+ ValueOptional = 0x01, // The value can appear... or not
+ ValueRequired = 0x02, // The value is required to appear!
+ ValueDisallowed = 0x03 // A value may not be specified (for flags)
};
enum OptionHidden { // Control whether -help shows this option
- NotHidden = 0x20, // Option included in -help & -help-hidden
- Hidden = 0x40, // -help doesn't, but -help-hidden does
- ReallyHidden = 0x60, // Neither -help nor -help-hidden show this arg
- HiddenMask = 0x60
+ NotHidden = 0x00, // Option included in -help & -help-hidden
+ Hidden = 0x01, // -help doesn't, but -help-hidden does
+ ReallyHidden = 0x02 // Neither -help nor -help-hidden show this arg
};
// Formatting flags - This controls special features that the option might have
@@ -130,18 +127,16 @@ enum OptionHidden { // Control whether -help shows this option
//
enum FormattingFlags {
- NormalFormatting = 0x000, // Nothing special
- Positional = 0x080, // Is a positional argument, no '-' required
- Prefix = 0x100, // Can this option directly prefix its value?
- Grouping = 0x180, // Can this option group with other options?
- FormattingMask = 0x180 // Union of the above flags.
+ NormalFormatting = 0x00, // Nothing special
+ Positional = 0x01, // Is a positional argument, no '-' required
+ Prefix = 0x02, // Can this option directly prefix its value?
+ Grouping = 0x03 // Can this option group with other options?
};
enum MiscFlags { // Miscellaneous flags to adjust argument
- CommaSeparated = 0x200, // Should this cl::list split between commas?
- PositionalEatsArgs = 0x400, // Should this positional cl::list eat -args?
- Sink = 0x800, // Should this cl::list eat all unknown options?
- MiscMask = 0xE00 // Union of the above flags.
+ CommaSeparated = 0x01, // Should this cl::list split between commas?
+ PositionalEatsArgs = 0x02, // Should this positional cl::list eat -args?
+ Sink = 0x04 // Should this cl::list eat all unknown options?
};
@@ -168,7 +163,15 @@ class Option {
virtual void anchor();
int NumOccurrences; // The number of times specified
- int Flags; // Flags for the argument
+ // Occurrences, HiddenFlag, and Formatting are all enum types but to avoid
+ // problems with signed enums in bitfields.
+ unsigned Occurrences : 3; // enum NumOccurrencesFlag
+ // not using the enum type for 'Value' because zero is an implementation
+ // detail representing the non-value
+ unsigned Value : 2;
+ unsigned HiddenFlag : 2; // enum OptionHidden
+ unsigned Formatting : 2; // enum FormattingFlags
+ unsigned Misc : 3;
unsigned Position; // Position of last occurrence of the option
unsigned AdditionalVals;// Greater than 0 for multi-valued option.
Option *NextRegistered; // Singly linked list of registered options.
@@ -178,21 +181,20 @@ public:
const char *ValueStr; // String describing what the value of this option is
inline enum NumOccurrencesFlag getNumOccurrencesFlag() const {
- return static_cast<enum NumOccurrencesFlag>(Flags & OccurrencesMask);
+ return (enum NumOccurrencesFlag)Occurrences;
}
inline enum ValueExpected getValueExpectedFlag() const {
- int VE = Flags & ValueMask;
- return VE ? static_cast<enum ValueExpected>(VE)
+ return Value ? ((enum ValueExpected)Value)
: getValueExpectedFlagDefault();
}
inline enum OptionHidden getOptionHiddenFlag() const {
- return static_cast<enum OptionHidden>(Flags & HiddenMask);
+ return (enum OptionHidden)HiddenFlag;
}
inline enum FormattingFlags getFormattingFlag() const {
- return static_cast<enum FormattingFlags>(Flags & FormattingMask);
+ return (enum FormattingFlags)Formatting;
}
inline unsigned getMiscFlags() const {
- return Flags & MiscMask;
+ return Misc;
}
inline unsigned getPosition() const { return Position; }
inline unsigned getNumAdditionalVals() const { return AdditionalVals; }
@@ -206,27 +208,21 @@ public:
void setArgStr(const char *S) { ArgStr = S; }
void setDescription(const char *S) { HelpStr = S; }
void setValueStr(const char *S) { ValueStr = S; }
-
- void setFlag(unsigned Flag, unsigned FlagMask) {
- Flags &= ~FlagMask;
- Flags |= Flag;
- }
-
void setNumOccurrencesFlag(enum NumOccurrencesFlag Val) {
- setFlag(Val, OccurrencesMask);
+ Occurrences = Val;
}
- void setValueExpectedFlag(enum ValueExpected Val) { setFlag(Val, ValueMask); }
- void setHiddenFlag(enum OptionHidden Val) { setFlag(Val, HiddenMask); }
- void setFormattingFlag(enum FormattingFlags V) { setFlag(V, FormattingMask); }
- void setMiscFlag(enum MiscFlags M) { setFlag(M, M); }
+ void setValueExpectedFlag(enum ValueExpected Val) { Value = Val; }
+ void setHiddenFlag(enum OptionHidden Val) { HiddenFlag = Val; }
+ void setFormattingFlag(enum FormattingFlags V) { Formatting = V; }
+ void setMiscFlag(enum MiscFlags M) { Misc |= M; }
void setPosition(unsigned pos) { Position = pos; }
protected:
- explicit Option(unsigned DefaultFlags)
- : NumOccurrences(0), Flags(DefaultFlags | NormalFormatting), Position(0),
+ explicit Option(enum NumOccurrencesFlag Occurrences,
+ enum OptionHidden Hidden)
+ : NumOccurrences(0), Occurrences(Occurrences), HiddenFlag(Hidden),
+ Formatting(NormalFormatting), Position(0),
AdditionalVals(0), NextRegistered(0),
ArgStr(""), HelpStr(""), ValueStr("") {
- assert(getNumOccurrencesFlag() != 0 &&
- getOptionHiddenFlag() != 0 && "Not all default flags specified!");
}
inline void setNumAdditionalVals(unsigned n) { AdditionalVals = n; }
@@ -326,6 +322,8 @@ LocationClass<Ty> location(Ty &L) { return LocationClass<Ty>(L); }
struct GenericOptionValue {
virtual ~GenericOptionValue() {}
virtual bool compare(const GenericOptionValue &V) const = 0;
+private:
+ virtual void anchor();
};
template<class DataType> struct OptionValue;
@@ -339,7 +337,7 @@ struct OptionValueBase : public GenericOptionValue {
bool hasValue() const { return false; }
- const DataType &getValue() const { assert(false && "no default value"); }
+ const DataType &getValue() const { llvm_unreachable("no default value"); }
// Some options may take their value from a different data type.
template<class DT>
@@ -416,6 +414,8 @@ struct OptionValue<cl::boolOrDefault> : OptionValueCopy<cl::boolOrDefault> {
setValue(V);
return *this;
}
+private:
+ virtual void anchor();
};
template<>
@@ -431,6 +431,8 @@ struct OptionValue<std::string> : OptionValueCopy<std::string> {
setValue(V);
return *this;
}
+private:
+ virtual void anchor();
};
//===----------------------------------------------------------------------===//
@@ -1171,14 +1173,14 @@ public:
// One option...
template<class M0t>
- explicit opt(const M0t &M0) : Option(Optional | NotHidden) {
+ explicit opt(const M0t &M0) : Option(Optional, NotHidden) {
apply(M0, this);
done();
}
// Two options...
template<class M0t, class M1t>
- opt(const M0t &M0, const M1t &M1) : Option(Optional | NotHidden) {
+ opt(const M0t &M0, const M1t &M1) : Option(Optional, NotHidden) {
apply(M0, this); apply(M1, this);
done();
}
@@ -1186,21 +1188,21 @@ public:
// Three options...
template<class M0t, class M1t, class M2t>
opt(const M0t &M0, const M1t &M1,
- const M2t &M2) : Option(Optional | NotHidden) {
+ const M2t &M2) : Option(Optional, NotHidden) {
apply(M0, this); apply(M1, this); apply(M2, this);
done();
}
// Four options...
template<class M0t, class M1t, class M2t, class M3t>
opt(const M0t &M0, const M1t &M1, const M2t &M2,
- const M3t &M3) : Option(Optional | NotHidden) {
+ const M3t &M3) : Option(Optional, NotHidden) {
apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
done();
}
// Five options...
template<class M0t, class M1t, class M2t, class M3t, class M4t>
opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
- const M4t &M4) : Option(Optional | NotHidden) {
+ const M4t &M4) : Option(Optional, NotHidden) {
apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
apply(M4, this);
done();
@@ -1209,7 +1211,7 @@ public:
template<class M0t, class M1t, class M2t, class M3t,
class M4t, class M5t>
opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
- const M4t &M4, const M5t &M5) : Option(Optional | NotHidden) {
+ const M4t &M4, const M5t &M5) : Option(Optional, NotHidden) {
apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
apply(M4, this); apply(M5, this);
done();
@@ -1219,7 +1221,7 @@ public:
class M4t, class M5t, class M6t>
opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
const M4t &M4, const M5t &M5,
- const M6t &M6) : Option(Optional | NotHidden) {
+ const M6t &M6) : Option(Optional, NotHidden) {
apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
apply(M4, this); apply(M5, this); apply(M6, this);
done();
@@ -1229,7 +1231,7 @@ public:
class M4t, class M5t, class M6t, class M7t>
opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
const M4t &M4, const M5t &M5, const M6t &M6,
- const M7t &M7) : Option(Optional | NotHidden) {
+ const M7t &M7) : Option(Optional, NotHidden) {
apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
apply(M4, this); apply(M5, this); apply(M6, this); apply(M7, this);
done();
@@ -1338,34 +1340,34 @@ public:
// One option...
template<class M0t>
- explicit list(const M0t &M0) : Option(ZeroOrMore | NotHidden) {
+ explicit list(const M0t &M0) : Option(ZeroOrMore, NotHidden) {
apply(M0, this);
done();
}
// Two options...
template<class M0t, class M1t>
- list(const M0t &M0, const M1t &M1) : Option(ZeroOrMore | NotHidden) {
+ list(const M0t &M0, const M1t &M1) : Option(ZeroOrMore, NotHidden) {
apply(M0, this); apply(M1, this);
done();
}
// Three options...
template<class M0t, class M1t, class M2t>
list(const M0t &M0, const M1t &M1, const M2t &M2)
- : Option(ZeroOrMore | NotHidden) {
+ : Option(ZeroOrMore, NotHidden) {
apply(M0, this); apply(M1, this); apply(M2, this);
done();
}
// Four options...
template<class M0t, class M1t, class M2t, class M3t>
list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3)
- : Option(ZeroOrMore | NotHidden) {
+ : Option(ZeroOrMore, NotHidden) {
apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
done();
}
// Five options...
template<class M0t, class M1t, class M2t, class M3t, class M4t>
list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
- const M4t &M4) : Option(ZeroOrMore | NotHidden) {
+ const M4t &M4) : Option(ZeroOrMore, NotHidden) {
apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
apply(M4, this);
done();
@@ -1374,7 +1376,7 @@ public:
template<class M0t, class M1t, class M2t, class M3t,
class M4t, class M5t>
list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
- const M4t &M4, const M5t &M5) : Option(ZeroOrMore | NotHidden) {
+ const M4t &M4, const M5t &M5) : Option(ZeroOrMore, NotHidden) {
apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
apply(M4, this); apply(M5, this);
done();
@@ -1384,7 +1386,7 @@ public:
class M4t, class M5t, class M6t>
list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
const M4t &M4, const M5t &M5, const M6t &M6)
- : Option(ZeroOrMore | NotHidden) {
+ : Option(ZeroOrMore, NotHidden) {
apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
apply(M4, this); apply(M5, this); apply(M6, this);
done();
@@ -1394,7 +1396,7 @@ public:
class M4t, class M5t, class M6t, class M7t>
list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
const M4t &M4, const M5t &M5, const M6t &M6,
- const M7t &M7) : Option(ZeroOrMore | NotHidden) {
+ const M7t &M7) : Option(ZeroOrMore, NotHidden) {
apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
apply(M4, this); apply(M5, this); apply(M6, this); apply(M7, this);
done();
@@ -1536,34 +1538,34 @@ public:
// One option...
template<class M0t>
- explicit bits(const M0t &M0) : Option(ZeroOrMore | NotHidden) {
+ explicit bits(const M0t &M0) : Option(ZeroOrMore, NotHidden) {
apply(M0, this);
done();
}
// Two options...
template<class M0t, class M1t>
- bits(const M0t &M0, const M1t &M1) : Option(ZeroOrMore | NotHidden) {
+ bits(const M0t &M0, const M1t &M1) : Option(ZeroOrMore, NotHidden) {
apply(M0, this); apply(M1, this);
done();
}
// Three options...
template<class M0t, class M1t, class M2t>
bits(const M0t &M0, const M1t &M1, const M2t &M2)
- : Option(ZeroOrMore | NotHidden) {
+ : Option(ZeroOrMore, NotHidden) {
apply(M0, this); apply(M1, this); apply(M2, this);
done();
}
// Four options...
template<class M0t, class M1t, class M2t, class M3t>
bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3)
- : Option(ZeroOrMore | NotHidden) {
+ : Option(ZeroOrMore, NotHidden) {
apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
done();
}
// Five options...
template<class M0t, class M1t, class M2t, class M3t, class M4t>
bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
- const M4t &M4) : Option(ZeroOrMore | NotHidden) {
+ const M4t &M4) : Option(ZeroOrMore, NotHidden) {
apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
apply(M4, this);
done();
@@ -1572,7 +1574,7 @@ public:
template<class M0t, class M1t, class M2t, class M3t,
class M4t, class M5t>
bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
- const M4t &M4, const M5t &M5) : Option(ZeroOrMore | NotHidden) {
+ const M4t &M4, const M5t &M5) : Option(ZeroOrMore, NotHidden) {
apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
apply(M4, this); apply(M5, this);
done();
@@ -1582,7 +1584,7 @@ public:
class M4t, class M5t, class M6t>
bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
const M4t &M4, const M5t &M5, const M6t &M6)
- : Option(ZeroOrMore | NotHidden) {
+ : Option(ZeroOrMore, NotHidden) {
apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
apply(M4, this); apply(M5, this); apply(M6, this);
done();
@@ -1592,7 +1594,7 @@ public:
class M4t, class M5t, class M6t, class M7t>
bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
const M4t &M4, const M5t &M5, const M6t &M6,
- const M7t &M7) : Option(ZeroOrMore | NotHidden) {
+ const M7t &M7) : Option(ZeroOrMore, NotHidden) {
apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
apply(M4, this); apply(M5, this); apply(M6, this); apply(M7, this);
done();
@@ -1632,27 +1634,27 @@ public:
// One option...
template<class M0t>
- explicit alias(const M0t &M0) : Option(Optional | Hidden), AliasFor(0) {
+ explicit alias(const M0t &M0) : Option(Optional, Hidden), AliasFor(0) {
apply(M0, this);
done();
}
// Two options...
template<class M0t, class M1t>
- alias(const M0t &M0, const M1t &M1) : Option(Optional | Hidden), AliasFor(0) {
+ alias(const M0t &M0, const M1t &M1) : Option(Optional, Hidden), AliasFor(0) {
apply(M0, this); apply(M1, this);
done();
}
// Three options...
template<class M0t, class M1t, class M2t>
alias(const M0t &M0, const M1t &M1, const M2t &M2)
- : Option(Optional | Hidden), AliasFor(0) {
+ : Option(Optional, Hidden), AliasFor(0) {
apply(M0, this); apply(M1, this); apply(M2, this);
done();
}
// Four options...
template<class M0t, class M1t, class M2t, class M3t>
alias(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3)
- : Option(Optional | Hidden), AliasFor(0) {
+ : Option(Optional, Hidden), AliasFor(0) {
apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
done();
}
diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h
index e092157..d0b186e 100644
--- a/include/llvm/Support/Compiler.h
+++ b/include/llvm/Support/Compiler.h
@@ -49,16 +49,22 @@
#define LLVM_ATTRIBUTE_UNUSED
#endif
-#ifdef __GNUC__ // aka 'ATTRIBUTE_CONST' but following LLVM Conventions.
-#define LLVM_ATTRIBUTE_READNONE __attribute__((__const__))
+#if (__GNUC__ >= 4) && !defined(__MINGW32__) && !defined(__CYGWIN__)
+#define LLVM_ATTRIBUTE_WEAK __attribute__((__weak__))
#else
-#define LLVM_ATTRIBUTE_READNONE
+#define LLVM_ATTRIBUTE_WEAK
#endif
-#ifdef __GNUC__ // aka 'ATTRIBUTE_PURE' but following LLVM Conventions.
-#define LLVM_ATTRIBUTE_READONLY __attribute__((__pure__))
+#ifdef __GNUC__ // aka 'CONST' but following LLVM Conventions.
+#define LLVM_READNONE __attribute__((__const__))
#else
-#define LLVM_ATTRIBUTE_READONLY
+#define LLVM_READNONE
+#endif
+
+#ifdef __GNUC__ // aka 'PURE' but following LLVM Conventions.
+#define LLVM_READONLY __attribute__((__pure__))
+#else
+#define LLVM_READONLY
#endif
#if (__GNUC__ >= 4)
@@ -67,6 +73,7 @@
#define BUILTIN_EXPECT(EXPR, VALUE) (EXPR)
#endif
+
// C++ doesn't support 'extern template' of template specializations. GCC does,
// but requires __extension__ before it. In the header, use this:
// EXTERN_TEMPLATE_INSTANTIATION(class foo<bar>);
@@ -111,6 +118,14 @@
#define LLVM_ATTRIBUTE_NORETURN
#endif
+// LLVM_EXTENSION - Support compilers where we have a keyword to suppress
+// pedantic diagnostics.
+#ifdef __GNUC__
+#define LLVM_EXTENSION __extension__
+#else
+#define LLVM_EXTENSION
+#endif
+
// LLVM_ATTRIBUTE_DEPRECATED(decl, "message")
#if __has_feature(attribute_deprecated_with_message)
# define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
diff --git a/include/llvm/Support/DOTGraphTraits.h b/include/llvm/Support/DOTGraphTraits.h
index 3cb8164..483f267 100644
--- a/include/llvm/Support/DOTGraphTraits.h
+++ b/include/llvm/Support/DOTGraphTraits.h
@@ -42,13 +42,13 @@ public:
/// top of the graph.
///
template<typename GraphType>
- static std::string getGraphName(const GraphType& Graph) { return ""; }
+ static std::string getGraphName(const GraphType &) { return ""; }
/// getGraphProperties - Return any custom properties that should be included
/// in the top level graph structure for dot.
///
template<typename GraphType>
- static std::string getGraphProperties(const GraphType& Graph) {
+ static std::string getGraphProperties(const GraphType &) {
return "";
}
@@ -61,44 +61,44 @@ public:
/// isNodeHidden - If the function returns true, the given node is not
/// displayed in the graph.
- static bool isNodeHidden(const void *Node) {
+ static bool isNodeHidden(const void *) {
return false;
}
/// getNodeLabel - Given a node and a pointer to the top level graph, return
/// the label to print in the node.
template<typename GraphType>
- std::string getNodeLabel(const void *Node, const GraphType& Graph) {
+ std::string getNodeLabel(const void *, const GraphType &) {
return "";
}
/// hasNodeAddressLabel - If this method returns true, the address of the node
/// is added to the label of the node.
template<typename GraphType>
- static bool hasNodeAddressLabel(const void *Node, const GraphType& Graph) {
+ static bool hasNodeAddressLabel(const void *, const GraphType &) {
return false;
}
/// If you want to specify custom node attributes, this is the place to do so
///
template<typename GraphType>
- static std::string getNodeAttributes(const void *Node,
- const GraphType& Graph) {
+ static std::string getNodeAttributes(const void *,
+ const GraphType &) {
return "";
}
/// If you want to override the dot attributes printed for a particular edge,
/// override this method.
template<typename EdgeIter, typename GraphType>
- static std::string getEdgeAttributes(const void *Node, EdgeIter EI,
- const GraphType& Graph) {
+ static std::string getEdgeAttributes(const void *, EdgeIter,
+ const GraphType &) {
return "";
}
/// getEdgeSourceLabel - If you want to label the edge source itself,
/// implement this method.
template<typename EdgeIter>
- static std::string getEdgeSourceLabel(const void *Node, EdgeIter I) {
+ static std::string getEdgeSourceLabel(const void *, EdgeIter) {
return "";
}
@@ -106,7 +106,7 @@ public:
/// should actually target another edge source, not a node. If this method is
/// implemented, getEdgeTarget should be implemented.
template<typename EdgeIter>
- static bool edgeTargetsEdgeSource(const void *Node, EdgeIter I) {
+ static bool edgeTargetsEdgeSource(const void *, EdgeIter) {
return false;
}
@@ -114,7 +114,7 @@ public:
/// called to determine which outgoing edge of Node is the target of this
/// edge.
template<typename EdgeIter>
- static EdgeIter getEdgeTarget(const void *Node, EdgeIter I) {
+ static EdgeIter getEdgeTarget(const void *, EdgeIter I) {
return I;
}
@@ -126,13 +126,13 @@ public:
/// numEdgeDestLabels - If hasEdgeDestLabels, this function returns the
/// number of incoming edge labels the given node has.
- static unsigned numEdgeDestLabels(const void *Node) {
+ static unsigned numEdgeDestLabels(const void *) {
return 0;
}
/// getEdgeDestLabel - If hasEdgeDestLabels, this function returns the
/// incoming edge label with the given index in the given node.
- static std::string getEdgeDestLabel(const void *Node, unsigned i) {
+ static std::string getEdgeDestLabel(const void *, unsigned) {
return "";
}
@@ -143,7 +143,7 @@ public:
/// it to add things to the output graph.
///
template<typename GraphType, typename GraphWriter>
- static void addCustomGraphFeatures(const GraphType& Graph, GraphWriter &GW) {}
+ static void addCustomGraphFeatures(const GraphType &, GraphWriter &) {}
};
diff --git a/include/llvm/Support/DataStream.h b/include/llvm/Support/DataStream.h
new file mode 100644
index 0000000..fedb0c9
--- /dev/null
+++ b/include/llvm/Support/DataStream.h
@@ -0,0 +1,38 @@
+//===---- llvm/Support/DataStream.h - Lazy bitcode streaming ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header defines DataStreamer, which fetches bytes of data from
+// a stream source. It provides support for streaming (lazy reading) of
+// data, e.g. bitcode
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_SUPPORT_DATASTREAM_H_
+#define LLVM_SUPPORT_DATASTREAM_H_
+
+#include <string>
+
+namespace llvm {
+
+class DataStreamer {
+public:
+ /// Fetch bytes [start-end) from the stream, and write them to the
+ /// buffer pointed to by buf. Returns the number of bytes actually written.
+ virtual size_t GetBytes(unsigned char *buf, size_t len) = 0;
+
+ virtual ~DataStreamer();
+};
+
+DataStreamer *getDataFileStreamer(const std::string &Filename,
+ std::string *Err);
+
+}
+
+#endif // LLVM_SUPPORT_DATASTREAM_H_
diff --git a/include/llvm/Support/DataTypes.h.cmake b/include/llvm/Support/DataTypes.h.cmake
index 8c0220a..a3a6489 100644
--- a/include/llvm/Support/DataTypes.h.cmake
+++ b/include/llvm/Support/DataTypes.h.cmake
@@ -94,6 +94,9 @@ typedef u_int64_t uint64_t;
#else /* _MSC_VER */
/* Visual C++ doesn't provide standard integer headers, but it does provide
built-in data types. */
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
#include <stdlib.h>
#include <stddef.h>
#include <sys/types.h>
@@ -167,9 +170,24 @@ typedef signed int ssize_t;
# define UINT64_C(C) C##ui64
#endif
+#ifndef PRId64
+# define PRId64 "I64d"
+#endif
+#ifndef PRIi64
+# define PRIi64 "I64i"
+#endif
+#ifndef PRIo64
+# define PRIo64 "I64o"
+#endif
+#ifndef PRIu64
+# define PRIu64 "I64u"
+#endif
#ifndef PRIx64
# define PRIx64 "I64x"
#endif
+#ifndef PRIX64
+# define PRIX64 "I64X"
+#endif
#endif /* _MSC_VER */
diff --git a/include/llvm/Support/DataTypes.h.in b/include/llvm/Support/DataTypes.h.in
index 425805a..b492bb1 100644
--- a/include/llvm/Support/DataTypes.h.in
+++ b/include/llvm/Support/DataTypes.h.in
@@ -167,9 +167,24 @@ typedef signed int ssize_t;
# define UINT64_C(C) C##ui64
#endif
+#ifndef PRId64
+# define PRId64 "I64d"
+#endif
+#ifndef PRIi64
+# define PRIi64 "I64i"
+#endif
+#ifndef PRIo64
+# define PRIo64 "I64o"
+#endif
+#ifndef PRIu64
+# define PRIu64 "I64u"
+#endif
#ifndef PRIx64
# define PRIx64 "I64x"
#endif
+#ifndef PRIX64
+# define PRIX64 "I64X"
+#endif
#endif /* _MSC_VER */
diff --git a/include/llvm/Support/Debug.h b/include/llvm/Support/Debug.h
index 8651fc1..e723272 100644
--- a/include/llvm/Support/Debug.h
+++ b/include/llvm/Support/Debug.h
@@ -35,14 +35,14 @@ class raw_ostream;
#ifndef DEBUG_TYPE
#define DEBUG_TYPE ""
#endif
-
+
#ifndef NDEBUG
/// DebugFlag - This boolean is set to true if the '-debug' command line option
/// is specified. This should probably not be referenced directly, instead, use
/// the DEBUG macro below.
///
extern bool DebugFlag;
-
+
/// isCurrentDebugType - Return true if the specified string is the debug type
/// specified on the command line, or if none was specified on the command line
/// with the -debug-only=X option.
@@ -54,7 +54,7 @@ bool isCurrentDebugType(const char *Type);
/// debug output to be produced.
///
void SetCurrentDebugType(const char *Type);
-
+
/// DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug
/// information. In the '-debug' option is specified on the commandline, and if
/// this is a debug build, then the code specified as the option to the macro
diff --git a/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h
index 30f9187..8f18a99 100644
--- a/include/llvm/Support/Dwarf.h
+++ b/include/llvm/Support/Dwarf.h
@@ -22,7 +22,8 @@ namespace llvm {
// Debug info constants.
enum {
- LLVMDebugVersion = (11 << 16), // Current version of debug information.
+ LLVMDebugVersion = (12 << 16), // Current version of debug information.
+ LLVMDebugVersion11 = (11 << 16), // Constant for version 11.
LLVMDebugVersion10 = (10 << 16), // Constant for version 10.
LLVMDebugVersion9 = (9 << 16), // Constant for version 9.
LLVMDebugVersion8 = (8 << 16), // Constant for version 8.
@@ -130,6 +131,7 @@ enum dwarf_constants {
DW_TAG_GNU_template_parameter_pack = 0x4107,
DW_TAG_GNU_formal_parameter_pack = 0x4108,
DW_TAG_lo_user = 0x4080,
+ DW_TAG_APPLE_property = 0x4200,
DW_TAG_hi_user = 0xffff,
// Children flag
@@ -269,6 +271,7 @@ enum dwarf_constants {
DW_AT_APPLE_property_setter = 0x3fea,
DW_AT_APPLE_property_attribute = 0x3feb,
DW_AT_APPLE_objc_complete_type = 0x3fec,
+ DW_AT_APPLE_property = 0x3fed,
// Attribute form encodings
DW_FORM_addr = 0x01,
@@ -526,6 +529,7 @@ enum dwarf_constants {
DW_LANG_D = 0x0013,
DW_LANG_Python = 0x0014,
DW_LANG_lo_user = 0x8000,
+ DW_LANG_Mips_Assembler = 0x8001,
DW_LANG_hi_user = 0xffff,
// Identifier case codes
diff --git a/include/llvm/Support/DynamicLibrary.h b/include/llvm/Support/DynamicLibrary.h
index 288936b..0f59cbf 100644
--- a/include/llvm/Support/DynamicLibrary.h
+++ b/include/llvm/Support/DynamicLibrary.h
@@ -17,6 +17,9 @@
#include <string>
namespace llvm {
+
+class StringRef;
+
namespace sys {
/// This class provides a portable interface to dynamic libraries which also
diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h
index c5b85e2..04953b6 100644
--- a/include/llvm/Support/ELF.h
+++ b/include/llvm/Support/ELF.h
@@ -599,7 +599,25 @@ enum {
R_ARM_THM_TLS_DESCSEQ32 = 0x82
};
+// Mips Specific e_flags
+enum {
+ EF_MIPS_NOREORDER = 0x00000001, // Don't reorder instructions
+ EF_MIPS_PIC = 0x00000002, // Position independent code
+ EF_MIPS_CPIC = 0x00000004, // Call object with Position independent code
+ EF_MIPS_ARCH_1 = 0x00000000, // MIPS1 instruction set
+ EF_MIPS_ARCH_2 = 0x10000000, // MIPS2 instruction set
+ EF_MIPS_ARCH_3 = 0x20000000, // MIPS3 instruction set
+ EF_MIPS_ARCH_4 = 0x30000000, // MIPS4 instruction set
+ EF_MIPS_ARCH_5 = 0x40000000, // MIPS5 instruction set
+ EF_MIPS_ARCH_32 = 0x50000000, // MIPS32 instruction set per linux not elf.h
+ EF_MIPS_ARCH_64 = 0x60000000, // MIPS64 instruction set per linux not elf.h
+ EF_MIPS_ARCH_32R2 = 0x70000000, // mips32r2
+ EF_MIPS_ARCH_64R2 = 0x80000000, // mips64r2
+ EF_MIPS_ARCH = 0xf0000000 // Mask for applying EF_MIPS_ARCH_ variant
+};
+
// ELF Relocation types for Mips
+// .
enum {
R_MIPS_NONE = 0,
R_MIPS_16 = 1,
@@ -611,6 +629,7 @@ enum {
R_MIPS_GPREL16 = 7,
R_MIPS_LITERAL = 8,
R_MIPS_GOT16 = 9,
+ R_MIPS_GOT = 9,
R_MIPS_PC16 = 10,
R_MIPS_CALL16 = 11,
R_MIPS_GPREL32 = 12,
@@ -717,6 +736,9 @@ enum {
SHT_GROUP = 17, // Section group.
SHT_SYMTAB_SHNDX = 18, // Indices for SHN_XINDEX entries.
SHT_LOOS = 0x60000000, // Lowest operating system-specific type.
+ SHT_GNU_verdef = 0x6ffffffd, // GNU version definitions.
+ SHT_GNU_verneed = 0x6ffffffe, // GNU version references.
+ SHT_GNU_versym = 0x6fffffff, // GNU symbol versions table.
SHT_HIOS = 0x6fffffff, // Highest operating system-specific type.
SHT_LOPROC = 0x70000000, // Lowest processor architecture-specific type.
// Fixme: All this is duplicated in MCSectionELF. Why??
@@ -871,6 +893,7 @@ enum {
STT_TLS = 6, // Thread local data object
STT_LOOS = 7, // Lowest operating system-specific symbol type
STT_HIOS = 8, // Highest operating system-specific symbol type
+ STT_GNU_IFUNC = 10, // GNU indirect function
STT_LOPROC = 13, // Lowest processor-specific symbol type
STT_HIPROC = 15 // Highest processor-specific symbol type
};
@@ -1084,6 +1107,33 @@ enum {
DF_STATIC_TLS = 0x10 // Reject attempts to load dynamically.
};
+// ElfXX_VerDef structure version (GNU versioning)
+enum {
+ VER_DEF_NONE = 0,
+ VER_DEF_CURRENT = 1
+};
+
+// VerDef Flags (ElfXX_VerDef::vd_flags)
+enum {
+ VER_FLG_BASE = 0x1,
+ VER_FLG_WEAK = 0x2,
+ VER_FLG_INFO = 0x4
+};
+
+// Special constants for the version table. (SHT_GNU_versym/.gnu.version)
+enum {
+ VER_NDX_LOCAL = 0, // Unversioned local symbol
+ VER_NDX_GLOBAL = 1, // Unversioned global symbol
+ VERSYM_VERSION = 0x7fff, // Version Index mask
+ VERSYM_HIDDEN = 0x8000 // Hidden bit (non-default version)
+};
+
+// ElfXX_VerNeed structure version (GNU versioning)
+enum {
+ VER_NEED_NONE = 0,
+ VER_NEED_CURRENT = 1
+};
+
} // end namespace ELF
} // end namespace llvm
diff --git a/include/llvm/Support/Endian.h b/include/llvm/Support/Endian.h
index af1b506..733ab75 100644
--- a/include/llvm/Support/Endian.h
+++ b/include/llvm/Support/Endian.h
@@ -98,6 +98,9 @@ public:
operator value_type() const {
return endian::read_le<value_type, unaligned>(Value);
}
+ void operator=(value_type newValue) {
+ endian::write_le<value_type, unaligned>((void *)&Value, newValue);
+ }
private:
uint8_t Value[sizeof(value_type)];
};
@@ -108,6 +111,9 @@ public:
operator value_type() const {
return endian::read_be<value_type, unaligned>(Value);
}
+ void operator=(value_type newValue) {
+ endian::write_be<value_type, unaligned>((void *)&Value, newValue);
+ }
private:
uint8_t Value[sizeof(value_type)];
};
@@ -118,6 +124,9 @@ public:
operator value_type() const {
return endian::read_le<value_type, aligned>(&Value);
}
+ void operator=(value_type newValue) {
+ endian::write_le<value_type, aligned>((void *)&Value, newValue);
+ }
private:
value_type Value;
};
@@ -128,6 +137,9 @@ public:
operator value_type() const {
return endian::read_be<value_type, aligned>(&Value);
}
+ void operator=(value_type newValue) {
+ endian::write_be<value_type, aligned>((void *)&Value, newValue);
+ }
private:
value_type Value;
};
diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h
index a868e5f..e6f9926 100644
--- a/include/llvm/Support/FileSystem.h
+++ b/include/llvm/Support/FileSystem.h
@@ -27,14 +27,21 @@
#ifndef LLVM_SUPPORT_FILE_SYSTEM_H
#define LLVM_SUPPORT_FILE_SYSTEM_H
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/PathV1.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/system_error.h"
#include <ctime>
#include <iterator>
+#include <stack>
#include <string>
+#include <vector>
+
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
namespace llvm {
namespace sys {
@@ -91,7 +98,20 @@ struct space_info {
/// a platform specific member to store the result.
class file_status
{
- // implementation defined status field.
+ #if defined(LLVM_ON_UNIX)
+ dev_t st_dev;
+ ino_t st_ino;
+ #elif defined (LLVM_ON_WIN32)
+ uint32_t LastWriteTimeHigh;
+ uint32_t LastWriteTimeLow;
+ uint32_t VolumeSerialNumber;
+ uint32_t FileSizeHigh;
+ uint32_t FileSizeLow;
+ uint32_t FileIndexHigh;
+ uint32_t FileIndexLow;
+ #endif
+ friend bool equivalent(file_status A, file_status B);
+ friend error_code status(const Twine &path, file_status &result);
file_type Type;
public:
explicit file_status(file_type v=file_type::status_error)
@@ -101,6 +121,44 @@ public:
void type(file_type v) { Type = v; }
};
+/// file_magic - An "enum class" enumeration of file types based on magic (the first
+/// N bytes of the file).
+struct file_magic {
+ enum _ {
+ unknown = 0, ///< Unrecognized file
+ bitcode, ///< Bitcode file
+ archive, ///< ar style archive file
+ elf_relocatable, ///< ELF Relocatable object file
+ elf_executable, ///< ELF Executable image
+ elf_shared_object, ///< ELF dynamically linked shared lib
+ elf_core, ///< ELF core image
+ macho_object, ///< Mach-O Object file
+ macho_executable, ///< Mach-O Executable
+ macho_fixed_virtual_memory_shared_lib, ///< Mach-O Shared Lib, FVM
+ macho_core, ///< Mach-O Core File
+ macho_preload_executabl, ///< Mach-O Preloaded Executable
+ macho_dynamically_linked_shared_lib, ///< Mach-O dynlinked shared lib
+ macho_dynamic_linker, ///< The Mach-O dynamic linker
+ macho_bundle, ///< Mach-O Bundle file
+ macho_dynamically_linked_shared_lib_stub, ///< Mach-O Shared lib stub
+ macho_dsym_companion, ///< Mach-O dSYM companion file
+ coff_object, ///< COFF object file
+ pecoff_executable ///< PECOFF executable file
+ };
+
+ bool is_object() const {
+ return v_ == unknown ? false : true;
+ }
+
+ file_magic() : v_(unknown) {}
+ file_magic(_ v) : v_(v) {}
+ explicit file_magic(int v) : v_(_(v)) {}
+ operator int() const {return v_;}
+
+private:
+ int v_;
+};
+
/// @}
/// @name Physical Operators
/// @{
@@ -241,6 +299,8 @@ bool equivalent(file_status A, file_status B);
/// @brief Do paths represent the same thing?
///
+/// assert(status_known(A) || status_known(B));
+///
/// @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
@@ -397,13 +457,16 @@ error_code has_magic(const Twine &path, const Twine &magic, bool &result);
error_code get_magic(const Twine &path, uint32_t len,
SmallVectorImpl<char> &result);
+/// @brief Identify the type of a binary file based on how magical it is.
+file_magic identify_magic(StringRef magic);
+
/// @brief Get and identify \a path's type based on its content.
///
/// @param path Input path.
/// @param result Set to the type of file, or LLVMFileType::Unknown_FileType.
/// @results errc::success if result has been successfully set, otherwise a
/// platform specific error_code.
-error_code identify_magic(const Twine &path, LLVMFileType &result);
+error_code identify_magic(const Twine &path, file_magic &result);
/// @brief Get library paths the system linker uses.
///
@@ -479,76 +542,171 @@ public:
bool operator>=(const directory_entry& rhs) const;
};
+namespace detail {
+ struct DirIterState;
+
+ error_code directory_iterator_construct(DirIterState&, StringRef);
+ error_code directory_iterator_increment(DirIterState&);
+ error_code directory_iterator_destruct(DirIterState&);
+
+ /// DirIterState - Keeps state for the directory_iterator. It is reference
+ /// counted in order to preserve InputIterator semantics on copy.
+ struct DirIterState : public RefCountedBase<DirIterState> {
+ DirIterState()
+ : IterationHandle(0) {}
+
+ ~DirIterState() {
+ directory_iterator_destruct(*this);
+ }
+
+ intptr_t IterationHandle;
+ directory_entry CurrentEntry;
+ };
+}
+
/// 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 {
- intptr_t IterationHandle;
- directory_entry CurrentEntry;
-
- // Platform implementations implement these functions to handle iteration.
- friend error_code directory_iterator_construct(directory_iterator &it,
- StringRef path);
- friend error_code directory_iterator_increment(directory_iterator &it);
- friend error_code directory_iterator_destruct(directory_iterator &it);
+ IntrusiveRefCntPtr<detail::DirIterState> State;
public:
- explicit directory_iterator(const Twine &path, error_code &ec)
- : IterationHandle(0) {
+ explicit directory_iterator(const Twine &path, error_code &ec) {
+ State = new detail::DirIterState;
SmallString<128> path_storage;
- ec = directory_iterator_construct(*this, path.toStringRef(path_storage));
+ ec = detail::directory_iterator_construct(*State,
+ path.toStringRef(path_storage));
}
- /// Construct end iterator.
- directory_iterator() : IterationHandle(0) {}
-
- ~directory_iterator() {
- directory_iterator_destruct(*this);
+ explicit directory_iterator(const directory_entry &de, error_code &ec) {
+ State = new detail::DirIterState;
+ ec = detail::directory_iterator_construct(*State, de.path());
}
+ /// Construct end iterator.
+ directory_iterator() : State(new detail::DirIterState) {}
+
// No operator++ because we need error_code.
directory_iterator &increment(error_code &ec) {
- ec = directory_iterator_increment(*this);
+ ec = directory_iterator_increment(*State);
return *this;
}
- const directory_entry &operator*() const { return CurrentEntry; }
- const directory_entry *operator->() const { return &CurrentEntry; }
+ const directory_entry &operator*() const { return State->CurrentEntry; }
+ const directory_entry *operator->() const { return &State->CurrentEntry; }
+
+ bool operator==(const directory_iterator &RHS) const {
+ return State->CurrentEntry == RHS.State->CurrentEntry;
+ }
bool operator!=(const directory_iterator &RHS) const {
- return CurrentEntry != RHS.CurrentEntry;
+ return !(*this == RHS);
}
// Other members as required by
// C++ Std, 24.1.1 Input iterators [input.iterators]
};
+namespace detail {
+ /// RecDirIterState - Keeps state for the recursive_directory_iterator. It is
+ /// reference counted in order to preserve InputIterator semantics on copy.
+ struct RecDirIterState : public RefCountedBase<RecDirIterState> {
+ RecDirIterState()
+ : Level(0)
+ , HasNoPushRequest(false) {}
+
+ std::stack<directory_iterator, std::vector<directory_iterator> > Stack;
+ uint16_t Level;
+ bool HasNoPushRequest;
+ };
+}
+
/// 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
+ IntrusiveRefCntPtr<detail::RecDirIterState> State;
public:
- explicit recursive_directory_iterator(const Twine &path, error_code &ec);
+ recursive_directory_iterator() {}
+ explicit recursive_directory_iterator(const Twine &path, error_code &ec)
+ : State(new detail::RecDirIterState) {
+ State->Stack.push(directory_iterator(path, ec));
+ if (State->Stack.top() == directory_iterator())
+ State.reset();
+ }
// No operator++ because we need error_code.
- directory_iterator &increment(error_code &ec);
+ recursive_directory_iterator &increment(error_code &ec) {
+ static const directory_iterator end_itr;
+
+ if (State->HasNoPushRequest)
+ State->HasNoPushRequest = false;
+ else {
+ file_status st;
+ if ((ec = State->Stack.top()->status(st))) return *this;
+ if (is_directory(st)) {
+ State->Stack.push(directory_iterator(*State->Stack.top(), ec));
+ if (ec) return *this;
+ if (State->Stack.top() != end_itr) {
+ ++State->Level;
+ return *this;
+ }
+ State->Stack.pop();
+ }
+ }
+
+ while (!State->Stack.empty()
+ && State->Stack.top().increment(ec) == end_itr) {
+ State->Stack.pop();
+ --State->Level;
+ }
+
+ // Check if we are done. If so, create an end iterator.
+ if (State->Stack.empty())
+ State.reset();
- const directory_entry &operator*() const;
- const directory_entry *operator->() const;
+ return *this;
+ }
+
+ const directory_entry &operator*() const { return *State->Stack.top(); }
+ const directory_entry *operator->() const { return &*State->Stack.top(); }
// observers
- /// Gets the current level. path is at level 0.
- int level() const;
+ /// Gets the current level. Starting path is at level 0.
+ int level() const { return State->Level; }
+
/// Returns true if no_push has been called for this directory_entry.
- bool no_push_request() const;
+ bool no_push_request() const { return State->HasNoPushRequest; }
// modifiers
/// Goes up one level if Level > 0.
- void pop();
+ void pop() {
+ assert(State && "Cannot pop and end itertor!");
+ assert(State->Level > 0 && "Cannot pop an iterator with level < 1");
+
+ static const directory_iterator end_itr;
+ error_code ec;
+ do {
+ if (ec)
+ report_fatal_error("Error incrementing directory iterator.");
+ State->Stack.pop();
+ --State->Level;
+ } while (!State->Stack.empty()
+ && State->Stack.top().increment(ec) == end_itr);
+
+ // Check if we are done. If so, create an end iterator.
+ if (State->Stack.empty())
+ State.reset();
+ }
+
/// Does not go down into the current directory_entry.
- void no_push();
+ void no_push() { State->HasNoPushRequest = true; }
+ bool operator==(const recursive_directory_iterator &RHS) const {
+ return State == RHS.State;
+ }
+
+ bool operator!=(const recursive_directory_iterator &RHS) const {
+ return !(*this == RHS);
+ }
// Other members as required by
// C++ Std, 24.1.1 Input iterators [input.iterators]
};
diff --git a/include/llvm/Support/GraphWriter.h b/include/llvm/Support/GraphWriter.h
index eab0c9d..ae32da5 100644
--- a/include/llvm/Support/GraphWriter.h
+++ b/include/llvm/Support/GraphWriter.h
@@ -296,26 +296,26 @@ public:
template<typename GraphType>
raw_ostream &WriteGraph(raw_ostream &O, const GraphType &G,
bool ShortNames = false,
- const std::string &Title = "") {
+ const Twine &Title = "") {
// Start the graph emission process...
GraphWriter<GraphType> W(O, G, ShortNames);
// Emit the graph.
- W.writeGraph(Title);
+ W.writeGraph(Title.str());
return O;
}
template<typename GraphType>
-sys::Path WriteGraph(const GraphType &G, const std::string &Name,
- bool ShortNames = false, const std::string &Title = "") {
+sys::Path WriteGraph(const GraphType &G, const Twine &Name,
+ bool ShortNames = false, const Twine &Title = "") {
std::string ErrMsg;
sys::Path Filename = sys::Path::GetTemporaryDirectory(&ErrMsg);
if (Filename.isEmpty()) {
errs() << "Error: " << ErrMsg << "\n";
return Filename;
}
- Filename.appendComponent(Name + ".dot");
+ Filename.appendComponent((Name + ".dot").str());
if (Filename.makeUnique(true,&ErrMsg)) {
errs() << "Error: " << ErrMsg << "\n";
return sys::Path();
@@ -341,8 +341,8 @@ sys::Path WriteGraph(const GraphType &G, const std::string &Name,
/// then cleanup. For use from the debugger.
///
template<typename GraphType>
-void ViewGraph(const GraphType &G, const std::string &Name,
- bool ShortNames = false, const std::string &Title = "",
+void ViewGraph(const GraphType &G, const Twine &Name,
+ bool ShortNames = false, const Twine &Title = "",
GraphProgram::Name Program = GraphProgram::DOT) {
sys::Path Filename = llvm::WriteGraph(G, Name, ShortNames, Title);
diff --git a/include/llvm/Support/Host.h b/include/llvm/Support/Host.h
index f77d4c1..b331016 100644
--- a/include/llvm/Support/Host.h
+++ b/include/llvm/Support/Host.h
@@ -33,14 +33,14 @@ namespace sys {
return !isLittleEndianHost();
}
- /// getHostTriple() - Return the target triple of the running
- /// system.
+ /// getDefaultTargetTriple() - Return the default target triple the compiler
+ /// has been configured to produce code for.
///
/// 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();
+ std::string getDefaultTargetTriple();
/// 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
diff --git a/include/llvm/Support/IRReader.h b/include/llvm/Support/IRReader.h
index 292c001..6d8a9b3 100644
--- a/include/llvm/Support/IRReader.h
+++ b/include/llvm/Support/IRReader.h
@@ -40,7 +40,8 @@ namespace llvm {
std::string ErrMsg;
Module *M = getLazyBitcodeModule(Buffer, Context, &ErrMsg);
if (M == 0) {
- Err = SMDiagnostic(Buffer->getBufferIdentifier(), ErrMsg);
+ Err = SMDiagnostic(Buffer->getBufferIdentifier(), SourceMgr::DK_Error,
+ ErrMsg);
// ParseBitcodeFile does not take ownership of the Buffer in the
// case of an error.
delete Buffer;
@@ -60,7 +61,7 @@ namespace llvm {
LLVMContext &Context) {
OwningPtr<MemoryBuffer> File;
if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), File)) {
- Err = SMDiagnostic(Filename,
+ Err = SMDiagnostic(Filename, SourceMgr::DK_Error,
"Could not open input file: " + ec.message());
return 0;
}
@@ -80,7 +81,8 @@ namespace llvm {
std::string ErrMsg;
Module *M = ParseBitcodeFile(Buffer, Context, &ErrMsg);
if (M == 0)
- Err = SMDiagnostic(Buffer->getBufferIdentifier(), ErrMsg);
+ Err = SMDiagnostic(Buffer->getBufferIdentifier(), SourceMgr::DK_Error,
+ ErrMsg);
// ParseBitcodeFile does not take ownership of the Buffer.
delete Buffer;
return M;
@@ -97,7 +99,7 @@ namespace llvm {
LLVMContext &Context) {
OwningPtr<MemoryBuffer> File;
if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), File)) {
- Err = SMDiagnostic(Filename,
+ Err = SMDiagnostic(Filename, SourceMgr::DK_Error,
"Could not open input file: " + ec.message());
return 0;
}
diff --git a/include/llvm/Support/InstVisitor.h b/include/llvm/Support/InstVisitor.h
index a661c4f..52de8f6 100644
--- a/include/llvm/Support/InstVisitor.h
+++ b/include/llvm/Support/InstVisitor.h
@@ -14,6 +14,7 @@
#include "llvm/Function.h"
#include "llvm/Instructions.h"
#include "llvm/Module.h"
+#include "llvm/Support/CallSite.h"
#include "llvm/Support/ErrorHandling.h"
namespace llvm {
@@ -157,54 +158,74 @@ public:
// Specific Instruction type classes... note that all of the casts are
// necessary because we use the instruction classes as opaque types...
//
- RetTy visitReturnInst(ReturnInst &I) { DELEGATE(TerminatorInst);}
- RetTy visitBranchInst(BranchInst &I) { DELEGATE(TerminatorInst);}
- RetTy visitSwitchInst(SwitchInst &I) { DELEGATE(TerminatorInst);}
- RetTy visitIndirectBrInst(IndirectBrInst &I) { DELEGATE(TerminatorInst);}
- RetTy visitInvokeInst(InvokeInst &I) { DELEGATE(TerminatorInst);}
- RetTy visitUnwindInst(UnwindInst &I) { DELEGATE(TerminatorInst);}
- RetTy visitResumeInst(ResumeInst &I) { DELEGATE(TerminatorInst);}
- RetTy visitUnreachableInst(UnreachableInst &I) { DELEGATE(TerminatorInst);}
- RetTy visitICmpInst(ICmpInst &I) { DELEGATE(CmpInst);}
- RetTy visitFCmpInst(FCmpInst &I) { DELEGATE(CmpInst);}
- RetTy visitAllocaInst(AllocaInst &I) { DELEGATE(Instruction); }
- RetTy visitLoadInst(LoadInst &I) { DELEGATE(Instruction); }
- RetTy visitStoreInst(StoreInst &I) { DELEGATE(Instruction); }
- RetTy visitAtomicCmpXchgInst(AtomicCmpXchgInst &I){ DELEGATE(Instruction); }
- RetTy visitAtomicRMWInst(AtomicRMWInst &I) { DELEGATE(Instruction); }
- RetTy visitFenceInst(FenceInst &I) { DELEGATE(Instruction); }
- RetTy visitGetElementPtrInst(GetElementPtrInst &I){ DELEGATE(Instruction); }
- RetTy visitPHINode(PHINode &I) { DELEGATE(Instruction); }
- RetTy visitTruncInst(TruncInst &I) { DELEGATE(CastInst); }
- RetTy visitZExtInst(ZExtInst &I) { DELEGATE(CastInst); }
- RetTy visitSExtInst(SExtInst &I) { DELEGATE(CastInst); }
- RetTy visitFPTruncInst(FPTruncInst &I) { DELEGATE(CastInst); }
- RetTy visitFPExtInst(FPExtInst &I) { DELEGATE(CastInst); }
- RetTy visitFPToUIInst(FPToUIInst &I) { DELEGATE(CastInst); }
- RetTy visitFPToSIInst(FPToSIInst &I) { DELEGATE(CastInst); }
- RetTy visitUIToFPInst(UIToFPInst &I) { DELEGATE(CastInst); }
- RetTy visitSIToFPInst(SIToFPInst &I) { DELEGATE(CastInst); }
- RetTy visitPtrToIntInst(PtrToIntInst &I) { DELEGATE(CastInst); }
- RetTy visitIntToPtrInst(IntToPtrInst &I) { DELEGATE(CastInst); }
- RetTy visitBitCastInst(BitCastInst &I) { DELEGATE(CastInst); }
- RetTy visitSelectInst(SelectInst &I) { DELEGATE(Instruction); }
- RetTy visitCallInst(CallInst &I) { DELEGATE(Instruction); }
- RetTy visitVAArgInst(VAArgInst &I) { DELEGATE(Instruction); }
+ RetTy visitReturnInst(ReturnInst &I) { DELEGATE(TerminatorInst);}
+ RetTy visitBranchInst(BranchInst &I) { DELEGATE(TerminatorInst);}
+ RetTy visitSwitchInst(SwitchInst &I) { DELEGATE(TerminatorInst);}
+ RetTy visitIndirectBrInst(IndirectBrInst &I) { DELEGATE(TerminatorInst);}
+ RetTy visitResumeInst(ResumeInst &I) { DELEGATE(TerminatorInst);}
+ RetTy visitUnreachableInst(UnreachableInst &I) { DELEGATE(TerminatorInst);}
+ RetTy visitICmpInst(ICmpInst &I) { DELEGATE(CmpInst);}
+ RetTy visitFCmpInst(FCmpInst &I) { DELEGATE(CmpInst);}
+ RetTy visitAllocaInst(AllocaInst &I) { DELEGATE(UnaryInstruction);}
+ RetTy visitLoadInst(LoadInst &I) { DELEGATE(UnaryInstruction);}
+ RetTy visitStoreInst(StoreInst &I) { DELEGATE(Instruction);}
+ RetTy visitAtomicCmpXchgInst(AtomicCmpXchgInst &I) { DELEGATE(Instruction);}
+ RetTy visitAtomicRMWInst(AtomicRMWInst &I) { DELEGATE(Instruction);}
+ RetTy visitFenceInst(FenceInst &I) { DELEGATE(Instruction);}
+ RetTy visitGetElementPtrInst(GetElementPtrInst &I){ DELEGATE(Instruction);}
+ RetTy visitPHINode(PHINode &I) { DELEGATE(Instruction);}
+ RetTy visitTruncInst(TruncInst &I) { DELEGATE(CastInst);}
+ RetTy visitZExtInst(ZExtInst &I) { DELEGATE(CastInst);}
+ RetTy visitSExtInst(SExtInst &I) { DELEGATE(CastInst);}
+ RetTy visitFPTruncInst(FPTruncInst &I) { DELEGATE(CastInst);}
+ RetTy visitFPExtInst(FPExtInst &I) { DELEGATE(CastInst);}
+ RetTy visitFPToUIInst(FPToUIInst &I) { DELEGATE(CastInst);}
+ RetTy visitFPToSIInst(FPToSIInst &I) { DELEGATE(CastInst);}
+ RetTy visitUIToFPInst(UIToFPInst &I) { DELEGATE(CastInst);}
+ RetTy visitSIToFPInst(SIToFPInst &I) { DELEGATE(CastInst);}
+ RetTy visitPtrToIntInst(PtrToIntInst &I) { DELEGATE(CastInst);}
+ RetTy visitIntToPtrInst(IntToPtrInst &I) { DELEGATE(CastInst);}
+ RetTy visitBitCastInst(BitCastInst &I) { DELEGATE(CastInst);}
+ RetTy visitSelectInst(SelectInst &I) { DELEGATE(Instruction);}
+ RetTy visitVAArgInst(VAArgInst &I) { DELEGATE(UnaryInstruction);}
RetTy visitExtractElementInst(ExtractElementInst &I) { DELEGATE(Instruction);}
- RetTy visitInsertElementInst(InsertElementInst &I) { DELEGATE(Instruction); }
- RetTy visitShuffleVectorInst(ShuffleVectorInst &I) { DELEGATE(Instruction); }
- RetTy visitExtractValueInst(ExtractValueInst &I) { DELEGATE(Instruction);}
- RetTy visitInsertValueInst(InsertValueInst &I) { DELEGATE(Instruction); }
- RetTy visitLandingPadInst(LandingPadInst &I) { DELEGATE(Instruction); }
+ RetTy visitInsertElementInst(InsertElementInst &I) { DELEGATE(Instruction);}
+ RetTy visitShuffleVectorInst(ShuffleVectorInst &I) { DELEGATE(Instruction);}
+ RetTy visitExtractValueInst(ExtractValueInst &I){ DELEGATE(UnaryInstruction);}
+ RetTy visitInsertValueInst(InsertValueInst &I) { DELEGATE(Instruction); }
+ RetTy visitLandingPadInst(LandingPadInst &I) { DELEGATE(Instruction); }
+
+ // Call and Invoke are slightly different as they delegate first through
+ // a generic CallSite visitor.
+ RetTy visitCallInst(CallInst &I) {
+ return static_cast<SubClass*>(this)->visitCallSite(&I);
+ }
+ RetTy visitInvokeInst(InvokeInst &I) {
+ return static_cast<SubClass*>(this)->visitCallSite(&I);
+ }
// Next level propagators: If the user does not overload a specific
// instruction type, they can overload one of these to get the whole class
// of instructions...
//
- RetTy visitTerminatorInst(TerminatorInst &I) { DELEGATE(Instruction); }
- RetTy visitBinaryOperator(BinaryOperator &I) { DELEGATE(Instruction); }
- RetTy visitCmpInst(CmpInst &I) { DELEGATE(Instruction); }
- RetTy visitCastInst(CastInst &I) { DELEGATE(Instruction); }
+ RetTy visitCastInst(CastInst &I) { DELEGATE(UnaryInstruction);}
+ RetTy visitBinaryOperator(BinaryOperator &I) { DELEGATE(Instruction);}
+ RetTy visitCmpInst(CmpInst &I) { DELEGATE(Instruction);}
+ RetTy visitTerminatorInst(TerminatorInst &I) { DELEGATE(Instruction);}
+ RetTy visitUnaryInstruction(UnaryInstruction &I){ DELEGATE(Instruction);}
+
+ // Provide a special visitor for a 'callsite' that visits both calls and
+ // invokes. When unimplemented, properly delegates to either the terminator or
+ // regular instruction visitor.
+ RetTy visitCallSite(CallSite CS) {
+ assert(CS);
+ Instruction &I = *CS.getInstruction();
+ if (CS.isCall())
+ DELEGATE(Instruction);
+
+ assert(CS.isInvoke());
+ DELEGATE(TerminatorInst);
+ }
// If the user wants a 'default' case, they can choose to override this
// function. If this function is not overloaded in the user's subclass, then
diff --git a/include/llvm/Support/JSONParser.h b/include/llvm/Support/JSONParser.h
new file mode 100644
index 0000000..11149f1
--- /dev/null
+++ b/include/llvm/Support/JSONParser.h
@@ -0,0 +1,448 @@
+//===--- JSONParser.h - Simple JSON parser ----------------------*- 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 a JSON parser.
+//
+// See http://www.json.org/ for an overview.
+// See http://www.ietf.org/rfc/rfc4627.txt for the full standard.
+//
+// FIXME: Currently this supports a subset of JSON. Specifically, support
+// for numbers, booleans and null for values is missing.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_JSON_PARSER_H
+#define LLVM_SUPPORT_JSON_PARSER_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/SourceMgr.h"
+
+namespace llvm {
+
+class JSONContainer;
+class JSONString;
+class JSONValue;
+class JSONKeyValuePair;
+
+/// \brief Base class for a parsable JSON atom.
+///
+/// This class has no semantics other than being a unit of JSON data which can
+/// be parsed out of a JSON document.
+class JSONAtom {
+public:
+ /// \brief Possible types of JSON objects.
+ enum Kind { JK_KeyValuePair, JK_Array, JK_Object, JK_String };
+
+ /// \brief Returns the type of this value.
+ Kind getKind() const { return MyKind; }
+
+ static bool classof(const JSONAtom *Atom) { return true; }
+
+protected:
+ JSONAtom(Kind MyKind) : MyKind(MyKind) {}
+
+private:
+ Kind MyKind;
+};
+
+/// \brief A parser for JSON text.
+///
+/// Use an object of JSONParser to iterate over the values of a JSON text.
+/// All objects are parsed during the iteration, so you can only iterate once
+/// over the JSON text, but the cost of partial iteration is minimized.
+/// Create a new JSONParser if you want to iterate multiple times.
+class JSONParser {
+public:
+ /// \brief Create a JSONParser for the given input.
+ ///
+ /// Parsing is started via parseRoot(). Access to the object returned from
+ /// parseRoot() will parse the input lazily.
+ JSONParser(StringRef Input, SourceMgr *SM);
+
+ /// \brief Returns the outermost JSON value (either an array or an object).
+ ///
+ /// Can return NULL if the input does not start with an array or an object.
+ /// The object is not parsed yet - the caller must iterate over the
+ /// returned object to trigger parsing.
+ ///
+ /// A JSONValue can be either a JSONString, JSONObject or JSONArray.
+ JSONValue *parseRoot();
+
+ /// \brief Parses the JSON text and returns whether it is valid JSON.
+ ///
+ /// In case validate() return false, failed() will return true and
+ /// getErrorMessage() will return the parsing error.
+ bool validate();
+
+ /// \brief Returns true if an error occurs during parsing.
+ ///
+ /// If there was an error while parsing an object that was created by
+ /// iterating over the result of 'parseRoot', 'failed' will return true.
+ bool failed() const;
+
+private:
+ /// \brief These methods manage the implementation details of parsing new JSON
+ /// atoms.
+ /// @{
+ JSONString *parseString();
+ JSONValue *parseValue();
+ JSONKeyValuePair *parseKeyValuePair();
+ /// @}
+
+ /// \brief Helpers to parse the elements out of both forms of containers.
+ /// @{
+ const JSONAtom *parseElement(JSONAtom::Kind ContainerKind);
+ StringRef::iterator parseFirstElement(JSONAtom::Kind ContainerKind,
+ char StartChar, char EndChar,
+ const JSONAtom *&Element);
+ StringRef::iterator parseNextElement(JSONAtom::Kind ContainerKind,
+ char EndChar,
+ const JSONAtom *&Element);
+ /// @}
+
+ /// \brief Whitespace parsing.
+ /// @{
+ void nextNonWhitespace();
+ bool isWhitespace();
+ /// @}
+
+ /// \brief These methods are used for error handling.
+ /// {
+ void setExpectedError(StringRef Expected, StringRef Found);
+ void setExpectedError(StringRef Expected, char Found);
+ bool errorIfAtEndOfFile(StringRef Message);
+ bool errorIfNotAt(char C, StringRef Message);
+ /// }
+
+ /// \brief Skips all elements in the given container.
+ bool skipContainer(const JSONContainer &Container);
+
+ /// \brief Skips to the next position behind the given JSON atom.
+ bool skip(const JSONAtom &Atom);
+
+ /// All nodes are allocated by the parser and will be deallocated when the
+ /// parser is destroyed.
+ BumpPtrAllocator ValueAllocator;
+
+ /// \brief The original input to the parser.
+ MemoryBuffer *InputBuffer;
+
+ /// \brief The source manager used for diagnostics and buffer management.
+ SourceMgr *SM;
+
+ /// \brief The current position in the parse stream.
+ StringRef::iterator Position;
+
+ /// \brief The end position for fast EOF checks without introducing
+ /// unnecessary dereferences.
+ StringRef::iterator End;
+
+ /// \brief If true, an error has occurred.
+ bool Failed;
+
+ friend class JSONContainer;
+};
+
+
+/// \brief Base class for JSON value objects.
+///
+/// This object represents an abstract JSON value. It is the root node behind
+/// the group of JSON entities that can represent top-level values in a JSON
+/// document. It has no API, and is just a placeholder in the type hierarchy of
+/// nodes.
+class JSONValue : public JSONAtom {
+protected:
+ JSONValue(Kind MyKind) : JSONAtom(MyKind) {}
+
+public:
+ /// \brief dyn_cast helpers
+ ///@{
+ static bool classof(const JSONAtom *Atom) {
+ switch (Atom->getKind()) {
+ case JK_Array:
+ case JK_Object:
+ case JK_String:
+ return true;
+ case JK_KeyValuePair:
+ return false;
+ }
+ llvm_unreachable("Invalid JSONAtom kind");
+ }
+ static bool classof(const JSONValue *Value) { return true; }
+ ///@}
+};
+
+/// \brief Gives access to the text of a JSON string.
+///
+/// FIXME: Implement a method to return the unescaped text.
+class JSONString : public JSONValue {
+public:
+ /// \brief Returns the underlying parsed text of the string.
+ ///
+ /// This is the unescaped content of the JSON text.
+ /// See http://www.ietf.org/rfc/rfc4627.txt for details.
+ StringRef getRawText() const { return RawText; }
+
+private:
+ JSONString(StringRef RawText) : JSONValue(JK_String), RawText(RawText) {}
+
+ StringRef RawText;
+
+ friend class JSONParser;
+
+public:
+ /// \brief dyn_cast helpers
+ ///@{
+ static bool classof(const JSONAtom *Atom) {
+ return Atom->getKind() == JK_String;
+ }
+ static bool classof(const JSONString *String) { return true; }
+ ///@}
+};
+
+/// \brief A (key, value) tuple of type (JSONString *, JSONValue *).
+///
+/// Note that JSONKeyValuePair is not a JSONValue, it is a bare JSONAtom.
+/// JSONKeyValuePairs can be elements of a JSONObject, but not of a JSONArray.
+/// They are not viable as top-level values either.
+class JSONKeyValuePair : public JSONAtom {
+public:
+ const JSONString * const Key;
+ const JSONValue * const Value;
+
+private:
+ JSONKeyValuePair(const JSONString *Key, const JSONValue *Value)
+ : JSONAtom(JK_KeyValuePair), Key(Key), Value(Value) {}
+
+ friend class JSONParser;
+
+public:
+ /// \brief dyn_cast helpers
+ ///@{
+ static bool classof(const JSONAtom *Atom) {
+ return Atom->getKind() == JK_KeyValuePair;
+ }
+ static bool classof(const JSONKeyValuePair *KeyValuePair) { return true; }
+ ///@}
+};
+
+/// \brief Implementation of JSON containers (arrays and objects).
+///
+/// JSONContainers drive the lazy parsing of JSON arrays and objects via
+/// forward iterators.
+class JSONContainer : public JSONValue {
+private:
+ /// \brief An iterator that parses the underlying container during iteration.
+ ///
+ /// Iterators on the same collection use shared state, so when multiple copies
+ /// of an iterator exist, only one is allowed to be used for iteration;
+ /// iterating multiple copies of an iterator of the same collection will lead
+ /// to undefined behavior.
+ class AtomIterator {
+ public:
+ AtomIterator(const AtomIterator &I) : Container(I.Container) {}
+
+ /// \brief Iterator interface.
+ ///@{
+ bool operator==(const AtomIterator &I) const {
+ if (isEnd() || I.isEnd())
+ return isEnd() == I.isEnd();
+ return Container->Position == I.Container->Position;
+ }
+ bool operator!=(const AtomIterator &I) const {
+ return !(*this == I);
+ }
+ AtomIterator &operator++() {
+ Container->parseNextElement();
+ return *this;
+ }
+ const JSONAtom *operator*() {
+ return Container->Current;
+ }
+ ///@}
+
+ private:
+ /// \brief Create an iterator for which 'isEnd' returns true.
+ AtomIterator() : Container(0) {}
+
+ /// \brief Create an iterator for the given container.
+ AtomIterator(const JSONContainer *Container) : Container(Container) {}
+
+ bool isEnd() const {
+ return Container == 0 || Container->Position == StringRef::iterator();
+ }
+
+ const JSONContainer * const Container;
+
+ friend class JSONContainer;
+ };
+
+protected:
+ /// \brief An iterator for the specified AtomT.
+ ///
+ /// Used for the implementation of iterators for JSONArray and JSONObject.
+ template <typename AtomT>
+ class IteratorTemplate : public std::iterator<std::forward_iterator_tag,
+ const AtomT*> {
+ public:
+ explicit IteratorTemplate(const AtomIterator& AtomI)
+ : AtomI(AtomI) {}
+
+ bool operator==(const IteratorTemplate &I) const {
+ return AtomI == I.AtomI;
+ }
+ bool operator!=(const IteratorTemplate &I) const { return !(*this == I); }
+
+ IteratorTemplate &operator++() {
+ ++AtomI;
+ return *this;
+ }
+
+ const AtomT *operator*() { return dyn_cast<AtomT>(*AtomI); }
+
+ private:
+ AtomIterator AtomI;
+ };
+
+ JSONContainer(JSONParser *Parser, char StartChar, char EndChar,
+ JSONAtom::Kind ContainerKind)
+ : JSONValue(ContainerKind), Parser(Parser),
+ Position(), Current(0), Started(false),
+ StartChar(StartChar), EndChar(EndChar) {}
+
+ /// \brief Returns a lazy parsing iterator over the container.
+ ///
+ /// As the iterator drives the parse stream, begin() must only be called
+ /// once per container.
+ AtomIterator atom_begin() const {
+ if (Started)
+ report_fatal_error("Cannot parse container twice.");
+ Started = true;
+ // Set up the position and current element when we begin iterating over the
+ // container.
+ Position = Parser->parseFirstElement(getKind(), StartChar, EndChar, Current);
+ return AtomIterator(this);
+ }
+ AtomIterator atom_end() const {
+ return AtomIterator();
+ }
+
+private:
+ AtomIterator atom_current() const {
+ if (!Started)
+ return atom_begin();
+
+ return AtomIterator(this);
+ }
+
+ /// \brief Parse the next element in the container into the Current element.
+ ///
+ /// This routine is called as an iterator into this container walks through
+ /// its elements. It mutates the container's internal current node to point to
+ /// the next atom of the container.
+ void parseNextElement() const {
+ Parser->skip(*Current);
+ Position = Parser->parseNextElement(getKind(), EndChar, Current);
+ }
+
+ // For parsing, JSONContainers call back into the JSONParser.
+ JSONParser * const Parser;
+
+ // 'Position', 'Current' and 'Started' store the state of the parse stream
+ // for iterators on the container, they don't change the container's elements
+ // and are thus marked as mutable.
+ mutable StringRef::iterator Position;
+ mutable const JSONAtom *Current;
+ mutable bool Started;
+
+ const char StartChar;
+ const char EndChar;
+
+ friend class JSONParser;
+
+public:
+ /// \brief dyn_cast helpers
+ ///@{
+ static bool classof(const JSONAtom *Atom) {
+ switch (Atom->getKind()) {
+ case JK_Array:
+ case JK_Object:
+ return true;
+ case JK_KeyValuePair:
+ case JK_String:
+ return false;
+ }
+ llvm_unreachable("Invalid JSONAtom kind");
+ }
+ static bool classof(const JSONContainer *Container) { return true; }
+ ///@}
+};
+
+/// \brief A simple JSON array.
+class JSONArray : public JSONContainer {
+public:
+ typedef IteratorTemplate<JSONValue> const_iterator;
+
+ /// \brief Returns a lazy parsing iterator over the container.
+ ///
+ /// As the iterator drives the parse stream, begin() must only be called
+ /// once per container.
+ const_iterator begin() const { return const_iterator(atom_begin()); }
+ const_iterator end() const { return const_iterator(atom_end()); }
+
+private:
+ JSONArray(JSONParser *Parser)
+ : JSONContainer(Parser, '[', ']', JSONAtom::JK_Array) {}
+
+public:
+ /// \brief dyn_cast helpers
+ ///@{
+ static bool classof(const JSONAtom *Atom) {
+ return Atom->getKind() == JSONAtom::JK_Array;
+ }
+ static bool classof(const JSONArray *Array) { return true; }
+ ///@}
+
+ friend class JSONParser;
+};
+
+/// \brief A JSON object: an iterable list of JSON key-value pairs.
+class JSONObject : public JSONContainer {
+public:
+ typedef IteratorTemplate<JSONKeyValuePair> const_iterator;
+
+ /// \brief Returns a lazy parsing iterator over the container.
+ ///
+ /// As the iterator drives the parse stream, begin() must only be called
+ /// once per container.
+ const_iterator begin() const { return const_iterator(atom_begin()); }
+ const_iterator end() const { return const_iterator(atom_end()); }
+
+private:
+ JSONObject(JSONParser *Parser)
+ : JSONContainer(Parser, '{', '}', JSONAtom::JK_Object) {}
+
+public:
+ /// \brief dyn_cast helpers
+ ///@{
+ static bool classof(const JSONAtom *Atom) {
+ return Atom->getKind() == JSONAtom::JK_Object;
+ }
+ static bool classof(const JSONObject *Object) { return true; }
+ ///@}
+
+ friend class JSONParser;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_SUPPORT_JSON_PARSER_H
diff --git a/include/llvm/Support/LockFileManager.h b/include/llvm/Support/LockFileManager.h
new file mode 100644
index 0000000..e2fa8eb
--- /dev/null
+++ b/include/llvm/Support/LockFileManager.h
@@ -0,0 +1,74 @@
+//===--- LockFileManager.h - File-level locking utility ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_SUPPORT_LOCKFILEMANAGER_H
+#define LLVM_SUPPORT_LOCKFILEMANAGER_H
+
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/system_error.h"
+#include <utility> // for std::pair
+
+namespace llvm {
+
+/// \brief Class that manages the creation of a lock file to aid
+/// implicit coordination between different processes.
+///
+/// The implicit coordination works by creating a ".lock" file alongside
+/// the file that we're coordinating for, using the atomicity of the file
+/// system to ensure that only a single process can create that ".lock" file.
+/// When the lock file is removed, the owning process has finished the
+/// operation.
+class LockFileManager {
+public:
+ /// \brief Describes the state of a lock file.
+ enum LockFileState {
+ /// \brief The lock file has been created and is owned by this instance
+ /// of the object.
+ LFS_Owned,
+ /// \brief The lock file already exists and is owned by some other
+ /// instance.
+ LFS_Shared,
+ /// \brief An error occurred while trying to create or find the lock
+ /// file.
+ LFS_Error
+ };
+
+private:
+ SmallString<128> LockFileName;
+ SmallString<128> UniqueLockFileName;
+
+ Optional<std::pair<std::string, int> > Owner;
+ Optional<error_code> Error;
+
+ LockFileManager(const LockFileManager &);
+ LockFileManager &operator=(const LockFileManager &);
+
+ static Optional<std::pair<std::string, int> >
+ readLockFile(StringRef LockFileName);
+
+ static bool processStillExecuting(StringRef Hostname, int PID);
+
+public:
+
+ LockFileManager(StringRef FileName);
+ ~LockFileManager();
+
+ /// \brief Determine the state of the lock file.
+ LockFileState getState() const;
+
+ operator LockFileState() const { return getState(); }
+
+ /// \brief For a shared lock, wait until the owner releases the lock.
+ void waitForUnlock();
+};
+
+} // end namespace llvm
+
+#endif // LLVM_SUPPORT_LOCKFILEMANAGER_H
diff --git a/include/llvm/Support/MachO.h b/include/llvm/Support/MachO.h
index 5b68586..44a7a79 100644
--- a/include/llvm/Support/MachO.h
+++ b/include/llvm/Support/MachO.h
@@ -114,6 +114,10 @@ namespace llvm {
LoadCommandVersionMinIPhoneOS = 0x00000025u, // LC_VERSION_MIN_IPHONEOS
LoadCommandFunctionStarts = 0x00000026u, // LC_FUNCTION_STARTS
LoadCommandDyldEnvironment = 0x00000027u, // LC_DYLD_ENVIRONMENT
+ LoadCommandMain = 0x80000028u, // LC_MAIN
+ LoadCommandDataInCode = 0x00000029u, // LC_DATA_IN_CODE
+ LoadCommandSourceVersion = 0x0000002Au, // LC_SOURCE_VERSION
+ LoadCommandCodeSignDRs = 0x0000002Bu, // LC_DYLIB_CODE_SIGN_DRS
// Constant bits for the "flags" field in llvm::MachO::segment_command
SegmentCommandFlagBitHighVM = 0x1u, // SG_HIGHVM
@@ -240,6 +244,9 @@ namespace llvm {
NListSectionNoSection = 0u, // NO_SECT
NListSectionMaxSection = 0xffu, // MAX_SECT
+ NListDescWeakRef = 0x40u,
+ NListDescWeakDef = 0x80u,
+
// Constant values for the "n_type" field in llvm::MachO::nlist and
// llvm::MachO::nlist_64 when "(n_type & NlistMaskStab) != 0"
StabGlobalSymbol = 0x20u, // N_GSYM
diff --git a/include/llvm/Support/ManagedStatic.h b/include/llvm/Support/ManagedStatic.h
index 53e73ad..4171d1b 100644
--- a/include/llvm/Support/ManagedStatic.h
+++ b/include/llvm/Support/ManagedStatic.h
@@ -16,6 +16,7 @@
#include "llvm/Support/Atomic.h"
#include "llvm/Support/Threading.h"
+#include "llvm/Support/Valgrind.h"
namespace llvm {
@@ -65,6 +66,7 @@ public:
void* tmp = Ptr;
if (llvm_is_multithreaded()) sys::MemoryFence();
if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
+ TsanHappensAfter(this);
return *static_cast<C*>(Ptr);
}
@@ -72,6 +74,7 @@ public:
void* tmp = Ptr;
if (llvm_is_multithreaded()) sys::MemoryFence();
if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
+ TsanHappensAfter(this);
return static_cast<C*>(Ptr);
}
@@ -79,6 +82,7 @@ public:
void* tmp = Ptr;
if (llvm_is_multithreaded()) sys::MemoryFence();
if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
+ TsanHappensAfter(this);
return *static_cast<C*>(Ptr);
}
@@ -86,6 +90,7 @@ public:
void* tmp = Ptr;
if (llvm_is_multithreaded()) sys::MemoryFence();
if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
+ TsanHappensAfter(this);
return static_cast<C*>(Ptr);
}
diff --git a/include/llvm/Support/MathExtras.h b/include/llvm/Support/MathExtras.h
index 4627557..d085c94 100644
--- a/include/llvm/Support/MathExtras.h
+++ b/include/llvm/Support/MathExtras.h
@@ -51,6 +51,13 @@ inline bool isInt<32>(int64_t x) {
return static_cast<int32_t>(x) == x;
}
+/// isShiftedInt<N,S> - Checks if a signed integer is an N bit number shifted
+/// left by S.
+template<unsigned N, unsigned S>
+inline bool isShiftedInt(int64_t x) {
+ return isInt<N+S>(x) && (x % (1<<S) == 0);
+}
+
/// isUInt - Checks if an unsigned integer fits into the given bit width.
template<unsigned N>
inline bool isUInt(uint64_t x) {
@@ -70,6 +77,13 @@ inline bool isUInt<32>(uint64_t x) {
return static_cast<uint32_t>(x) == x;
}
+/// isShiftedUInt<N,S> - Checks if a unsigned integer is an N bit number shifted
+/// left by S.
+template<unsigned N, unsigned S>
+inline bool isShiftedUInt(uint64_t x) {
+ return isUInt<N+S>(x) && (x % (1<<S) == 0);
+}
+
/// isUIntN - Checks if an unsigned integer fits into the given (dynamic)
/// bit width.
inline bool isUIntN(unsigned N, uint64_t x) {
diff --git a/include/llvm/Support/MemoryObject.h b/include/llvm/Support/MemoryObject.h
index dec0f13..b778b08 100644
--- a/include/llvm/Support/MemoryObject.h
+++ b/include/llvm/Support/MemoryObject.h
@@ -23,19 +23,19 @@ class MemoryObject {
public:
/// Destructor - Override as necessary.
virtual ~MemoryObject();
-
+
/// getBase - Returns the lowest valid address in the region.
///
/// @result - The lowest valid address.
virtual uint64_t getBase() const = 0;
-
+
/// getExtent - Returns the size of the region in bytes. (The region is
- /// contiguous, so the highest valid address of the region
+ /// contiguous, so the highest valid address of the region
/// is getBase() + getExtent() - 1).
///
/// @result - The size of the region.
virtual uint64_t getExtent() const = 0;
-
+
/// readByte - Tries to read a single byte from the region.
///
/// @param address - The address of the byte, in the same space as getBase().
@@ -43,7 +43,7 @@ public:
/// @result - 0 if successful; -1 if not. Failure may be due to a
/// bounds violation or an implementation-specific error.
virtual int readByte(uint64_t address, uint8_t* ptr) const = 0;
-
+
/// readBytes - Tries to read a contiguous range of bytes from the
/// region, up to the end of the region.
/// You should override this function if there is a quicker
@@ -67,4 +67,3 @@ public:
}
#endif
-
diff --git a/include/llvm/Support/PathV1.h b/include/llvm/Support/PathV1.h
index 45165de..f4bedf9 100644
--- a/include/llvm/Support/PathV1.h
+++ b/include/llvm/Support/PathV1.h
@@ -131,20 +131,6 @@ namespace sys {
/// @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
diff --git a/include/llvm/Support/PatternMatch.h b/include/llvm/Support/PatternMatch.h
index f0fb516..221fa8b 100644
--- a/include/llvm/Support/PatternMatch.h
+++ b/include/llvm/Support/PatternMatch.h
@@ -31,6 +31,7 @@
#include "llvm/Constants.h"
#include "llvm/Instructions.h"
+#include "llvm/Operator.h"
namespace llvm {
namespace PatternMatch {
@@ -97,12 +98,19 @@ struct apint_match {
Res = &CI->getValue();
return true;
}
+ // FIXME: Remove this.
if (ConstantVector *CV = dyn_cast<ConstantVector>(V))
if (ConstantInt *CI =
dyn_cast_or_null<ConstantInt>(CV->getSplatValue())) {
Res = &CI->getValue();
return true;
}
+ if (ConstantDataVector *CV = dyn_cast<ConstantDataVector>(V))
+ if (ConstantInt *CI =
+ dyn_cast_or_null<ConstantInt>(CV->getSplatValue())) {
+ Res = &CI->getValue();
+ return true;
+ }
return false;
}
};
@@ -143,9 +151,13 @@ struct cst_pred_ty : public Predicate {
bool match(ITy *V) {
if (const ConstantInt *CI = dyn_cast<ConstantInt>(V))
return this->isValue(CI->getValue());
+ // FIXME: Remove this.
if (const ConstantVector *CV = dyn_cast<ConstantVector>(V))
if (ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CV->getSplatValue()))
return this->isValue(CI->getValue());
+ if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(V))
+ if (ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CV->getSplatValue()))
+ return this->isValue(CI->getValue());
return false;
}
};
@@ -163,12 +175,22 @@ struct api_pred_ty : public Predicate {
Res = &CI->getValue();
return true;
}
+
+ // FIXME: remove.
if (const ConstantVector *CV = dyn_cast<ConstantVector>(V))
if (ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CV->getSplatValue()))
if (this->isValue(CI->getValue())) {
Res = &CI->getValue();
return true;
}
+
+ if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(V))
+ if (ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CV->getSplatValue()))
+ if (this->isValue(CI->getValue())) {
+ Res = &CI->getValue();
+ return true;
+ }
+
return false;
}
};
@@ -441,6 +463,26 @@ m_IDiv(const LHS &L, const RHS &R) {
}
//===----------------------------------------------------------------------===//
+// Class that matches exact binary ops.
+//
+template<typename SubPattern_t>
+struct Exact_match {
+ SubPattern_t SubPattern;
+
+ Exact_match(const SubPattern_t &SP) : SubPattern(SP) {}
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ if (PossiblyExactOperator *PEO = dyn_cast<PossiblyExactOperator>(V))
+ return PEO->isExact() && SubPattern.match(V);
+ return false;
+ }
+};
+
+template<typename T>
+inline Exact_match<T> m_Exact(const T &SubPattern) { return SubPattern; }
+
+//===----------------------------------------------------------------------===//
// Matchers for CmpInst classes
//
@@ -529,10 +571,8 @@ struct CastClass_match {
template<typename OpTy>
bool match(OpTy *V) {
- if (CastInst *I = dyn_cast<CastInst>(V))
- return I->getOpcode() == Opcode && Op.match(I->getOperand(0));
- if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
- return CE->getOpcode() == Opcode && Op.match(CE->getOperand(0));
+ if (Operator *O = dyn_cast<Operator>(V))
+ return O->getOpcode() == Opcode && Op.match(O->getOperand(0));
return false;
}
};
@@ -585,21 +625,18 @@ struct not_match {
template<typename OpTy>
bool match(OpTy *V) {
- if (Instruction *I = dyn_cast<Instruction>(V))
- if (I->getOpcode() == Instruction::Xor)
- return matchIfNot(I->getOperand(0), I->getOperand(1));
- if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
- if (CE->getOpcode() == Instruction::Xor)
- return matchIfNot(CE->getOperand(0), CE->getOperand(1));
+ if (Operator *O = dyn_cast<Operator>(V))
+ if (O->getOpcode() == Instruction::Xor)
+ return matchIfNot(O->getOperand(0), O->getOperand(1));
return false;
}
private:
bool matchIfNot(Value *LHS, Value *RHS) {
- if (ConstantInt *CI = dyn_cast<ConstantInt>(RHS))
- return CI->isAllOnesValue() && L.match(LHS);
- if (ConstantVector *CV = dyn_cast<ConstantVector>(RHS))
- return CV->isAllOnesValue() && L.match(LHS);
- return false;
+ return (isa<ConstantInt>(RHS) || isa<ConstantDataVector>(RHS) ||
+ // FIXME: Remove CV.
+ isa<ConstantVector>(RHS)) &&
+ cast<Constant>(RHS)->isAllOnesValue() &&
+ L.match(LHS);
}
};
@@ -615,19 +652,16 @@ struct neg_match {
template<typename OpTy>
bool match(OpTy *V) {
- if (Instruction *I = dyn_cast<Instruction>(V))
- if (I->getOpcode() == Instruction::Sub)
- return matchIfNeg(I->getOperand(0), I->getOperand(1));
- if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
- if (CE->getOpcode() == Instruction::Sub)
- return matchIfNeg(CE->getOperand(0), CE->getOperand(1));
+ if (Operator *O = dyn_cast<Operator>(V))
+ if (O->getOpcode() == Instruction::Sub)
+ return matchIfNeg(O->getOperand(0), O->getOperand(1));
return false;
}
private:
bool matchIfNeg(Value *LHS, Value *RHS) {
- if (ConstantInt *C = dyn_cast<ConstantInt>(LHS))
- return C->isZero() && L.match(RHS);
- return false;
+ return ((isa<ConstantInt>(LHS) && cast<ConstantInt>(LHS)->isZero()) ||
+ isa<ConstantAggregateZero>(LHS)) &&
+ L.match(RHS);
}
};
@@ -644,12 +678,9 @@ struct fneg_match {
template<typename OpTy>
bool match(OpTy *V) {
- if (Instruction *I = dyn_cast<Instruction>(V))
- if (I->getOpcode() == Instruction::FSub)
- return matchIfFNeg(I->getOperand(0), I->getOperand(1));
- if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
- if (CE->getOpcode() == Instruction::FSub)
- return matchIfFNeg(CE->getOperand(0), CE->getOperand(1));
+ if (Operator *O = dyn_cast<Operator>(V))
+ if (O->getOpcode() == Instruction::FSub)
+ return matchIfFNeg(O->getOperand(0), O->getOperand(1));
return false;
}
private:
diff --git a/include/llvm/Support/Process.h b/include/llvm/Support/Process.h
index 27ef267..3379922 100644
--- a/include/llvm/Support/Process.h
+++ b/include/llvm/Support/Process.h
@@ -138,9 +138,6 @@ namespace sys {
/// Resets the terminals colors, or returns an escape sequence to do so.
static const char *ResetColor();
-
- /// Change the program working directory to that given by \arg Path.
- static void SetWorkingDirectory(std::string Path);
/// @}
};
}
diff --git a/include/llvm/Support/Program.h b/include/llvm/Support/Program.h
index a502657..a85f235 100644
--- a/include/llvm/Support/Program.h
+++ b/include/llvm/Support/Program.h
@@ -17,6 +17,7 @@
#include "llvm/Support/Path.h"
namespace llvm {
+class error_code;
namespace sys {
// TODO: Add operations to communicate with the process, redirect its I/O,
@@ -122,12 +123,12 @@ namespace sys {
/// @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();
+ // These methods change the specified standard stream (stdin, stdout, or
+ // stderr) to binary mode. They return errc::success if the specified stream
+ // was changed. Otherwise a platform dependent error is returned.
+ static error_code ChangeStdinToBinary();
+ static error_code ChangeStdoutToBinary();
+ static error_code ChangeStderrToBinary();
/// A convenience function equivalent to Program prg; prg.Execute(..);
/// prg.Wait(..);
diff --git a/include/llvm/Support/Recycler.h b/include/llvm/Support/Recycler.h
index d8f8c78..fa6e189 100644
--- a/include/llvm/Support/Recycler.h
+++ b/include/llvm/Support/Recycler.h
@@ -17,6 +17,7 @@
#include "llvm/ADT/ilist.h"
#include "llvm/Support/AlignOf.h"
+#include "llvm/Support/ErrorHandling.h"
#include <cassert>
namespace llvm {
@@ -52,7 +53,7 @@ struct ilist_traits<RecyclerStruct> :
static void noteHead(RecyclerStruct*, RecyclerStruct*) {}
static void deleteNode(RecyclerStruct *) {
- assert(0 && "Recycler's ilist_traits shouldn't see a deleteNode call!");
+ llvm_unreachable("Recycler's ilist_traits shouldn't see a deleteNode call!");
}
};
diff --git a/include/llvm/Support/SMLoc.h b/include/llvm/Support/SMLoc.h
index 02db327..d48bfcc 100644
--- a/include/llvm/Support/SMLoc.h
+++ b/include/llvm/Support/SMLoc.h
@@ -15,9 +15,11 @@
#ifndef SUPPORT_SMLOC_H
#define SUPPORT_SMLOC_H
+#include <cassert>
+
namespace llvm {
-// SMLoc - Represents a location in source code.
+/// SMLoc - Represents a location in source code.
class SMLoc {
const char *Ptr;
public:
@@ -38,7 +40,23 @@ public:
}
};
-}
+/// SMRange - Represents a range in source code. Note that unlike standard STL
+/// ranges, the locations specified are considered to be *inclusive*. For
+/// example, [X,X] *does* include X, it isn't an empty range.
+class SMRange {
+public:
+ SMLoc Start, End;
+
+ SMRange() {}
+ SMRange(SMLoc Start, SMLoc End) : Start(Start), End(End) {
+ assert(Start.isValid() == End.isValid() &&
+ "Start and end should either both be valid or both be invalid!");
+ }
+
+ bool isValid() const { return Start.isValid(); }
+};
+
+} // end namespace llvm
#endif
diff --git a/include/llvm/Support/SaveAndRestore.h b/include/llvm/Support/SaveAndRestore.h
new file mode 100644
index 0000000..ffa99b9
--- /dev/null
+++ b/include/llvm/Support/SaveAndRestore.h
@@ -0,0 +1,47 @@
+//===-- SaveAndRestore.h - Utility -------------------------------*- 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 utility classes that uses RAII to save and restore
+// values.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SAVERESTORE
+#define LLVM_ADT_SAVERESTORE
+
+namespace llvm {
+
+// SaveAndRestore - A utility class that uses RAII to save and restore
+// the value of a variable.
+template<typename T>
+struct SaveAndRestore {
+ SaveAndRestore(T& x) : X(x), old_value(x) {}
+ SaveAndRestore(T& x, const T &new_value) : X(x), old_value(x) {
+ X = new_value;
+ }
+ ~SaveAndRestore() { X = old_value; }
+ T get() { return old_value; }
+private:
+ T& X;
+ T old_value;
+};
+
+// SaveOr - Similar to SaveAndRestore. Operates only on bools; the old
+// value of a variable is saved, and during the dstor the old value is
+// or'ed with the new value.
+struct SaveOr {
+ SaveOr(bool& x) : X(x), old_value(x) { x = false; }
+ ~SaveOr() { X |= old_value; }
+private:
+ bool& X;
+ const bool old_value;
+};
+
+}
+#endif
diff --git a/include/llvm/Support/SourceMgr.h b/include/llvm/Support/SourceMgr.h
index deb8caf..58b8fab 100644
--- a/include/llvm/Support/SourceMgr.h
+++ b/include/llvm/Support/SourceMgr.h
@@ -17,10 +17,8 @@
#define SUPPORT_SOURCEMGR_H
#include "llvm/Support/SMLoc.h"
-
+#include "llvm/ADT/ArrayRef.h"
#include <string>
-#include <vector>
-#include <cassert>
namespace llvm {
class MemoryBuffer;
@@ -33,10 +31,16 @@ namespace llvm {
/// and handles diagnostic wrangling.
class SourceMgr {
public:
+ enum DiagKind {
+ DK_Error,
+ DK_Warning,
+ DK_Note
+ };
+
/// DiagHandlerTy - Clients that want to handle their own diagnostics in a
/// custom way can register a function pointer+context as a diagnostic
/// handler. It gets called each time PrintMessage is invoked.
- typedef void (*DiagHandlerTy)(const SMDiagnostic&, void *Context);
+ typedef void (*DiagHandlerTy)(const SMDiagnostic &, void *Context);
private:
struct SrcBuffer {
/// Buffer - The memory buffer for the file.
@@ -124,11 +128,8 @@ public:
/// PrintMessage - Emit a message about the specified location with the
/// specified string.
///
- /// @param Type - If non-null, the kind of message (e.g., "error") which is
- /// prefixed to the message.
- /// @param ShowLine - Should the diagnostic show the source line.
- void PrintMessage(SMLoc Loc, const Twine &Msg, const char *Type,
- bool ShowLine = true) const;
+ void PrintMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg,
+ ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) const;
/// GetMessage - Return an SMDiagnostic at the specified location with the
@@ -136,10 +137,8 @@ public:
///
/// @param Type - If non-null, the kind of message (e.g., "error") which is
/// prefixed to the message.
- /// @param ShowLine - Should the diagnostic show the source line.
- SMDiagnostic GetMessage(SMLoc Loc,
- const Twine &Msg, const char *Type,
- bool ShowLine = true) const;
+ SMDiagnostic GetMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg,
+ ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) const;
/// PrintIncludeStack - Prints the names of included files and the line of the
/// file they were included from. A diagnostic handler can use this before
@@ -158,35 +157,38 @@ class SMDiagnostic {
SMLoc Loc;
std::string Filename;
int LineNo, ColumnNo;
+ SourceMgr::DiagKind Kind;
std::string Message, LineContents;
- unsigned ShowLine : 1;
+ std::vector<std::pair<unsigned, unsigned> > Ranges;
public:
// Null diagnostic.
- SMDiagnostic() : SM(0), LineNo(0), ColumnNo(0), ShowLine(0) {}
+ SMDiagnostic()
+ : SM(0), LineNo(0), ColumnNo(0), Kind(SourceMgr::DK_Error) {}
// Diagnostic with no location (e.g. file not found, command line arg error).
- SMDiagnostic(const std::string &filename, const std::string &Msg)
- : SM(0), Filename(filename), LineNo(-1), ColumnNo(-1),
- Message(Msg), ShowLine(false) {}
+ SMDiagnostic(const std::string &filename, SourceMgr::DiagKind Kind,
+ const std::string &Msg)
+ : SM(0), Filename(filename), LineNo(-1), ColumnNo(-1), Kind(Kind),
+ Message(Msg) {}
// Diagnostic with a location.
SMDiagnostic(const SourceMgr &sm, SMLoc L, const std::string &FN,
- int Line, int Col,
+ int Line, int Col, SourceMgr::DiagKind Kind,
const std::string &Msg, const std::string &LineStr,
- bool showline = true)
- : SM(&sm), Loc(L), Filename(FN), LineNo(Line), ColumnNo(Col), Message(Msg),
- LineContents(LineStr), ShowLine(showline) {}
+ ArrayRef<std::pair<unsigned,unsigned> > Ranges);
const SourceMgr *getSourceMgr() const { return SM; }
SMLoc getLoc() const { return Loc; }
const std::string &getFilename() const { return Filename; }
int getLineNo() const { return LineNo; }
int getColumnNo() const { return ColumnNo; }
+ SourceMgr::DiagKind getKind() const { return Kind; }
const std::string &getMessage() const { return Message; }
const std::string &getLineContents() const { return LineContents; }
- bool getShowLine() const { return ShowLine; }
-
- void Print(const char *ProgName, raw_ostream &S) const;
+ const std::vector<std::pair<unsigned, unsigned> > &getRanges() const {
+ return Ranges;
+ }
+ void print(const char *ProgName, raw_ostream &S) const;
};
} // end llvm namespace
diff --git a/include/llvm/Support/StreamableMemoryObject.h b/include/llvm/Support/StreamableMemoryObject.h
new file mode 100644
index 0000000..531dbb2
--- /dev/null
+++ b/include/llvm/Support/StreamableMemoryObject.h
@@ -0,0 +1,181 @@
+//===- StreamableMemoryObject.h - Streamable data interface -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef STREAMABLEMEMORYOBJECT_H_
+#define STREAMABLEMEMORYOBJECT_H_
+
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/Support/MemoryObject.h"
+#include "llvm/Support/DataStream.h"
+#include <vector>
+
+namespace llvm {
+
+/// StreamableMemoryObject - Interface to data which might be streamed.
+/// Streamability has 2 important implications/restrictions. First, the data
+/// might not yet exist in memory when the request is made. This just means
+/// that readByte/readBytes might have to block or do some work to get it.
+/// More significantly, the exact size of the object might not be known until
+/// it has all been fetched. This means that to return the right result,
+/// getExtent must also wait for all the data to arrive; therefore it should
+/// not be called on objects which are actually streamed (this would defeat
+/// the purpose of streaming). Instead, isValidAddress and isObjectEnd can be
+/// used to test addresses without knowing the exact size of the stream.
+/// Finally, getPointer can be used instead of readBytes to avoid extra copying.
+class StreamableMemoryObject : public MemoryObject {
+ public:
+ /// Destructor - Override as necessary.
+ virtual ~StreamableMemoryObject();
+
+ /// getBase - Returns the lowest valid address in the region.
+ ///
+ /// @result - The lowest valid address.
+ virtual uint64_t getBase() const = 0;
+
+ /// getExtent - Returns the size of the region in bytes. (The region is
+ /// contiguous, so the highest valid address of the region
+ /// is getBase() + getExtent() - 1).
+ /// May block until all bytes in the stream have been read
+ ///
+ /// @result - The size of the region.
+ virtual uint64_t getExtent() const = 0;
+
+ /// readByte - Tries to read a single byte from the region.
+ /// May block until (address - base) bytes have been read
+ /// @param address - The address of the byte, in the same space as getBase().
+ /// @param ptr - A pointer to a byte to be filled in. Must be non-NULL.
+ /// @result - 0 if successful; -1 if not. Failure may be due to a
+ /// bounds violation or an implementation-specific error.
+ virtual int readByte(uint64_t address, uint8_t* ptr) const = 0;
+
+ /// readBytes - Tries to read a contiguous range of bytes from the
+ /// region, up to the end of the region.
+ /// May block until (address - base + size) bytes have
+ /// been read. Additionally, StreamableMemoryObjects will
+ /// not do partial reads - if size bytes cannot be read,
+ /// readBytes will fail.
+ ///
+ /// @param address - The address of the first byte, in the same space as
+ /// getBase().
+ /// @param size - The maximum number of bytes to copy.
+ /// @param buf - A pointer to a buffer to be filled in. Must be non-NULL
+ /// and large enough to hold size bytes.
+ /// @param copied - A pointer to a nunber that is filled in with the number
+ /// of bytes actually read. May be NULL.
+ /// @result - 0 if successful; -1 if not. Failure may be due to a
+ /// bounds violation or an implementation-specific error.
+ virtual int readBytes(uint64_t address,
+ uint64_t size,
+ uint8_t* buf,
+ uint64_t* copied) const = 0;
+
+ /// getPointer - Ensures that the requested data is in memory, and returns
+ /// A pointer to it. More efficient than using readBytes if the
+ /// data is already in memory.
+ /// May block until (address - base + size) bytes have been read
+ /// @param address - address of the byte, in the same space as getBase()
+ /// @param size - amount of data that must be available on return
+ /// @result - valid pointer to the requested data
+ virtual const uint8_t *getPointer(uint64_t address, uint64_t size) const = 0;
+
+ /// isValidAddress - Returns true if the address is within the object
+ /// (i.e. between base and base + extent - 1 inclusive)
+ /// May block until (address - base) bytes have been read
+ /// @param address - address of the byte, in the same space as getBase()
+ /// @result - true if the address may be read with readByte()
+ virtual bool isValidAddress(uint64_t address) const = 0;
+
+ /// isObjectEnd - Returns true if the address is one past the end of the
+ /// object (i.e. if it is equal to base + extent)
+ /// May block until (address - base) bytes have been read
+ /// @param address - address of the byte, in the same space as getBase()
+ /// @result - true if the address is equal to base + extent
+ virtual bool isObjectEnd(uint64_t address) const = 0;
+};
+
+/// StreamingMemoryObject - interface to data which is actually streamed from
+/// a DataStreamer. In addition to inherited members, it has the
+/// dropLeadingBytes and setKnownObjectSize methods which are not applicable
+/// to non-streamed objects.
+class StreamingMemoryObject : public StreamableMemoryObject {
+public:
+ StreamingMemoryObject(DataStreamer *streamer);
+ virtual uint64_t getBase() const { return 0; }
+ virtual uint64_t getExtent() const;
+ virtual int readByte(uint64_t address, uint8_t* ptr) const;
+ virtual int readBytes(uint64_t address,
+ uint64_t size,
+ uint8_t* buf,
+ uint64_t* copied) const ;
+ virtual const uint8_t *getPointer(uint64_t address, uint64_t size) const {
+ // This could be fixed by ensuring the bytes are fetched and making a copy,
+ // requiring that the bitcode size be known, or otherwise ensuring that
+ // the memory doesn't go away/get reallocated, but it's
+ // not currently necessary. Users that need the pointer don't stream.
+ assert(0 && "getPointer in streaming memory objects not allowed");
+ return NULL;
+ }
+ virtual bool isValidAddress(uint64_t address) const;
+ virtual bool isObjectEnd(uint64_t address) const;
+
+ /// Drop s bytes from the front of the stream, pushing the positions of the
+ /// remaining bytes down by s. This is used to skip past the bitcode header,
+ /// since we don't know a priori if it's present, and we can't put bytes
+ /// back into the stream once we've read them.
+ bool dropLeadingBytes(size_t s);
+
+ /// If the data object size is known in advance, many of the operations can
+ /// be made more efficient, so this method should be called before reading
+ /// starts (although it can be called anytime).
+ void setKnownObjectSize(size_t size);
+
+private:
+ const static uint32_t kChunkSize = 4096 * 4;
+ mutable std::vector<unsigned char> Bytes;
+ OwningPtr<DataStreamer> Streamer;
+ mutable size_t BytesRead; // Bytes read from stream
+ size_t BytesSkipped;// Bytes skipped at start of stream (e.g. wrapper/header)
+ mutable size_t ObjectSize; // 0 if unknown, set if wrapper seen or EOF reached
+ mutable bool EOFReached;
+
+ // Fetch enough bytes such that Pos can be read or EOF is reached
+ // (i.e. BytesRead > Pos). Return true if Pos can be read.
+ // Unlike most of the functions in BitcodeReader, returns true on success.
+ // Most of the requests will be small, but we fetch at kChunkSize bytes
+ // at a time to avoid making too many potentially expensive GetBytes calls
+ bool fetchToPos(size_t Pos) const {
+ if (EOFReached) return Pos < ObjectSize;
+ while (Pos >= BytesRead) {
+ Bytes.resize(BytesRead + BytesSkipped + kChunkSize);
+ size_t bytes = Streamer->GetBytes(&Bytes[BytesRead + BytesSkipped],
+ kChunkSize);
+ BytesRead += bytes;
+ if (bytes < kChunkSize) {
+ if (ObjectSize && BytesRead < Pos)
+ assert(0 && "Unexpected short read fetching bitcode");
+ if (BytesRead <= Pos) { // reached EOF/ran out of bytes
+ ObjectSize = BytesRead;
+ EOFReached = true;
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ StreamingMemoryObject(const StreamingMemoryObject&); // DO NOT IMPLEMENT
+ void operator=(const StreamingMemoryObject&); // DO NOT IMPLEMENT
+};
+
+StreamableMemoryObject *getNonStreamedMemoryObject(
+ const unsigned char *Start, const unsigned char *End);
+
+}
+#endif // STREAMABLEMEMORYOBJECT_H_
diff --git a/include/llvm/Support/TargetRegistry.h b/include/llvm/Support/TargetRegistry.h
index 45f249d..8808130 100644
--- a/include/llvm/Support/TargetRegistry.h
+++ b/include/llvm/Support/TargetRegistry.h
@@ -44,12 +44,14 @@ namespace llvm {
class MCTargetAsmLexer;
class MCTargetAsmParser;
class TargetMachine;
+ class TargetOptions;
class raw_ostream;
class formatted_raw_ostream;
MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
bool isVerboseAsm,
bool useLoc, bool useCFI,
+ bool useDwarfDirectory,
MCInstPrinter *InstPrint,
MCCodeEmitter *CE,
MCAsmBackend *TAB,
@@ -73,7 +75,8 @@ namespace llvm {
StringRef TT);
typedef MCCodeGenInfo *(*MCCodeGenInfoCtorFnTy)(StringRef TT,
Reloc::Model RM,
- CodeModel::Model CM);
+ CodeModel::Model CM,
+ CodeGenOpt::Level OL);
typedef MCInstrInfo *(*MCInstrInfoCtorFnTy)(void);
typedef MCInstrAnalysis *(*MCInstrAnalysisCtorFnTy)(const MCInstrInfo*Info);
typedef MCRegisterInfo *(*MCRegInfoCtorFnTy)(StringRef TT);
@@ -84,8 +87,10 @@ namespace llvm {
StringRef TT,
StringRef CPU,
StringRef Features,
+ const TargetOptions &Options,
Reloc::Model RM,
- CodeModel::Model CM);
+ CodeModel::Model CM,
+ CodeGenOpt::Level OL);
typedef AsmPrinter *(*AsmPrinterCtorTy)(TargetMachine &TM,
MCStreamer &Streamer);
typedef MCAsmBackend *(*MCAsmBackendCtorTy)(const Target &T, StringRef TT);
@@ -99,6 +104,8 @@ namespace llvm {
typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Target &T,
unsigned SyntaxVariant,
const MCAsmInfo &MAI,
+ const MCInstrInfo &MII,
+ const MCRegisterInfo &MRI,
const MCSubtargetInfo &STI);
typedef MCCodeEmitter *(*MCCodeEmitterCtorTy)(const MCInstrInfo &II,
const MCSubtargetInfo &STI,
@@ -116,6 +123,7 @@ namespace llvm {
bool isVerboseAsm,
bool useLoc,
bool useCFI,
+ bool useDwarfDirectory,
MCInstPrinter *InstPrint,
MCCodeEmitter *CE,
MCAsmBackend *TAB,
@@ -143,8 +151,8 @@ namespace llvm {
/// registered.
MCAsmInfoCtorFnTy MCAsmInfoCtorFn;
- /// MCCodeGenInfoCtorFn - Constructor function for this target's MCCodeGenInfo,
- /// if registered.
+ /// MCCodeGenInfoCtorFn - Constructor function for this target's
+ /// MCCodeGenInfo, if registered.
MCCodeGenInfoCtorFnTy MCCodeGenInfoCtorFn;
/// MCInstrInfoCtorFn - Constructor function for this target's MCInstrInfo,
@@ -275,10 +283,11 @@ namespace llvm {
/// createMCCodeGenInfo - Create a MCCodeGenInfo implementation.
///
MCCodeGenInfo *createMCCodeGenInfo(StringRef Triple, Reloc::Model RM,
- CodeModel::Model CM) const {
+ CodeModel::Model CM,
+ CodeGenOpt::Level OL) const {
if (!MCCodeGenInfoCtorFn)
return 0;
- return MCCodeGenInfoCtorFn(Triple, RM, CM);
+ return MCCodeGenInfoCtorFn(Triple, RM, CM, OL);
}
/// createMCInstrInfo - Create a MCInstrInfo implementation.
@@ -329,12 +338,14 @@ namespace llvm {
/// either the target triple from the module, or the target triple of the
/// host if that does not exist.
TargetMachine *createTargetMachine(StringRef Triple, StringRef CPU,
- StringRef Features,
- Reloc::Model RM = Reloc::Default,
- CodeModel::Model CM = CodeModel::Default) const {
+ StringRef Features, const TargetOptions &Options,
+ Reloc::Model RM = Reloc::Default,
+ CodeModel::Model CM = CodeModel::Default,
+ CodeGenOpt::Level OL = CodeGenOpt::Default) const {
if (!TargetMachineCtorFn)
return 0;
- return TargetMachineCtorFn(*this, Triple, CPU, Features, RM, CM);
+ return TargetMachineCtorFn(*this, Triple, CPU, Features, Options,
+ RM, CM, OL);
}
/// createMCAsmBackend - Create a target specific assembly parser.
@@ -383,10 +394,12 @@ namespace llvm {
MCInstPrinter *createMCInstPrinter(unsigned SyntaxVariant,
const MCAsmInfo &MAI,
+ const MCInstrInfo &MII,
+ const MCRegisterInfo &MRI,
const MCSubtargetInfo &STI) const {
if (!MCInstPrinterCtorFn)
return 0;
- return MCInstPrinterCtorFn(*this, SyntaxVariant, MAI, STI);
+ return MCInstPrinterCtorFn(*this, SyntaxVariant, MAI, MII, MRI, STI);
}
@@ -426,13 +439,14 @@ namespace llvm {
bool isVerboseAsm,
bool useLoc,
bool useCFI,
+ bool useDwarfDirectory,
MCInstPrinter *InstPrint,
MCCodeEmitter *CE,
MCAsmBackend *TAB,
bool ShowInst) const {
// AsmStreamerCtorFn is default to llvm::createAsmStreamer
return AsmStreamerCtorFn(Ctx, OS, isVerboseAsm, useLoc, useCFI,
- InstPrint, CE, TAB, ShowInst);
+ useDwarfDirectory, InstPrint, CE, TAB, ShowInst);
}
/// @}
@@ -776,7 +790,7 @@ namespace llvm {
/// extern "C" void LLVMInitializeFooTargetInfo() {
/// RegisterTarget<Triple::foo> X(TheFooTarget, "foo", "Foo description");
/// }
- template<Triple::ArchType TargetArchType = Triple::InvalidArch,
+ template<Triple::ArchType TargetArchType = Triple::UnknownArch,
bool HasJIT = false>
struct RegisterTarget {
RegisterTarget(Target &T, const char *Name, const char *Desc) {
@@ -840,8 +854,8 @@ namespace llvm {
TargetRegistry::RegisterMCCodeGenInfo(T, &Allocator);
}
private:
- static MCCodeGenInfo *Allocator(StringRef TT,
- Reloc::Model RM, CodeModel::Model CM) {
+ static MCCodeGenInfo *Allocator(StringRef TT, Reloc::Model RM,
+ CodeModel::Model CM, CodeGenOpt::Level OL) {
return new MCCodeGenInfoImpl();
}
};
@@ -1010,9 +1024,11 @@ namespace llvm {
private:
static TargetMachine *Allocator(const Target &T, StringRef TT,
StringRef CPU, StringRef FS,
+ const TargetOptions &Options,
Reloc::Model RM,
- CodeModel::Model CM) {
- return new TargetMachineImpl(T, TT, CPU, FS, RM, CM);
+ CodeModel::Model CM,
+ CodeGenOpt::Level OL) {
+ return new TargetMachineImpl(T, TT, CPU, FS, Options, RM, CM, OL);
}
};
diff --git a/include/llvm/Support/TargetSelect.h b/include/llvm/Support/TargetSelect.h
index 83ff68c..a86e953 100644
--- a/include/llvm/Support/TargetSelect.h
+++ b/include/llvm/Support/TargetSelect.h
@@ -149,6 +149,18 @@ namespace llvm {
#endif
}
+ /// InitializeNativeTargetDisassembler - The main program should call
+ /// this function to initialize the native target disassembler.
+ inline bool InitializeNativeTargetDisassembler() {
+ // If we have a native target, initialize the corresponding disassembler.
+#ifdef LLVM_NATIVE_DISASSEMBLER
+ LLVM_NATIVE_DISASSEMBLER();
+ return false;
+#else
+ return true;
+#endif
+ }
+
}
#endif
diff --git a/include/llvm/Support/Valgrind.h b/include/llvm/Support/Valgrind.h
index 7662eaa..e147647 100644
--- a/include/llvm/Support/Valgrind.h
+++ b/include/llvm/Support/Valgrind.h
@@ -16,8 +16,23 @@
#ifndef LLVM_SYSTEM_VALGRIND_H
#define LLVM_SYSTEM_VALGRIND_H
+#include "llvm/Support/Compiler.h"
+#include "llvm/Config/llvm-config.h"
#include <stddef.h>
+#if LLVM_ENABLE_THREADS != 0 && !defined(NDEBUG)
+// tsan (Thread Sanitizer) is a valgrind-based tool that detects these exact
+// functions by name.
+extern "C" {
+LLVM_ATTRIBUTE_WEAK void AnnotateHappensAfter(const char *file, int line,
+ const volatile void *cv);
+LLVM_ATTRIBUTE_WEAK void AnnotateHappensBefore(const char *file, int line,
+ const volatile void *cv);
+LLVM_ATTRIBUTE_WEAK void AnnotateIgnoreWritesBegin(const char *file, int line);
+LLVM_ATTRIBUTE_WEAK void AnnotateIgnoreWritesEnd(const char *file, int line);
+}
+#endif
+
namespace llvm {
namespace sys {
// True if Valgrind is controlling this process.
@@ -26,6 +41,34 @@ namespace sys {
// 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);
+
+#if LLVM_ENABLE_THREADS != 0 && !defined(NDEBUG)
+ // Thread Sanitizer is a valgrind tool that finds races in code.
+ // See http://code.google.com/p/data-race-test/wiki/DynamicAnnotations .
+
+ // This marker is used to define a happens-before arc. The race detector will
+ // infer an arc from the begin to the end when they share the same pointer
+ // argument.
+ #define TsanHappensBefore(cv) \
+ AnnotateHappensBefore(__FILE__, __LINE__, cv)
+
+ // This marker defines the destination of a happens-before arc.
+ #define TsanHappensAfter(cv) \
+ AnnotateHappensAfter(__FILE__, __LINE__, cv)
+
+ // Ignore any races on writes between here and the next TsanIgnoreWritesEnd.
+ #define TsanIgnoreWritesBegin() \
+ AnnotateIgnoreWritesBegin(__FILE__, __LINE__)
+
+ // Resume checking for racy writes.
+ #define TsanIgnoreWritesEnd() \
+ AnnotateIgnoreWritesEnd(__FILE__, __LINE__)
+#else
+ #define TsanHappensBefore(cv)
+ #define TsanHappensAfter(cv)
+ #define TsanIgnoreWritesBegin()
+ #define TsanIgnoreWritesEnd()
+#endif
}
}
diff --git a/include/llvm/Support/ValueHandle.h b/include/llvm/Support/ValueHandle.h
index c0cdc35..b7210b2 100644
--- a/include/llvm/Support/ValueHandle.h
+++ b/include/llvm/Support/ValueHandle.h
@@ -49,52 +49,61 @@ protected:
Tracking,
Weak
};
-private:
+private:
PointerIntPair<ValueHandleBase**, 2, HandleBaseKind> PrevPair;
ValueHandleBase *Next;
- Value *VP;
+
+ // A subclass may want to store some information along with the value
+ // pointer. Allow them to do this by making the value pointer a pointer-int
+ // pair. The 'setValPtrInt' and 'getValPtrInt' methods below give them this
+ // access.
+ PointerIntPair<Value*, 2> VP;
explicit ValueHandleBase(const ValueHandleBase&); // DO NOT IMPLEMENT.
public:
explicit ValueHandleBase(HandleBaseKind Kind)
- : PrevPair(0, Kind), Next(0), VP(0) {}
+ : PrevPair(0, Kind), Next(0), VP(0, 0) {}
ValueHandleBase(HandleBaseKind Kind, Value *V)
- : PrevPair(0, Kind), Next(0), VP(V) {
- if (isValid(VP))
+ : PrevPair(0, Kind), Next(0), VP(V, 0) {
+ if (isValid(VP.getPointer()))
AddToUseList();
}
ValueHandleBase(HandleBaseKind Kind, const ValueHandleBase &RHS)
: PrevPair(0, Kind), Next(0), VP(RHS.VP) {
- if (isValid(VP))
+ if (isValid(VP.getPointer()))
AddToExistingUseList(RHS.getPrevPtr());
}
~ValueHandleBase() {
- if (isValid(VP))
+ if (isValid(VP.getPointer()))
RemoveFromUseList();
}
Value *operator=(Value *RHS) {
- if (VP == RHS) return RHS;
- if (isValid(VP)) RemoveFromUseList();
- VP = RHS;
- if (isValid(VP)) AddToUseList();
+ if (VP.getPointer() == RHS) return RHS;
+ if (isValid(VP.getPointer())) RemoveFromUseList();
+ VP.setPointer(RHS);
+ if (isValid(VP.getPointer())) AddToUseList();
return RHS;
}
Value *operator=(const ValueHandleBase &RHS) {
- if (VP == RHS.VP) return RHS.VP;
- if (isValid(VP)) RemoveFromUseList();
- VP = RHS.VP;
- if (isValid(VP)) AddToExistingUseList(RHS.getPrevPtr());
- return VP;
+ if (VP.getPointer() == RHS.VP.getPointer()) return RHS.VP.getPointer();
+ if (isValid(VP.getPointer())) RemoveFromUseList();
+ VP.setPointer(RHS.VP.getPointer());
+ if (isValid(VP.getPointer())) AddToExistingUseList(RHS.getPrevPtr());
+ return VP.getPointer();
}
Value *operator->() const { return getValPtr(); }
Value &operator*() const { return *getValPtr(); }
protected:
- Value *getValPtr() const { return VP; }
+ Value *getValPtr() const { return VP.getPointer(); }
+
+ void setValPtrInt(unsigned K) { VP.setInt(K); }
+ unsigned getValPtrInt() const { return VP.getInt(); }
+
static bool isValid(Value *V) {
return V &&
V != DenseMapInfo<Value *>::getEmptyKey() &&
diff --git a/include/llvm/Support/YAMLParser.h b/include/llvm/Support/YAMLParser.h
new file mode 100644
index 0000000..b24cacd
--- /dev/null
+++ b/include/llvm/Support/YAMLParser.h
@@ -0,0 +1,549 @@
+//===--- YAMLParser.h - Simple YAML parser --------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is a YAML 1.2 parser.
+//
+// See http://www.yaml.org/spec/1.2/spec.html for the full standard.
+//
+// This currently does not implement the following:
+// * Multi-line literal folding.
+// * Tag resolution.
+// * UTF-16.
+// * BOMs anywhere other than the first Unicode scalar value in the file.
+//
+// The most important class here is Stream. This represents a YAML stream with
+// 0, 1, or many documents.
+//
+// SourceMgr sm;
+// StringRef input = getInput();
+// yaml::Stream stream(input, sm);
+//
+// for (yaml::document_iterator di = stream.begin(), de = stream.end();
+// di != de; ++di) {
+// yaml::Node *n = di->getRoot();
+// if (n) {
+// // Do something with n...
+// } else
+// break;
+// }
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_YAML_PARSER_H
+#define LLVM_SUPPORT_YAML_PARSER_H
+
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/SMLoc.h"
+
+#include <limits>
+#include <utility>
+
+namespace llvm {
+class MemoryBuffer;
+class SourceMgr;
+class raw_ostream;
+class Twine;
+
+namespace yaml {
+
+class document_iterator;
+class Document;
+class Node;
+class Scanner;
+struct Token;
+
+/// @brief Dump all the tokens in this stream to OS.
+/// @returns true if there was an error, false otherwise.
+bool dumpTokens(StringRef Input, raw_ostream &);
+
+/// @brief Scans all tokens in input without outputting anything. This is used
+/// for benchmarking the tokenizer.
+/// @returns true if there was an error, false otherwise.
+bool scanTokens(StringRef Input);
+
+/// @brief Escape \a Input for a double quoted scalar.
+std::string escape(StringRef Input);
+
+/// @brief This class represents a YAML stream potentially containing multiple
+/// documents.
+class Stream {
+public:
+ Stream(StringRef Input, SourceMgr &);
+ ~Stream();
+
+ document_iterator begin();
+ document_iterator end();
+ void skip();
+ bool failed();
+ bool validate() {
+ skip();
+ return !failed();
+ }
+
+ void printError(Node *N, const Twine &Msg);
+
+private:
+ OwningPtr<Scanner> scanner;
+ OwningPtr<Document> CurrentDoc;
+
+ friend class Document;
+
+ /// @brief Validate a %YAML x.x directive.
+ void handleYAMLDirective(const Token &);
+};
+
+/// @brief Abstract base class for all Nodes.
+class Node {
+public:
+ enum NodeKind {
+ NK_Null,
+ NK_Scalar,
+ NK_KeyValue,
+ NK_Mapping,
+ NK_Sequence,
+ NK_Alias
+ };
+
+ Node(unsigned int Type, OwningPtr<Document>&, StringRef Anchor);
+
+ /// @brief Get the value of the anchor attached to this node. If it does not
+ /// have one, getAnchor().size() will be 0.
+ StringRef getAnchor() const { return Anchor; }
+
+ SMRange getSourceRange() const { return SourceRange; }
+ void setSourceRange(SMRange SR) { SourceRange = SR; }
+
+ // These functions forward to Document and Scanner.
+ Token &peekNext();
+ Token getNext();
+ Node *parseBlockNode();
+ BumpPtrAllocator &getAllocator();
+ void setError(const Twine &Message, Token &Location) const;
+ bool failed() const;
+
+ virtual void skip() {};
+
+ unsigned int getType() const { return TypeID; }
+ static inline bool classof(const Node *) { return true; }
+
+ void *operator new ( size_t Size
+ , BumpPtrAllocator &Alloc
+ , size_t Alignment = 16) throw() {
+ return Alloc.Allocate(Size, Alignment);
+ }
+
+ void operator delete(void *Ptr, BumpPtrAllocator &Alloc, size_t) throw() {
+ Alloc.Deallocate(Ptr);
+ }
+
+protected:
+ OwningPtr<Document> &Doc;
+ SMRange SourceRange;
+
+ void operator delete(void *) throw() {}
+
+ virtual ~Node() {}
+
+private:
+ unsigned int TypeID;
+ StringRef Anchor;
+};
+
+/// @brief A null value.
+///
+/// Example:
+/// !!null null
+class NullNode : public Node {
+public:
+ NullNode(OwningPtr<Document> &D) : Node(NK_Null, D, StringRef()) {}
+
+ static inline bool classof(const NullNode *) { return true; }
+ static inline bool classof(const Node *N) {
+ return N->getType() == NK_Null;
+ }
+};
+
+/// @brief A scalar node is an opaque datum that can be presented as a
+/// series of zero or more Unicode scalar values.
+///
+/// Example:
+/// Adena
+class ScalarNode : public Node {
+public:
+ ScalarNode(OwningPtr<Document> &D, StringRef Anchor, StringRef Val)
+ : Node(NK_Scalar, D, Anchor)
+ , Value(Val) {
+ SMLoc Start = SMLoc::getFromPointer(Val.begin());
+ SMLoc End = SMLoc::getFromPointer(Val.end() - 1);
+ SourceRange = SMRange(Start, End);
+ }
+
+ // Return Value without any escaping or folding or other fun YAML stuff. This
+ // is the exact bytes that are contained in the file (after conversion to
+ // utf8).
+ StringRef getRawValue() const { return Value; }
+
+ /// @brief Gets the value of this node as a StringRef.
+ ///
+ /// @param Storage is used to store the content of the returned StringRef iff
+ /// it requires any modification from how it appeared in the source.
+ /// This happens with escaped characters and multi-line literals.
+ StringRef getValue(SmallVectorImpl<char> &Storage) const;
+
+ static inline bool classof(const ScalarNode *) { return true; }
+ static inline bool classof(const Node *N) {
+ return N->getType() == NK_Scalar;
+ }
+
+private:
+ StringRef Value;
+
+ StringRef unescapeDoubleQuoted( StringRef UnquotedValue
+ , StringRef::size_type Start
+ , SmallVectorImpl<char> &Storage) const;
+};
+
+/// @brief A key and value pair. While not technically a Node under the YAML
+/// representation graph, it is easier to treat them this way.
+///
+/// TODO: Consider making this not a child of Node.
+///
+/// Example:
+/// Section: .text
+class KeyValueNode : public Node {
+public:
+ KeyValueNode(OwningPtr<Document> &D)
+ : Node(NK_KeyValue, D, StringRef())
+ , Key(0)
+ , Value(0)
+ {}
+
+ /// @brief Parse and return the key.
+ ///
+ /// This may be called multiple times.
+ ///
+ /// @returns The key, or nullptr if failed() == true.
+ Node *getKey();
+
+ /// @brief Parse and return the value.
+ ///
+ /// This may be called multiple times.
+ ///
+ /// @returns The value, or nullptr if failed() == true.
+ Node *getValue();
+
+ virtual void skip() {
+ getKey()->skip();
+ getValue()->skip();
+ }
+
+ static inline bool classof(const KeyValueNode *) { return true; }
+ static inline bool classof(const Node *N) {
+ return N->getType() == NK_KeyValue;
+ }
+
+private:
+ Node *Key;
+ Node *Value;
+};
+
+/// @brief This is an iterator abstraction over YAML collections shared by both
+/// sequences and maps.
+///
+/// BaseT must have a ValueT* member named CurrentEntry and a member function
+/// increment() which must set CurrentEntry to 0 to create an end iterator.
+template <class BaseT, class ValueT>
+class basic_collection_iterator
+ : public std::iterator<std::forward_iterator_tag, ValueT> {
+public:
+ basic_collection_iterator() : Base(0) {}
+ basic_collection_iterator(BaseT *B) : Base(B) {}
+
+ ValueT *operator ->() const {
+ assert(Base && Base->CurrentEntry && "Attempted to access end iterator!");
+ return Base->CurrentEntry;
+ }
+
+ ValueT &operator *() const {
+ assert(Base && Base->CurrentEntry &&
+ "Attempted to dereference end iterator!");
+ return *Base->CurrentEntry;
+ }
+
+ operator ValueT*() const {
+ assert(Base && Base->CurrentEntry && "Attempted to access end iterator!");
+ return Base->CurrentEntry;
+ }
+
+ bool operator !=(const basic_collection_iterator &Other) const {
+ if(Base != Other.Base)
+ return true;
+ return (Base && Other.Base) && Base->CurrentEntry
+ != Other.Base->CurrentEntry;
+ }
+
+ basic_collection_iterator &operator++() {
+ assert(Base && "Attempted to advance iterator past end!");
+ Base->increment();
+ // Create an end iterator.
+ if (Base->CurrentEntry == 0)
+ Base = 0;
+ return *this;
+ }
+
+private:
+ BaseT *Base;
+};
+
+// The following two templates are used for both MappingNode and Sequence Node.
+template <class CollectionType>
+typename CollectionType::iterator begin(CollectionType &C) {
+ assert(C.IsAtBeginning && "You may only iterate over a collection once!");
+ C.IsAtBeginning = false;
+ typename CollectionType::iterator ret(&C);
+ ++ret;
+ return ret;
+}
+
+template <class CollectionType>
+void skip(CollectionType &C) {
+ // TODO: support skipping from the middle of a parsed collection ;/
+ assert((C.IsAtBeginning || C.IsAtEnd) && "Cannot skip mid parse!");
+ if (C.IsAtBeginning)
+ for (typename CollectionType::iterator i = begin(C), e = C.end();
+ i != e; ++i)
+ i->skip();
+}
+
+/// @brief Represents a YAML map created from either a block map for a flow map.
+///
+/// This parses the YAML stream as increment() is called.
+///
+/// Example:
+/// Name: _main
+/// Scope: Global
+class MappingNode : public Node {
+public:
+ enum MappingType {
+ MT_Block,
+ MT_Flow,
+ MT_Inline //< An inline mapping node is used for "[key: value]".
+ };
+
+ MappingNode(OwningPtr<Document> &D, StringRef Anchor, MappingType MT)
+ : Node(NK_Mapping, D, Anchor)
+ , Type(MT)
+ , IsAtBeginning(true)
+ , IsAtEnd(false)
+ , CurrentEntry(0)
+ {}
+
+ friend class basic_collection_iterator<MappingNode, KeyValueNode>;
+ typedef basic_collection_iterator<MappingNode, KeyValueNode> iterator;
+ template <class T> friend typename T::iterator yaml::begin(T &);
+ template <class T> friend void yaml::skip(T &);
+
+ iterator begin() {
+ return yaml::begin(*this);
+ }
+
+ iterator end() { return iterator(); }
+
+ virtual void skip() {
+ yaml::skip(*this);
+ }
+
+ static inline bool classof(const MappingNode *) { return true; }
+ static inline bool classof(const Node *N) {
+ return N->getType() == NK_Mapping;
+ }
+
+private:
+ MappingType Type;
+ bool IsAtBeginning;
+ bool IsAtEnd;
+ KeyValueNode *CurrentEntry;
+
+ void increment();
+};
+
+/// @brief Represents a YAML sequence created from either a block sequence for a
+/// flow sequence.
+///
+/// This parses the YAML stream as increment() is called.
+///
+/// Example:
+/// - Hello
+/// - World
+class SequenceNode : public Node {
+public:
+ enum SequenceType {
+ ST_Block,
+ ST_Flow,
+ // Use for:
+ //
+ // key:
+ // - val1
+ // - val2
+ //
+ // As a BlockMappingEntry and BlockEnd are not created in this case.
+ ST_Indentless
+ };
+
+ SequenceNode(OwningPtr<Document> &D, StringRef Anchor, SequenceType ST)
+ : Node(NK_Sequence, D, Anchor)
+ , SeqType(ST)
+ , IsAtBeginning(true)
+ , IsAtEnd(false)
+ , WasPreviousTokenFlowEntry(true) // Start with an imaginary ','.
+ , CurrentEntry(0)
+ {}
+
+ friend class basic_collection_iterator<SequenceNode, Node>;
+ typedef basic_collection_iterator<SequenceNode, Node> iterator;
+ template <class T> friend typename T::iterator yaml::begin(T &);
+ template <class T> friend void yaml::skip(T &);
+
+ void increment();
+
+ iterator begin() {
+ return yaml::begin(*this);
+ }
+
+ iterator end() { return iterator(); }
+
+ virtual void skip() {
+ yaml::skip(*this);
+ }
+
+ static inline bool classof(const SequenceNode *) { return true; }
+ static inline bool classof(const Node *N) {
+ return N->getType() == NK_Sequence;
+ }
+
+private:
+ SequenceType SeqType;
+ bool IsAtBeginning;
+ bool IsAtEnd;
+ bool WasPreviousTokenFlowEntry;
+ Node *CurrentEntry;
+};
+
+/// @brief Represents an alias to a Node with an anchor.
+///
+/// Example:
+/// *AnchorName
+class AliasNode : public Node {
+public:
+ AliasNode(OwningPtr<Document> &D, StringRef Val)
+ : Node(NK_Alias, D, StringRef()), Name(Val) {}
+
+ StringRef getName() const { return Name; }
+ Node *getTarget();
+
+ static inline bool classof(const ScalarNode *) { return true; }
+ static inline bool classof(const Node *N) {
+ return N->getType() == NK_Alias;
+ }
+
+private:
+ StringRef Name;
+};
+
+/// @brief A YAML Stream is a sequence of Documents. A document contains a root
+/// node.
+class Document {
+public:
+ /// @brief Root for parsing a node. Returns a single node.
+ Node *parseBlockNode();
+
+ Document(Stream &ParentStream);
+
+ /// @brief Finish parsing the current document and return true if there are
+ /// more. Return false otherwise.
+ bool skip();
+
+ /// @brief Parse and return the root level node.
+ Node *getRoot() {
+ if (Root)
+ return Root;
+ return Root = parseBlockNode();
+ }
+
+private:
+ friend class Node;
+ friend class document_iterator;
+
+ /// @brief Stream to read tokens from.
+ Stream &stream;
+
+ /// @brief Used to allocate nodes to. All are destroyed without calling their
+ /// destructor when the document is destroyed.
+ BumpPtrAllocator NodeAllocator;
+
+ /// @brief The root node. Used to support skipping a partially parsed
+ /// document.
+ Node *Root;
+
+ Token &peekNext();
+ Token getNext();
+ void setError(const Twine &Message, Token &Location) const;
+ bool failed() const;
+
+ void handleTagDirective(const Token &Tag) {
+ // TODO: Track tags.
+ }
+
+ /// @brief Parse %BLAH directives and return true if any were encountered.
+ bool parseDirectives();
+
+ /// @brief Consume the next token and error if it is not \a TK.
+ bool expectToken(int TK);
+};
+
+/// @brief Iterator abstraction for Documents over a Stream.
+class document_iterator {
+public:
+ document_iterator() : Doc(NullDoc) {}
+ document_iterator(OwningPtr<Document> &D) : Doc(D) {}
+
+ bool operator !=(const document_iterator &Other) {
+ return Doc != Other.Doc;
+ }
+
+ document_iterator operator ++() {
+ if (!Doc->skip()) {
+ Doc.reset(0);
+ } else {
+ Stream &S = Doc->stream;
+ Doc.reset(new Document(S));
+ }
+ return *this;
+ }
+
+ Document &operator *() {
+ return *Doc;
+ }
+
+ OwningPtr<Document> &operator ->() {
+ return Doc;
+ }
+
+private:
+ static OwningPtr<Document> NullDoc;
+ OwningPtr<Document> &Doc;
+};
+
+}
+}
+
+#endif
diff --git a/include/llvm/Support/system_error.h b/include/llvm/Support/system_error.h
index 2c15b69..af81206 100644
--- a/include/llvm/Support/system_error.h
+++ b/include/llvm/Support/system_error.h
@@ -470,17 +470,6 @@ template <> struct hash<std::error_code>;
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 {};
@@ -738,6 +727,10 @@ class error_code {
public:
error_code() : _val_(0), _cat_(&system_category()) {}
+ static error_code success() {
+ return error_code();
+ }
+
error_code(int _val, const error_category& _cat)
: _val_(_val), _cat_(&_cat) {}
diff --git a/include/llvm/Support/type_traits.h b/include/llvm/Support/type_traits.h
index 515295b..a3a551f 100644
--- a/include/llvm/Support/type_traits.h
+++ b/include/llvm/Support/type_traits.h
@@ -17,6 +17,8 @@
#ifndef LLVM_SUPPORT_TYPE_TRAITS_H
#define LLVM_SUPPORT_TYPE_TRAITS_H
+#include "llvm/Support/DataTypes.h"
+#include <cstddef>
#include <utility>
// This is actually the conforming implementation which works with abstract
@@ -64,22 +66,99 @@ struct isPodLike {
// std::pair's are pod-like if their elements are.
template<typename T, typename U>
struct isPodLike<std::pair<T, U> > {
- static const bool value = isPodLike<T>::value & isPodLike<U>::value;
+ static const bool value = isPodLike<T>::value && isPodLike<U>::value;
};
+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;
+
/// \brief Metafunction that determines whether the two given types are
/// equivalent.
-template<typename T, typename U>
-struct is_same {
- static const bool value = false;
+template<typename T, typename U> struct is_same : public false_type {};
+template<typename T> struct is_same<T, T> : public true_type {};
+
+/// \brief Metafunction that removes const qualification from a type.
+template <typename T> struct remove_const { typedef T type; };
+template <typename T> struct remove_const<const T> { typedef T type; };
+
+/// \brief Metafunction that removes volatile qualification from a type.
+template <typename T> struct remove_volatile { typedef T type; };
+template <typename T> struct remove_volatile<volatile T> { typedef T type; };
+
+/// \brief Metafunction that removes both const and volatile qualification from
+/// a type.
+template <typename T> struct remove_cv {
+ typedef typename remove_const<typename remove_volatile<T>::type>::type type;
};
-template<typename T>
-struct is_same<T, T> {
- static const bool value = true;
+/// \brief Helper to implement is_integral metafunction.
+template <typename T> struct is_integral_impl : false_type {};
+template <> struct is_integral_impl< bool> : true_type {};
+template <> struct is_integral_impl< char> : true_type {};
+template <> struct is_integral_impl< signed char> : true_type {};
+template <> struct is_integral_impl<unsigned char> : true_type {};
+template <> struct is_integral_impl< wchar_t> : true_type {};
+template <> struct is_integral_impl< short> : true_type {};
+template <> struct is_integral_impl<unsigned short> : true_type {};
+template <> struct is_integral_impl< int> : true_type {};
+template <> struct is_integral_impl<unsigned int> : true_type {};
+template <> struct is_integral_impl< long> : true_type {};
+template <> struct is_integral_impl<unsigned long> : true_type {};
+template <> struct is_integral_impl< long long> : true_type {};
+template <> struct is_integral_impl<unsigned long long> : true_type {};
+
+/// \brief Metafunction that determines whether the given type is an integral
+/// type.
+template <typename T>
+struct is_integral : is_integral_impl<T> {};
+
+/// \brief Metafunction to remove reference from a type.
+template <typename T> struct remove_reference { typedef T type; };
+template <typename T> struct remove_reference<T&> { typedef T type; };
+
+/// \brief Metafunction that determines whether the given type is a pointer
+/// type.
+template <typename T> struct is_pointer : false_type {};
+template <typename T> struct is_pointer<T*> : true_type {};
+template <typename T> struct is_pointer<T* const> : true_type {};
+template <typename T> struct is_pointer<T* volatile> : true_type {};
+template <typename T> struct is_pointer<T* const volatile> : true_type {};
+
+/// \brief Metafunction that determines whether the given type is either an
+/// integral type or an enumeration type.
+///
+/// Note that this accepts potentially more integral types than we whitelist
+/// above for is_integral because it is based on merely being convertible
+/// implicitly to an integral type.
+template <typename T> class is_integral_or_enum {
+ // Provide an overload which can be called with anything implicitly
+ // convertible to an unsigned long long. This should catch integer types and
+ // enumeration types at least. We blacklist classes with conversion operators
+ // below.
+ static double check_int_convertible(unsigned long long);
+ static char check_int_convertible(...);
+
+ typedef typename remove_reference<T>::type UnderlyingT;
+ static UnderlyingT &nonce_instance;
+
+public:
+ enum {
+ value = (!is_class<UnderlyingT>::value && !is_pointer<UnderlyingT>::value &&
+ !is_same<UnderlyingT, float>::value &&
+ !is_same<UnderlyingT, double>::value &&
+ sizeof(char) != sizeof(check_int_convertible(nonce_instance)))
+ };
};
-
+
// enable_if_c - Enable/disable a template based on a metafunction
template<bool Cond, typename T = void>
struct enable_if_c {
OpenPOWER on IntegriCloud