diff options
Diffstat (limited to 'include/llvm/Support')
-rw-r--r-- | include/llvm/Support/CFG.h | 6 | ||||
-rw-r--r-- | include/llvm/Support/CommandLine.h | 148 | ||||
-rw-r--r-- | include/llvm/Support/DataStream.h | 38 | ||||
-rw-r--r-- | include/llvm/Support/Dwarf.h | 5 | ||||
-rw-r--r-- | include/llvm/Support/Endian.h | 12 | ||||
-rw-r--r-- | include/llvm/Support/InstVisitor.h | 1 | ||||
-rw-r--r-- | include/llvm/Support/JSONParser.h | 448 | ||||
-rw-r--r-- | include/llvm/Support/LockFileManager.h | 74 | ||||
-rw-r--r-- | include/llvm/Support/MemoryObject.h | 11 | ||||
-rw-r--r-- | include/llvm/Support/PatternMatch.h | 91 | ||||
-rw-r--r-- | include/llvm/Support/Process.h | 3 | ||||
-rw-r--r-- | include/llvm/Support/Recycler.h | 3 | ||||
-rw-r--r-- | include/llvm/Support/SaveAndRestore.h | 47 | ||||
-rw-r--r-- | include/llvm/Support/StreamableMemoryObject.h | 181 | ||||
-rw-r--r-- | include/llvm/Support/TargetRegistry.h | 6 | ||||
-rw-r--r-- | include/llvm/Support/system_error.h | 15 | ||||
-rw-r--r-- | include/llvm/Support/type_traits.h | 61 |
17 files changed, 1012 insertions, 138 deletions
diff --git a/include/llvm/Support/CFG.h b/include/llvm/Support/CFG.h index 6e354f9..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; diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h index a2990e4..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; } @@ -341,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> @@ -1177,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(); } @@ -1192,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(); @@ -1215,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(); @@ -1225,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(); @@ -1235,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(); @@ -1344,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(); @@ -1380,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(); @@ -1390,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(); @@ -1400,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(); @@ -1542,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(); @@ -1578,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(); @@ -1588,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(); @@ -1598,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(); @@ -1638,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/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/Dwarf.h b/include/llvm/Support/Dwarf.h index 357f555a..e57fbf7 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, 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/InstVisitor.h b/include/llvm/Support/InstVisitor.h index a661c4f..4b1f3c9 100644 --- a/include/llvm/Support/InstVisitor.h +++ b/include/llvm/Support/InstVisitor.h @@ -162,7 +162,6 @@ public: 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);} 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/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/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/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/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/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 ea55c91..93bdbca 100644 --- a/include/llvm/Support/TargetRegistry.h +++ b/include/llvm/Support/TargetRegistry.h @@ -104,6 +104,7 @@ namespace llvm { typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Target &T, unsigned SyntaxVariant, const MCAsmInfo &MAI, + const MCRegisterInfo &MRI, const MCSubtargetInfo &STI); typedef MCCodeEmitter *(*MCCodeEmitterCtorTy)(const MCInstrInfo &II, const MCSubtargetInfo &STI, @@ -392,10 +393,11 @@ namespace llvm { MCInstPrinter *createMCInstPrinter(unsigned SyntaxVariant, const MCAsmInfo &MAI, + const MCRegisterInfo &MRI, const MCSubtargetInfo &STI) const { if (!MCInstPrinterCtorFn) return 0; - return MCInstPrinterCtorFn(*this, SyntaxVariant, MAI, STI); + return MCInstPrinterCtorFn(*this, SyntaxVariant, MAI, MRI, STI); } @@ -786,7 +788,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) { 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..85d90b1 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 @@ -68,17 +70,62 @@ struct isPodLike<std::pair<T, U> > { }; +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; }; -template<typename T> -struct is_same<T, T> { - static const bool value = true; +/// \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; }; + +/// \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 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 {}; + // enable_if_c - Enable/disable a template based on a metafunction template<bool Cond, typename T = void> |