aboutsummaryrefslogtreecommitdiff
path: root/include/llvm/Support
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/Support')
-rw-r--r--include/llvm/Support/ARMBuildAttributes.h7
-rw-r--r--include/llvm/Support/AlignOf.h14
-rw-r--r--include/llvm/Support/Allocator.h26
-rw-r--r--include/llvm/Support/BranchProbability.h2
-rw-r--r--include/llvm/Support/COFF.h12
-rw-r--r--include/llvm/Support/COM.h36
-rw-r--r--include/llvm/Support/CommandLine.h507
-rw-r--r--include/llvm/Support/Compiler.h144
-rw-r--r--include/llvm/Support/Compression.h4
-rw-r--r--include/llvm/Support/ConvertUTF.h8
-rw-r--r--include/llvm/Support/CrashRecoveryContext.h2
-rw-r--r--include/llvm/Support/DataExtractor.h1
-rw-r--r--include/llvm/Support/Debug.h3
-rw-r--r--include/llvm/Support/Dwarf.def350
-rw-r--r--include/llvm/Support/Dwarf.h339
-rw-r--r--include/llvm/Support/ELF.h79
-rw-r--r--include/llvm/Support/ELFRelocs/Mips.def5
-rw-r--r--include/llvm/Support/Endian.h23
-rw-r--r--include/llvm/Support/EndianStream.h25
-rw-r--r--include/llvm/Support/ErrorOr.h6
-rw-r--r--include/llvm/Support/FileOutputBuffer.h4
-rw-r--r--include/llvm/Support/FileSystem.h9
-rw-r--r--include/llvm/Support/FileUtilities.h4
-rw-r--r--include/llvm/Support/Format.h192
-rw-r--r--include/llvm/Support/FormattedStream.h72
-rw-r--r--include/llvm/Support/GCOV.h147
-rw-r--r--include/llvm/Support/GenericDomTree.h95
-rw-r--r--include/llvm/Support/GenericDomTreeConstruction.h20
-rw-r--r--include/llvm/Support/GraphWriter.h3
-rw-r--r--include/llvm/Support/LockFileManager.h8
-rw-r--r--include/llvm/Support/MathExtras.h378
-rw-r--r--include/llvm/Support/MemoryBuffer.h6
-rw-r--r--include/llvm/Support/MipsABIFlags.h102
-rw-r--r--include/llvm/Support/Mutex.h6
-rw-r--r--include/llvm/Support/MutexGuard.h4
-rw-r--r--include/llvm/Support/OnDiskHashTable.h7
-rw-r--r--include/llvm/Support/Options.h2
-rw-r--r--include/llvm/Support/PrettyStackTrace.h4
-rw-r--r--include/llvm/Support/Program.h3
-rw-r--r--include/llvm/Support/RWMutex.h6
-rw-r--r--include/llvm/Support/RandomNumberGenerator.h6
-rw-r--r--include/llvm/Support/Regex.h3
-rw-r--r--include/llvm/Support/Registry.h9
-rw-r--r--include/llvm/Support/ScaledNumber.h25
-rw-r--r--include/llvm/Support/Signals.h15
-rw-r--r--include/llvm/Support/SourceMgr.h4
-rw-r--r--include/llvm/Support/SpecialCaseList.h30
-rw-r--r--include/llvm/Support/StreamingMemoryObject.h39
-rw-r--r--include/llvm/Support/StringPool.h4
-rw-r--r--include/llvm/Support/SwapByteOrder.h20
-rw-r--r--include/llvm/Support/SystemUtils.h2
-rw-r--r--include/llvm/Support/TargetParser.h155
-rw-r--r--include/llvm/Support/TargetRegistry.h2170
-rw-r--r--include/llvm/Support/Timer.h7
-rw-r--r--include/llvm/Support/ToolOutputFile.h21
-rw-r--r--include/llvm/Support/UnicodeCharRanges.h4
-rw-r--r--include/llvm/Support/UniqueLock.h4
-rw-r--r--include/llvm/Support/Watchdog.h4
-rw-r--r--include/llvm/Support/YAMLParser.h57
-rw-r--r--include/llvm/Support/YAMLTraits.h169
-rw-r--r--include/llvm/Support/circular_raw_ostream.h23
-rw-r--r--include/llvm/Support/raw_os_ostream.h2
-rw-r--r--include/llvm/Support/raw_ostream.h253
-rw-r--r--include/llvm/Support/type_traits.h10
64 files changed, 3106 insertions, 2595 deletions
diff --git a/include/llvm/Support/ARMBuildAttributes.h b/include/llvm/Support/ARMBuildAttributes.h
index 96a8219bfb85..fc14cb2d0b0c 100644
--- a/include/llvm/Support/ARMBuildAttributes.h
+++ b/include/llvm/Support/ARMBuildAttributes.h
@@ -100,13 +100,13 @@ enum CPUArch {
v5TEJ = 5, // e.g. ARM926EJ_S
v6 = 6, // e.g. ARM1136J_S
v6KZ = 7, // e.g. ARM1176JZ_S
- v6T2 = 8, // e.g. ARM1156T2F_S
- v6K = 9, // e.g. ARM1136J_S
+ v6T2 = 8, // e.g. ARM1156T2_S
+ v6K = 9, // e.g. ARM1176JZ_S
v7 = 10, // e.g. Cortex A8, Cortex M3
v6_M = 11, // e.g. Cortex M1
v6S_M = 12, // v6_M with the System extensions
v7E_M = 13, // v7_M with DSP extensions
- v8 = 14 // v8, AArch32
+ v8 = 14, // v8,v8.1a AArch32
};
enum CPUArchProfile { // (=7), uleb128
@@ -145,6 +145,7 @@ enum {
AllowNeon = 1, // SIMDv1 was permitted
AllowNeon2 = 2, // SIMDv2 was permitted (Half-precision FP, MAC operations)
AllowNeonARMv8 = 3, // ARM v8-A SIMD was permitted
+ AllowNeonARMv8_1a = 4,// ARM v8.1-A SIMD was permitted (RDMA)
// Tag_ABI_PCS_R9_use, (=14), uleb128
R9IsGPR = 0, // R9 used as v6 (just another callee-saved register)
diff --git a/include/llvm/Support/AlignOf.h b/include/llvm/Support/AlignOf.h
index 061d5acf2322..574b514aef39 100644
--- a/include/llvm/Support/AlignOf.h
+++ b/include/llvm/Support/AlignOf.h
@@ -22,6 +22,14 @@ namespace llvm {
template <typename T>
struct AlignmentCalcImpl {
char x;
+#if defined(_MSC_VER)
+// Disables "structure was padded due to __declspec(align())" warnings that are
+// generated by any class using AlignOf<T> with a manually specified alignment.
+// Although the warning is disabled in the LLVM project we need this pragma
+// as AlignOf.h is a published support header that's available for use
+// out-of-tree, and we would like that to compile cleanly at /W4.
+#pragma warning(suppress : 4324)
+#endif
T t;
private:
AlignmentCalcImpl() {} // Never instantiate.
@@ -190,12 +198,12 @@ union SizerImpl {
} // end namespace detail
/// \brief This union template exposes a suitably aligned and sized character
-/// array member which can hold elements of any of up to four types.
+/// array member which can hold elements of any of up to ten types.
///
/// These types may be arrays, structs, or any other types. The goal is to
/// expose a char array buffer member which can be used as suitable storage for
-/// a placement new of any of these types. Support for more than seven types can
-/// be added at the cost of more boiler plate.
+/// a placement new of any of these types. Support for more than ten types can
+/// be added at the cost of more boilerplate.
template <typename T1,
typename T2 = char, typename T3 = char, typename T4 = char,
typename T5 = char, typename T6 = char, typename T7 = char,
diff --git a/include/llvm/Support/Allocator.h b/include/llvm/Support/Allocator.h
index de317719714d..f9b5cf22f97d 100644
--- a/include/llvm/Support/Allocator.h
+++ b/include/llvm/Support/Allocator.h
@@ -148,7 +148,7 @@ public:
: CurPtr(nullptr), End(nullptr), BytesAllocated(0),
Allocator(std::forward<T &&>(Allocator)) {}
- // Manually implement a move constructor as we must clear the old allocators
+ // Manually implement a move constructor as we must clear the old allocator's
// slabs as a matter of correctness.
BumpPtrAllocatorImpl(BumpPtrAllocatorImpl &&Old)
: CurPtr(Old.CurPtr), End(Old.End), Slabs(std::move(Old.Slabs)),
@@ -187,6 +187,9 @@ public:
/// \brief Deallocate all but the current slab and reset the current pointer
/// to the beginning of it, freeing all memory allocated so far.
void Reset() {
+ DeallocateCustomSizedSlabs();
+ CustomSizedSlabs.clear();
+
if (Slabs.empty())
return;
@@ -195,15 +198,14 @@ public:
CurPtr = (char *)Slabs.front();
End = CurPtr + SlabSize;
- // Deallocate all but the first slab, and all custome sized slabs.
+ // Deallocate all but the first slab, and deallocate all custom-sized slabs.
DeallocateSlabs(std::next(Slabs.begin()), Slabs.end());
Slabs.erase(std::next(Slabs.begin()), Slabs.end());
- DeallocateCustomSizedSlabs();
- CustomSizedSlabs.clear();
}
/// \brief Allocate space at the specified alignment.
- LLVM_ATTRIBUTE_RETURNS_NONNULL void *Allocate(size_t Size, size_t Alignment) {
+ LLVM_ATTRIBUTE_RETURNS_NONNULL LLVM_ATTRIBUTE_RETURNS_NOALIAS void *
+ Allocate(size_t Size, size_t Alignment) {
assert(Alignment > 0 && "0-byte alignnment is not allowed. Use 1 instead.");
// Keep track of how many bytes we've allocated.
@@ -319,14 +321,6 @@ private:
for (; I != E; ++I) {
size_t AllocatedSlabSize =
computeSlabSize(std::distance(Slabs.begin(), I));
-#ifndef NDEBUG
- // Poison the memory so stale pointers crash sooner. Note we must
- // preserve the Size and NextPtr fields at the beginning.
- if (AllocatedSlabSize != 0) {
- sys::Memory::setRangeWritable(*I, AllocatedSlabSize);
- memset(*I, 0xCD, AllocatedSlabSize);
- }
-#endif
Allocator.Deallocate(*I, AllocatedSlabSize);
}
}
@@ -336,12 +330,6 @@ private:
for (auto &PtrAndSize : CustomSizedSlabs) {
void *Ptr = PtrAndSize.first;
size_t Size = PtrAndSize.second;
-#ifndef NDEBUG
- // Poison the memory so stale pointers crash sooner. Note we must
- // preserve the Size and NextPtr fields at the beginning.
- sys::Memory::setRangeWritable(Ptr, Size);
- memset(Ptr, 0xCD, Size);
-#endif
Allocator.Deallocate(Ptr, Size);
}
}
diff --git a/include/llvm/Support/BranchProbability.h b/include/llvm/Support/BranchProbability.h
index 9aab6ace6e3f..a6429dd22a3b 100644
--- a/include/llvm/Support/BranchProbability.h
+++ b/include/llvm/Support/BranchProbability.h
@@ -31,7 +31,7 @@ class BranchProbability {
public:
BranchProbability(uint32_t n, uint32_t d) : N(n), D(d) {
- assert(d > 0 && "Denomiator cannot be 0!");
+ assert(d > 0 && "Denominator cannot be 0!");
assert(n <= d && "Probability cannot be bigger than 1!");
}
diff --git a/include/llvm/Support/COFF.h b/include/llvm/Support/COFF.h
index 150bce50d9ae..7f54822d503f 100644
--- a/include/llvm/Support/COFF.h
+++ b/include/llvm/Support/COFF.h
@@ -664,16 +664,16 @@ namespace COFF {
}
};
- enum CodeViewLineTableIdentifiers {
- DEBUG_SECTION_MAGIC = 0x4,
- DEBUG_SYMBOL_SUBSECTION = 0xF1,
- DEBUG_LINE_TABLE_SUBSECTION = 0xF2,
+ enum CodeViewIdentifiers {
+ DEBUG_SECTION_MAGIC = 0x4,
+ DEBUG_SYMBOL_SUBSECTION = 0xF1,
+ DEBUG_LINE_TABLE_SUBSECTION = 0xF2,
DEBUG_STRING_TABLE_SUBSECTION = 0xF3,
- DEBUG_INDEX_SUBSECTION = 0xF4,
+ DEBUG_INDEX_SUBSECTION = 0xF4,
// Symbol subsections are split into records of different types.
DEBUG_SYMBOL_TYPE_PROC_START = 0x1147,
- DEBUG_SYMBOL_TYPE_PROC_END = 0x114F
+ DEBUG_SYMBOL_TYPE_PROC_END = 0x114F
};
inline bool isReservedSectionNumber(int32_t SectionNumber) {
diff --git a/include/llvm/Support/COM.h b/include/llvm/Support/COM.h
new file mode 100644
index 000000000000..a2d5a7a68ba9
--- /dev/null
+++ b/include/llvm/Support/COM.h
@@ -0,0 +1,36 @@
+//===- llvm/Support/COM.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// Provides a library for accessing COM functionality of the Host OS.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_COM_H
+#define LLVM_SUPPORT_COM_H
+
+namespace llvm {
+namespace sys {
+
+enum class COMThreadingMode { SingleThreaded, MultiThreaded };
+
+class InitializeCOMRAII {
+public:
+ explicit InitializeCOMRAII(COMThreadingMode Threading,
+ bool SpeedOverMemory = false);
+ ~InitializeCOMRAII();
+
+private:
+ InitializeCOMRAII(const InitializeCOMRAII &) = delete;
+ void operator=(const InitializeCOMRAII &) = delete;
+};
+}
+}
+
+#endif
diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h
index 1c06bf5f8c07..bd1d1cb6dc97 100644
--- a/include/llvm/Support/CommandLine.h
+++ b/include/llvm/Support/CommandLine.h
@@ -20,6 +20,7 @@
#ifndef LLVM_SUPPORT_COMMANDLINE_H
#define LLVM_SUPPORT_COMMANDLINE_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/Twine.h"
@@ -72,8 +73,17 @@ void AddExtraVersionPrinter(void (*func)());
// (Currently not perfect, but best-effort.)
void PrintOptionValues();
-// MarkOptionsChanged - Internal helper function.
-void MarkOptionsChanged();
+// Forward declaration - AddLiteralOption needs to be up here to make gcc happy.
+class Option;
+
+/// \brief Adds a new option for parsing and provides the option it refers to.
+///
+/// \param O pointer to the option
+/// \param Name the string name for the option to handle during parsing
+///
+/// Literal options are used by some parsers to register special option values.
+/// This is how the PassNameParser registers pass names for opt.
+void AddLiteralOption(Option &O, const char *Name);
//===----------------------------------------------------------------------===//
// Flags permitted to be passed to command line arguments
@@ -191,13 +201,13 @@ class Option {
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.
public:
const char *ArgStr; // The argument string itself (ex: "help", "o")
const char *HelpStr; // The descriptive text message for -help
const char *ValueStr; // String describing what the value of this option is
OptionCategory *Category; // The Category this option belongs to
+ bool FullyInitialized; // Has addArguemnt been called?
inline enum NumOccurrencesFlag getNumOccurrencesFlag() const {
return (enum NumOccurrencesFlag)Occurrences;
@@ -221,7 +231,7 @@ public:
//-------------------------------------------------------------------------===
// Accessor functions set by OptionModifiers
//
- void setArgStr(const char *S) { ArgStr = S; }
+ void setArgStr(const char *S);
void setDescription(const char *S) { HelpStr = S; }
void setValueStr(const char *S) { ValueStr = S; }
void setNumOccurrencesFlag(enum NumOccurrencesFlag Val) { Occurrences = Val; }
@@ -237,8 +247,8 @@ protected:
enum OptionHidden Hidden)
: NumOccurrences(0), Occurrences(OccurrencesFlag), Value(0),
HiddenFlag(Hidden), Formatting(NormalFormatting), Misc(0), Position(0),
- AdditionalVals(0), NextRegistered(nullptr), ArgStr(""), HelpStr(""),
- ValueStr(""), Category(&GeneralCategory) {}
+ AdditionalVals(0), ArgStr(""), HelpStr(""), ValueStr(""),
+ Category(&GeneralCategory), FullyInitialized(false) {}
inline void setNumAdditionalVals(unsigned n) { AdditionalVals = n; }
@@ -253,8 +263,6 @@ public:
/// For testing purposes only.
void removeArgument();
- Option *getNextRegisteredOption() const { return NextRegistered; }
-
// Return the width of the option tag for printing...
virtual size_t getOptionWidth() const = 0;
@@ -344,9 +352,14 @@ struct cat {
// Support value comparison outside the template.
struct GenericOptionValue {
- virtual ~GenericOptionValue() {}
virtual bool compare(const GenericOptionValue &V) const = 0;
+protected:
+ ~GenericOptionValue() = default;
+ GenericOptionValue() = default;
+ GenericOptionValue(const GenericOptionValue&) = default;
+ GenericOptionValue &operator=(const GenericOptionValue &) = default;
+
private:
virtual void anchor();
};
@@ -372,6 +385,9 @@ struct OptionValueBase : public GenericOptionValue {
bool compare(const GenericOptionValue & /*V*/) const override {
return false;
}
+
+protected:
+ ~OptionValueBase() = default;
};
// Simple copy of the option value.
@@ -379,6 +395,11 @@ template <class DataType> class OptionValueCopy : public GenericOptionValue {
DataType Value;
bool Valid;
+protected:
+ ~OptionValueCopy() = default;
+ OptionValueCopy(const OptionValueCopy&) = default;
+ OptionValueCopy &operator=(const OptionValueCopy&) = default;
+
public:
OptionValueCopy() : Valid(false) {}
@@ -409,12 +430,19 @@ public:
template <class DataType>
struct OptionValueBase<DataType, false> : OptionValueCopy<DataType> {
typedef DataType WrapperType;
+
+protected:
+ ~OptionValueBase() = default;
+ OptionValueBase() = default;
+ OptionValueBase(const OptionValueBase&) = default;
+ OptionValueBase &operator=(const OptionValueBase&) = default;
};
// Top-level option class.
template <class DataType>
-struct OptionValue : OptionValueBase<DataType, std::is_class<DataType>::value> {
- OptionValue() {}
+struct OptionValue final
+ : OptionValueBase<DataType, std::is_class<DataType>::value> {
+ OptionValue() = default;
OptionValue(const DataType &V) { this->setValue(V); }
// Some options may take their value from a different data type.
@@ -427,7 +455,8 @@ struct OptionValue : OptionValueBase<DataType, std::is_class<DataType>::value> {
// Other safe-to-copy-by-value common option types.
enum boolOrDefault { BOU_UNSET, BOU_TRUE, BOU_FALSE };
template <>
-struct OptionValue<cl::boolOrDefault> : OptionValueCopy<cl::boolOrDefault> {
+struct OptionValue<cl::boolOrDefault> final
+ : OptionValueCopy<cl::boolOrDefault> {
typedef cl::boolOrDefault WrapperType;
OptionValue() {}
@@ -442,7 +471,8 @@ private:
void anchor() override;
};
-template <> struct OptionValue<std::string> : OptionValueCopy<std::string> {
+template <>
+struct OptionValue<std::string> final : OptionValueCopy<std::string> {
typedef StringRef WrapperType;
OptionValue() {}
@@ -531,6 +561,8 @@ protected:
};
public:
+ generic_parser_base(Option &O) : Owner(O) {}
+
virtual ~generic_parser_base() {} // Base class should have virtual-dtor
// getNumOptions - Virtual function implemented by generic subclass to
@@ -569,18 +601,13 @@ public:
printGenericOptionDiff(O, V, Default, GlobalWidth);
}
- void initialize(Option &O) {
- // All of the modifiers for the option have been processed by now, so the
- // argstr field should be stable, copy it down now.
- //
- hasArgStr = O.hasArgStr();
- }
+ void initialize() {}
void getExtraOptionNames(SmallVectorImpl<const char *> &OptionNames) {
// If there has been no argstr specified, that means that we need to add an
// argument for every possible option. This ensures that our options are
// vectored to us.
- if (!hasArgStr)
+ if (!Owner.hasArgStr())
for (unsigned i = 0, e = getNumOptions(); i != e; ++i)
OptionNames.push_back(getOption(i));
}
@@ -597,7 +624,7 @@ public:
//
// If this is the case, we cannot allow a value.
//
- if (hasArgStr)
+ if (Owner.hasArgStr())
return ValueRequired;
else
return ValueDisallowed;
@@ -609,7 +636,7 @@ public:
unsigned findOption(const char *Name);
protected:
- bool hasArgStr;
+ Option &Owner;
};
// Default parser implementation - This implementation depends on having a
@@ -629,6 +656,7 @@ protected:
SmallVector<OptionInfo, 8> Values;
public:
+ parser(Option &O) : generic_parser_base(O) {}
typedef DataType parser_data_type;
// Implement virtual functions needed by generic_parser_base
@@ -646,7 +674,7 @@ public:
// parse - Return true on error.
bool parse(Option &O, StringRef ArgName, StringRef Arg, DataType &V) {
StringRef ArgVal;
- if (hasArgStr)
+ if (Owner.hasArgStr())
ArgVal = Arg;
else
ArgVal = ArgName;
@@ -667,7 +695,7 @@ public:
assert(findOption(Name) == Values.size() && "Option already exists!");
OptionInfo X(Name, static_cast<DataType>(V), HelpStr);
Values.push_back(X);
- MarkOptionsChanged();
+ AddLiteralOption(Owner, Name);
}
/// removeLiteralOption - Remove the specified option.
@@ -684,7 +712,8 @@ public:
//
class basic_parser_impl { // non-template implementation of basic_parser<t>
public:
- virtual ~basic_parser_impl() {}
+ basic_parser_impl(Option &O) {}
+
enum ValueExpected getValueExpectedFlagDefault() const {
return ValueRequired;
@@ -692,7 +721,7 @@ public:
void getExtraOptionNames(SmallVectorImpl<const char *> &) {}
- void initialize(Option &) {}
+ void initialize() {}
// Return the width of the option tag for printing...
size_t getOptionWidth(const Option &O) const;
@@ -713,6 +742,7 @@ public:
virtual void anchor();
protected:
+ ~basic_parser_impl() = default;
// A helper for basic_parser::printOptionDiff.
void printOptionName(const Option &O, size_t GlobalWidth) const;
};
@@ -722,21 +752,26 @@ protected:
//
template <class DataType> class basic_parser : public basic_parser_impl {
public:
+ basic_parser(Option &O) : basic_parser_impl(O) {}
typedef DataType parser_data_type;
typedef OptionValue<DataType> OptVal;
+
+protected:
+ // Workaround Clang PR22793
+ ~basic_parser() {}
};
//--------------------------------------------------
// parser<bool>
//
-template <> class parser<bool> : public basic_parser<bool> {
- const char *ArgStr;
-
+template <> class parser<bool> final : public basic_parser<bool> {
public:
+ parser(Option &O) : basic_parser(O) {}
+
// parse - Return true on error.
bool parse(Option &O, StringRef ArgName, StringRef Arg, bool &Val);
- template <class Opt> void initialize(Opt &O) { ArgStr = O.ArgStr; }
+ void initialize() {}
enum ValueExpected getValueExpectedFlagDefault() const {
return ValueOptional;
@@ -756,8 +791,11 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<bool>);
//--------------------------------------------------
// parser<boolOrDefault>
-template <> class parser<boolOrDefault> : public basic_parser<boolOrDefault> {
+template <>
+class parser<boolOrDefault> final : public basic_parser<boolOrDefault> {
public:
+ parser(Option &O) : basic_parser(O) {}
+
// parse - Return true on error.
bool parse(Option &O, StringRef ArgName, StringRef Arg, boolOrDefault &Val);
@@ -780,8 +818,10 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<boolOrDefault>);
//--------------------------------------------------
// parser<int>
//
-template <> class parser<int> : public basic_parser<int> {
+template <> class parser<int> final : public basic_parser<int> {
public:
+ parser(Option &O) : basic_parser(O) {}
+
// parse - Return true on error.
bool parse(Option &O, StringRef ArgName, StringRef Arg, int &Val);
@@ -800,8 +840,10 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<int>);
//--------------------------------------------------
// parser<unsigned>
//
-template <> class parser<unsigned> : public basic_parser<unsigned> {
+template <> class parser<unsigned> final : public basic_parser<unsigned> {
public:
+ parser(Option &O) : basic_parser(O) {}
+
// parse - Return true on error.
bool parse(Option &O, StringRef ArgName, StringRef Arg, unsigned &Val);
@@ -821,8 +863,11 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<unsigned>);
// parser<unsigned long long>
//
template <>
-class parser<unsigned long long> : public basic_parser<unsigned long long> {
+class parser<unsigned long long> final
+ : public basic_parser<unsigned long long> {
public:
+ parser(Option &O) : basic_parser(O) {}
+
// parse - Return true on error.
bool parse(Option &O, StringRef ArgName, StringRef Arg,
unsigned long long &Val);
@@ -842,8 +887,10 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<unsigned long long>);
//--------------------------------------------------
// parser<double>
//
-template <> class parser<double> : public basic_parser<double> {
+template <> class parser<double> final : public basic_parser<double> {
public:
+ parser(Option &O) : basic_parser(O) {}
+
// parse - Return true on error.
bool parse(Option &O, StringRef ArgName, StringRef Arg, double &Val);
@@ -862,8 +909,10 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<double>);
//--------------------------------------------------
// parser<float>
//
-template <> class parser<float> : public basic_parser<float> {
+template <> class parser<float> final : public basic_parser<float> {
public:
+ parser(Option &O) : basic_parser(O) {}
+
// parse - Return true on error.
bool parse(Option &O, StringRef ArgName, StringRef Arg, float &Val);
@@ -882,8 +931,10 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<float>);
//--------------------------------------------------
// parser<std::string>
//
-template <> class parser<std::string> : public basic_parser<std::string> {
+template <> class parser<std::string> final : public basic_parser<std::string> {
public:
+ parser(Option &O) : basic_parser(O) {}
+
// parse - Return true on error.
bool parse(Option &, StringRef, StringRef Arg, std::string &Value) {
Value = Arg.str();
@@ -905,8 +956,10 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<std::string>);
//--------------------------------------------------
// parser<char>
//
-template <> class parser<char> : public basic_parser<char> {
+template <> class parser<char> final : public basic_parser<char> {
public:
+ parser(Option &O) : basic_parser(O) {}
+
// parse - Return true on error.
bool parse(Option &, StringRef, StringRef Arg, char &Value) {
Value = Arg[0];
@@ -942,7 +995,7 @@ void printOptionDiff(const Option &O, const generic_parser_base &P, const DT &V,
// This is instantiated for basic parsers when the parsed value has a different
// type than the option value. e.g. HelpPrinter.
template <class ParserDT, class ValDT> struct OptionDiffPrinter {
- void print(const Option &O, const parser<ParserDT> P, const ValDT & /*V*/,
+ void print(const Option &O, const parser<ParserDT> &P, const ValDT & /*V*/,
const OptionValue<ValDT> & /*Default*/, size_t GlobalWidth) {
P.printOptionNoValue(O, GlobalWidth);
}
@@ -951,7 +1004,7 @@ template <class ParserDT, class ValDT> struct OptionDiffPrinter {
// This is instantiated for basic parsers when the parsed value has the same
// type as the option value.
template <class DT> struct OptionDiffPrinter<DT, DT> {
- void print(const Option &O, const parser<DT> P, const DT &V,
+ void print(const Option &O, const parser<DT> &P, const DT &V,
const OptionValue<DT> &Default, size_t GlobalWidth) {
P.printOptionDiff(O, V, Default, GlobalWidth);
}
@@ -1015,8 +1068,14 @@ template <> struct applicator<MiscFlags> {
static void opt(MiscFlags MF, Option &O) { O.setMiscFlag(MF); }
};
-// apply method - Apply a modifier to an option in a type safe way.
-template <class Mod, class Opt> void apply(const Mod &M, Opt *O) {
+// apply method - Apply modifiers to an option in a type safe way.
+template <class Opt, class Mod, class... Mods>
+void apply(Opt *O, const Mod &M, const Mods &... Ms) {
+ applicator<Mod>::opt(M, *O);
+ apply(O, Ms...);
+}
+
+template <class Opt, class Mod> void apply(Opt *O, const Mod &M) {
applicator<Mod>::opt(M, *O);
}
@@ -1166,9 +1225,13 @@ class opt : public Option,
void done() {
addArgument();
- Parser.initialize(*this);
+ Parser.initialize();
}
+ // Command line options should not be copyable
+ opt(const opt &) = delete;
+ opt &operator=(const opt &) = delete;
+
public:
// setInitialValue - Used by the cl::init modifier...
void setInitialValue(const DataType &V) { this->setValue(V, true); }
@@ -1180,95 +1243,10 @@ public:
return this->getValue();
}
- // One option...
- template <class M0t>
- 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) {
- apply(M0, this);
- apply(M1, this);
- done();
- }
-
- // Three options...
- template <class M0t, class M1t, class M2t>
- opt(const M0t &M0, const M1t &M1, 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) {
- 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) {
- apply(M0, this);
- apply(M1, this);
- apply(M2, this);
- apply(M3, this);
- apply(M4, this);
- done();
- }
- // Six options...
- 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) {
- apply(M0, this);
- apply(M1, this);
- apply(M2, this);
- apply(M3, this);
- apply(M4, this);
- apply(M5, this);
- done();
- }
- // Seven options...
- template <class M0t, class M1t, class M2t, class M3t, 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) {
- apply(M0, this);
- apply(M1, this);
- apply(M2, this);
- apply(M3, this);
- apply(M4, this);
- apply(M5, this);
- apply(M6, this);
- done();
- }
- // Eight options...
- template <class M0t, class M1t, class M2t, class M3t, 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) {
- apply(M0, this);
- apply(M1, this);
- apply(M2, this);
- apply(M3, this);
- apply(M4, this);
- apply(M5, this);
- apply(M6, this);
- apply(M7, this);
+ template <class... Mods>
+ explicit opt(const Mods &... Ms)
+ : Option(Optional, NotHidden), Parser(*this) {
+ apply(this, Ms...);
done();
}
};
@@ -1361,9 +1339,13 @@ class list : public Option, public list_storage<DataType, Storage> {
void done() {
addArgument();
- Parser.initialize(*this);
+ Parser.initialize();
}
+ // Command line options should not be copyable
+ list(const list &) = delete;
+ list &operator=(const list &) = delete;
+
public:
ParserClass &getParser() { return Parser; }
@@ -1374,94 +1356,10 @@ public:
void setNumAdditionalVals(unsigned n) { Option::setNumAdditionalVals(n); }
- // One option...
- template <class M0t>
- 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) {
- 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) {
- 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) {
- 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) {
- apply(M0, this);
- apply(M1, this);
- apply(M2, this);
- apply(M3, this);
- apply(M4, this);
- done();
- }
- // Six options...
- 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) {
- apply(M0, this);
- apply(M1, this);
- apply(M2, this);
- apply(M3, this);
- apply(M4, this);
- apply(M5, this);
- done();
- }
- // Seven options...
- template <class M0t, class M1t, class M2t, class M3t, 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) {
- apply(M0, this);
- apply(M1, this);
- apply(M2, this);
- apply(M3, this);
- apply(M4, this);
- apply(M5, this);
- apply(M6, this);
- done();
- }
- // Eight options...
- template <class M0t, class M1t, class M2t, class M3t, 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) {
- apply(M0, this);
- apply(M1, this);
- apply(M2, this);
- apply(M3, this);
- apply(M4, this);
- apply(M5, this);
- apply(M6, this);
- apply(M7, this);
+ template <class... Mods>
+ explicit list(const Mods &... Ms)
+ : Option(ZeroOrMore, NotHidden), Parser(*this) {
+ apply(this, Ms...);
done();
}
};
@@ -1581,9 +1479,13 @@ class bits : public Option, public bits_storage<DataType, Storage> {
void done() {
addArgument();
- Parser.initialize(*this);
+ Parser.initialize();
}
+ // Command line options should not be copyable
+ bits(const bits &) = delete;
+ bits &operator=(const bits &) = delete;
+
public:
ParserClass &getParser() { return Parser; }
@@ -1592,94 +1494,10 @@ public:
return Positions[optnum];
}
- // One option...
- template <class M0t>
- 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) {
- 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) {
- 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) {
- 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) {
- apply(M0, this);
- apply(M1, this);
- apply(M2, this);
- apply(M3, this);
- apply(M4, this);
- done();
- }
- // Six options...
- 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) {
- apply(M0, this);
- apply(M1, this);
- apply(M2, this);
- apply(M3, this);
- apply(M4, this);
- apply(M5, this);
- done();
- }
- // Seven options...
- template <class M0t, class M1t, class M2t, class M3t, 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) {
- apply(M0, this);
- apply(M1, this);
- apply(M2, this);
- apply(M3, this);
- apply(M4, this);
- apply(M5, this);
- apply(M6, this);
- done();
- }
- // Eight options...
- template <class M0t, class M1t, class M2t, class M3t, 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) {
- apply(M0, this);
- apply(M1, this);
- apply(M2, this);
- apply(M3, this);
- apply(M4, this);
- apply(M5, this);
- apply(M6, this);
- apply(M7, this);
+ template <class... Mods>
+ explicit bits(const Mods &... Ms)
+ : Option(ZeroOrMore, NotHidden), Parser(*this) {
+ apply(this, Ms...);
done();
}
};
@@ -1718,6 +1536,10 @@ class alias : public Option {
addArgument();
}
+ // Command line options should not be copyable
+ alias(const alias &) = delete;
+ alias &operator=(const alias &) = delete;
+
public:
void setAliasFor(Option &O) {
if (AliasFor)
@@ -1725,38 +1547,10 @@ public:
AliasFor = &O;
}
- // One option...
- template <class M0t>
- explicit alias(const M0t &M0)
- : Option(Optional, Hidden), AliasFor(nullptr) {
- apply(M0, this);
- done();
- }
- // Two options...
- template <class M0t, class M1t>
- alias(const M0t &M0, const M1t &M1)
- : Option(Optional, Hidden), AliasFor(nullptr) {
- 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(nullptr) {
- 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)
+ template <class... Mods>
+ explicit alias(const Mods &... Ms)
: Option(Optional, Hidden), AliasFor(nullptr) {
- apply(M0, this);
- apply(M1, this);
- apply(M2, this);
- apply(M3, this);
+ apply(this, Ms...);
done();
}
};
@@ -1795,9 +1589,7 @@ void PrintHelpMessage(bool Hidden = false, bool Categorized = false);
/// \brief Use this to get a StringMap to all registered named options
/// (e.g. -help). Note \p Map Should be an empty StringMap.
///
-/// \param [out] Map will be filled with mappings where the key is the
-/// Option argument string (e.g. "help") and value is the corresponding
-/// Option*.
+/// \return A reference to the StringMap used by the cl APIs to parse options.
///
/// Access to unnamed arguments (i.e. positional) are not provided because
/// it is expected that the client already has access to these.
@@ -1805,8 +1597,7 @@ void PrintHelpMessage(bool Hidden = false, bool Categorized = false);
/// Typical usage:
/// \code
/// main(int argc,char* argv[]) {
-/// StringMap<llvm::cl::Option*> opts;
-/// llvm::cl::getRegisteredOptions(opts);
+/// StringMap<llvm::cl::Option*> &opts = llvm::cl::getRegisteredOptions();
/// assert(opts.count("help") == 1)
/// opts["help"]->setDescription("Show alphabetical help information")
/// // More code
@@ -1818,7 +1609,11 @@ void PrintHelpMessage(bool Hidden = false, bool Categorized = false);
/// This interface is useful for modifying options in libraries that are out of
/// the control of the client. The options should be modified before calling
/// llvm::cl::ParseCommandLineOptions().
-void getRegisteredOptions(StringMap<Option *> &Map);
+///
+/// Hopefully this API can be depricated soon. Any situation where options need
+/// to be modified by tools or libraries should be handled by sane APIs rather
+/// than just handing around a global list.
+StringMap<Option *> &getRegisteredOptions();
//===----------------------------------------------------------------------===//
// Standalone command line processing utilities.
@@ -1889,6 +1684,24 @@ bool ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer,
SmallVectorImpl<const char *> &Argv,
bool MarkEOLs = false);
+/// \brief Mark all options not part of this category as cl::ReallyHidden.
+///
+/// \param Category the category of options to keep displaying
+///
+/// Some tools (like clang-format) like to be able to hide all options that are
+/// not specific to the tool. This function allows a tool to specify a single
+/// option category to display in the -help output.
+void HideUnrelatedOptions(cl::OptionCategory &Category);
+
+/// \brief Mark all options not part of the categories as cl::ReallyHidden.
+///
+/// \param Categories the categories of options to keep displaying.
+///
+/// Some tools (like clang-format) like to be able to hide all options that are
+/// not specific to the tool. This function allows a tool to specify a single
+/// option category to display in the -help output.
+void HideUnrelatedOptions(ArrayRef<const cl::OptionCategory *> Categories);
+
} // End namespace cl
} // End namespace llvm
diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h
index d008fec89d64..c81fbaff9dba 100644
--- a/include/llvm/Support/Compiler.h
+++ b/include/llvm/Support/Compiler.h
@@ -52,14 +52,14 @@
/// \macro LLVM_MSC_PREREQ
/// \brief Is the compiler MSVC of at least the specified version?
/// The common \param version values to check for are:
-/// * 1700: Microsoft Visual Studio 2012 / 11.0
/// * 1800: Microsoft Visual Studio 2013 / 12.0
+/// * 1900: Microsoft Visual Studio 2015 / 14.0
#ifdef _MSC_VER
#define LLVM_MSC_PREREQ(version) (_MSC_VER >= (version))
-// We require at least MSVC 2012.
-#if !LLVM_MSC_PREREQ(1700)
-#error LLVM requires at least MSVC 2012.
+// We require at least MSVC 2013.
+#if !LLVM_MSC_PREREQ(1800)
+#error LLVM requires at least MSVC 2013.
#endif
#else
@@ -72,54 +72,26 @@
#define LLVM_NOEXCEPT
#endif
-/// \brief Does the compiler support r-value reference *this?
+/// \brief Does the compiler support ref-qualifiers for *this?
///
-/// Sadly, this is separate from just r-value reference support because GCC
-/// implemented this later than everything else.
+/// Sadly, this is separate from just rvalue reference support because GCC
+/// and MSVC implemented this later than everything else.
#if __has_feature(cxx_rvalue_references) || LLVM_GNUC_PREREQ(4, 8, 1)
#define LLVM_HAS_RVALUE_REFERENCE_THIS 1
#else
#define LLVM_HAS_RVALUE_REFERENCE_THIS 0
#endif
-/// \macro LLVM_HAS_VARIADIC_TEMPLATES
-/// \brief Does this compiler support variadic templates.
+/// Expands to '&' if ref-qualifiers for *this are supported.
///
-/// Implies LLVM_HAS_RVALUE_REFERENCES and the existence of std::forward.
-#if __has_feature(cxx_variadic_templates) || LLVM_MSC_PREREQ(1800)
-# define LLVM_HAS_VARIADIC_TEMPLATES 1
-#else
-# define LLVM_HAS_VARIADIC_TEMPLATES 0
-#endif
-
-/// Expands to '&' if r-value references are supported.
-///
-/// This can be used to provide l-value/r-value overrides of member functions.
-/// The r-value override should be guarded by LLVM_HAS_RVALUE_REFERENCE_THIS
+/// This can be used to provide lvalue/rvalue overrides of member functions.
+/// The rvalue override should be guarded by LLVM_HAS_RVALUE_REFERENCE_THIS
#if LLVM_HAS_RVALUE_REFERENCE_THIS
#define LLVM_LVALUE_FUNCTION &
#else
#define LLVM_LVALUE_FUNCTION
#endif
-/// LLVM_DELETED_FUNCTION - Expands to = delete if the compiler supports it.
-/// Use to mark functions as uncallable. Member functions with this should
-/// be declared private so that some behavior is kept in C++03 mode.
-///
-/// class DontCopy {
-/// private:
-/// DontCopy(const DontCopy&) LLVM_DELETED_FUNCTION;
-/// DontCopy &operator =(const DontCopy&) LLVM_DELETED_FUNCTION;
-/// public:
-/// ...
-/// };
-#if __has_feature(cxx_deleted_functions) || \
- defined(__GXX_EXPERIMENTAL_CXX0X__) || LLVM_MSC_PREREQ(1800)
-#define LLVM_DELETED_FUNCTION = delete
-#else
-#define LLVM_DELETED_FUNCTION
-#endif
-
#if __has_feature(cxx_constexpr) || defined(__GXX_EXPERIMENTAL_CXX0X__)
# define LLVM_CONSTEXPR constexpr
#else
@@ -251,6 +223,16 @@
#define LLVM_ATTRIBUTE_RETURNS_NONNULL
#endif
+/// \macro LLVM_ATTRIBUTE_RETURNS_NOALIAS Used to mark a function as returning a
+/// pointer that does not alias any other valid pointer.
+#ifdef __GNUC__
+#define LLVM_ATTRIBUTE_RETURNS_NOALIAS __attribute__((__malloc__))
+#elif defined(_MSC_VER)
+#define LLVM_ATTRIBUTE_RETURNS_NOALIAS __declspec(restrict)
+#else
+#define LLVM_ATTRIBUTE_RETURNS_NOALIAS
+#endif
+
/// LLVM_EXTENSION - Support compilers where we have a keyword to suppress
/// pedantic diagnostics.
#ifdef __GNUC__
@@ -287,6 +269,12 @@
/// which causes the program to exit abnormally.
#if __has_builtin(__builtin_trap) || LLVM_GNUC_PREREQ(4, 3, 0)
# define LLVM_BUILTIN_TRAP __builtin_trap()
+#elif defined(_MSC_VER)
+// The __debugbreak intrinsic is supported by MSVC, does not require forward
+// declarations involving platform-specific typedefs (unlike RaiseException),
+// results in a call to vectored exception handlers, and encodes to a short
+// instruction that still causes the trapping behavior we want.
+# define LLVM_BUILTIN_TRAP __debugbreak()
#else
# define LLVM_BUILTIN_TRAP *(volatile int*)0x11 = 0
#endif
@@ -303,6 +291,37 @@
# define LLVM_ASSUME_ALIGNED(p, a) (p)
#endif
+/// \macro LLVM_ALIGNAS
+/// \brief Used to specify a minimum alignment for a structure or variable. The
+/// alignment must be a constant integer. Use LLVM_PTR_SIZE to compute
+/// alignments in terms of the size of a pointer.
+///
+/// Note that __declspec(align) has special quirks, it's not legal to pass a
+/// structure with __declspec(align) as a formal parameter.
+#ifdef _MSC_VER
+# define LLVM_ALIGNAS(x) __declspec(align(x))
+#elif __GNUC__ && !__has_feature(cxx_alignas) && !LLVM_GNUC_PREREQ(4, 8, 0)
+# define LLVM_ALIGNAS(x) __attribute__((aligned(x)))
+#else
+# define LLVM_ALIGNAS(x) alignas(x)
+#endif
+
+/// \macro LLVM_PTR_SIZE
+/// \brief A constant integer equivalent to the value of sizeof(void*).
+/// Generally used in combination with LLVM_ALIGNAS or when doing computation in
+/// the preprocessor.
+#ifdef __SIZEOF_POINTER__
+# define LLVM_PTR_SIZE __SIZEOF_POINTER__
+#elif defined(_WIN64)
+# define LLVM_PTR_SIZE 8
+#elif defined(_WIN32)
+# define LLVM_PTR_SIZE 4
+#elif defined(_MSC_VER)
+# error "could not determine LLVM_PTR_SIZE as a constant int for MSVC"
+#else
+# define LLVM_PTR_SIZE sizeof(void *)
+#endif
+
/// \macro LLVM_FUNCTION_NAME
/// \brief Expands to __func__ on compilers which support it. Otherwise,
/// expands to a compiler-dependent replacement.
@@ -344,26 +363,6 @@
# define LLVM_IS_UNALIGNED_ACCESS_FAST 0
#endif
-/// \macro LLVM_EXPLICIT
-/// \brief Expands to explicit on compilers which support explicit conversion
-/// operators. Otherwise expands to nothing.
-#if __has_feature(cxx_explicit_conversions) || \
- defined(__GXX_EXPERIMENTAL_CXX0X__) || LLVM_MSC_PREREQ(1800)
-#define LLVM_EXPLICIT explicit
-#else
-#define LLVM_EXPLICIT
-#endif
-
-/// \brief Does the compiler support generalized initializers (using braced
-/// lists and std::initializer_list). While clang may claim it supports general
-/// initializers, if we're using MSVC's headers, we might not have a usable
-/// std::initializer list type from the STL. Disable this for now.
-#if __has_feature(cxx_generalized_initializers) && !defined(_MSC_VER)
-#define LLVM_HAS_INITIALIZER_LISTS 1
-#else
-#define LLVM_HAS_INITIALIZER_LISTS 0
-#endif
-
/// \brief Mark debug helper function definitions like dump() that should not be
/// stripped from debug builds.
// FIXME: Move this to a private config.h as it's not usable in public headers.
@@ -373,4 +372,33 @@
#define LLVM_DUMP_METHOD LLVM_ATTRIBUTE_NOINLINE
#endif
+/// \macro LLVM_THREAD_LOCAL
+/// \brief A thread-local storage specifier which can be used with globals,
+/// extern globals, and static globals.
+///
+/// This is essentially an extremely restricted analog to C++11's thread_local
+/// support, and uses that when available. However, it falls back on
+/// platform-specific or vendor-provided extensions when necessary. These
+/// extensions don't support many of the C++11 thread_local's features. You
+/// should only use this for PODs that you can statically initialize to
+/// some constant value. In almost all circumstances this is most appropriate
+/// for use with a pointer, integer, or small aggregation of pointers and
+/// integers.
+#if LLVM_ENABLE_THREADS
+#if __has_feature(cxx_thread_local)
+#define LLVM_THREAD_LOCAL thread_local
+#elif defined(_MSC_VER)
+// MSVC supports this with a __declspec.
+#define LLVM_THREAD_LOCAL __declspec(thread)
+#else
+// Clang, GCC, and other compatible compilers used __thread prior to C++11 and
+// we only need the restricted functionality that provides.
+#define LLVM_THREAD_LOCAL __thread
+#endif
+#else // !LLVM_ENABLE_THREADS
+// If threading is disabled entirely, this compiles to nothing and you get
+// a normal global variable.
+#define LLVM_THREAD_LOCAL
+#endif
+
#endif
diff --git a/include/llvm/Support/Compression.h b/include/llvm/Support/Compression.h
index 88727fa3fcfc..28274d67aad2 100644
--- a/include/llvm/Support/Compression.h
+++ b/include/llvm/Support/Compression.h
@@ -14,12 +14,10 @@
#ifndef LLVM_SUPPORT_COMPRESSION_H
#define LLVM_SUPPORT_COMPRESSION_H
-#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/DataTypes.h"
-#include <memory>
namespace llvm {
-
+template <typename T> class SmallVectorImpl;
class StringRef;
namespace zlib {
diff --git a/include/llvm/Support/ConvertUTF.h b/include/llvm/Support/ConvertUTF.h
index a184d0df2132..38952ec99e61 100644
--- a/include/llvm/Support/ConvertUTF.h
+++ b/include/llvm/Support/ConvertUTF.h
@@ -251,6 +251,14 @@ bool hasUTF16ByteOrderMark(ArrayRef<char> SrcBytes);
*/
bool convertUTF16ToUTF8String(ArrayRef<char> SrcBytes, std::string &Out);
+/**
+ * Converts a UTF-8 string into a UTF-16 string with native endianness.
+ *
+ * \returns true on success
+ */
+bool convertUTF8ToUTF16String(StringRef SrcUTF8,
+ SmallVectorImpl<UTF16> &DstUTF16);
+
} /* end namespace llvm */
#endif
diff --git a/include/llvm/Support/CrashRecoveryContext.h b/include/llvm/Support/CrashRecoveryContext.h
index 1f3965c8ade4..c08c3c1f0d21 100644
--- a/include/llvm/Support/CrashRecoveryContext.h
+++ b/include/llvm/Support/CrashRecoveryContext.h
@@ -14,8 +14,6 @@
#include <string>
namespace llvm {
-class StringRef;
-
class CrashRecoveryContextCleanup;
/// \brief Crash recovery helper object.
diff --git a/include/llvm/Support/DataExtractor.h b/include/llvm/Support/DataExtractor.h
index 48235d4145bd..3ffa9bc90dd1 100644
--- a/include/llvm/Support/DataExtractor.h
+++ b/include/llvm/Support/DataExtractor.h
@@ -10,7 +10,6 @@
#ifndef LLVM_SUPPORT_DATAEXTRACTOR_H
#define LLVM_SUPPORT_DATAEXTRACTOR_H
-#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataTypes.h"
diff --git a/include/llvm/Support/Debug.h b/include/llvm/Support/Debug.h
index e93e6ca34498..fff4f986a6c0 100644
--- a/include/llvm/Support/Debug.h
+++ b/include/llvm/Support/Debug.h
@@ -28,9 +28,8 @@
#ifndef LLVM_SUPPORT_DEBUG_H
#define LLVM_SUPPORT_DEBUG_H
-#include "llvm/Support/raw_ostream.h"
-
namespace llvm {
+class raw_ostream;
#ifndef NDEBUG
/// DebugFlag - This boolean is set to true if the '-debug' command line option
diff --git a/include/llvm/Support/Dwarf.def b/include/llvm/Support/Dwarf.def
new file mode 100644
index 000000000000..4b923b897e6f
--- /dev/null
+++ b/include/llvm/Support/Dwarf.def
@@ -0,0 +1,350 @@
+//===- llvm/Support/Dwarf.def - Dwarf definitions ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Macros for running through Dwarf enumerators.
+//
+//===----------------------------------------------------------------------===//
+
+// TODO: Add other DW-based macros.
+#if !(defined HANDLE_DW_TAG || defined HANDLE_DW_OP || \
+ defined HANDLE_DW_LANG || defined HANDLE_DW_ATE || \
+ defined HANDLE_DW_VIRTUALITY)
+#error "Missing macro definition of HANDLE_DW*"
+#endif
+
+#ifndef HANDLE_DW_TAG
+#define HANDLE_DW_TAG(ID, NAME)
+#endif
+
+#ifndef HANDLE_DW_OP
+#define HANDLE_DW_OP(ID, NAME)
+#endif
+
+#ifndef HANDLE_DW_LANG
+#define HANDLE_DW_LANG(ID, NAME)
+#endif
+
+#ifndef HANDLE_DW_ATE
+#define HANDLE_DW_ATE(ID, NAME)
+#endif
+
+#ifndef HANDLE_DW_VIRTUALITY
+#define HANDLE_DW_VIRTUALITY(ID, NAME)
+#endif
+
+HANDLE_DW_TAG(0x0001, array_type)
+HANDLE_DW_TAG(0x0002, class_type)
+HANDLE_DW_TAG(0x0003, entry_point)
+HANDLE_DW_TAG(0x0004, enumeration_type)
+HANDLE_DW_TAG(0x0005, formal_parameter)
+HANDLE_DW_TAG(0x0008, imported_declaration)
+HANDLE_DW_TAG(0x000a, label)
+HANDLE_DW_TAG(0x000b, lexical_block)
+HANDLE_DW_TAG(0x000d, member)
+HANDLE_DW_TAG(0x000f, pointer_type)
+HANDLE_DW_TAG(0x0010, reference_type)
+HANDLE_DW_TAG(0x0011, compile_unit)
+HANDLE_DW_TAG(0x0012, string_type)
+HANDLE_DW_TAG(0x0013, structure_type)
+HANDLE_DW_TAG(0x0015, subroutine_type)
+HANDLE_DW_TAG(0x0016, typedef)
+HANDLE_DW_TAG(0x0017, union_type)
+HANDLE_DW_TAG(0x0018, unspecified_parameters)
+HANDLE_DW_TAG(0x0019, variant)
+HANDLE_DW_TAG(0x001a, common_block)
+HANDLE_DW_TAG(0x001b, common_inclusion)
+HANDLE_DW_TAG(0x001c, inheritance)
+HANDLE_DW_TAG(0x001d, inlined_subroutine)
+HANDLE_DW_TAG(0x001e, module)
+HANDLE_DW_TAG(0x001f, ptr_to_member_type)
+HANDLE_DW_TAG(0x0020, set_type)
+HANDLE_DW_TAG(0x0021, subrange_type)
+HANDLE_DW_TAG(0x0022, with_stmt)
+HANDLE_DW_TAG(0x0023, access_declaration)
+HANDLE_DW_TAG(0x0024, base_type)
+HANDLE_DW_TAG(0x0025, catch_block)
+HANDLE_DW_TAG(0x0026, const_type)
+HANDLE_DW_TAG(0x0027, constant)
+HANDLE_DW_TAG(0x0028, enumerator)
+HANDLE_DW_TAG(0x0029, file_type)
+HANDLE_DW_TAG(0x002a, friend)
+HANDLE_DW_TAG(0x002b, namelist)
+HANDLE_DW_TAG(0x002c, namelist_item)
+HANDLE_DW_TAG(0x002d, packed_type)
+HANDLE_DW_TAG(0x002e, subprogram)
+HANDLE_DW_TAG(0x002f, template_type_parameter)
+HANDLE_DW_TAG(0x0030, template_value_parameter)
+HANDLE_DW_TAG(0x0031, thrown_type)
+HANDLE_DW_TAG(0x0032, try_block)
+HANDLE_DW_TAG(0x0033, variant_part)
+HANDLE_DW_TAG(0x0034, variable)
+HANDLE_DW_TAG(0x0035, volatile_type)
+HANDLE_DW_TAG(0x0036, dwarf_procedure)
+HANDLE_DW_TAG(0x0037, restrict_type)
+HANDLE_DW_TAG(0x0038, interface_type)
+HANDLE_DW_TAG(0x0039, namespace)
+HANDLE_DW_TAG(0x003a, imported_module)
+HANDLE_DW_TAG(0x003b, unspecified_type)
+HANDLE_DW_TAG(0x003c, partial_unit)
+HANDLE_DW_TAG(0x003d, imported_unit)
+HANDLE_DW_TAG(0x003f, condition)
+HANDLE_DW_TAG(0x0040, shared_type)
+HANDLE_DW_TAG(0x0041, type_unit)
+HANDLE_DW_TAG(0x0042, rvalue_reference_type)
+HANDLE_DW_TAG(0x0043, template_alias)
+
+// Mock tags we use as discriminators.
+HANDLE_DW_TAG(0x0100, auto_variable) // Tag for local (auto) variables.
+HANDLE_DW_TAG(0x0101, arg_variable) // Tag for argument variables.
+
+// New in DWARF v5.
+HANDLE_DW_TAG(0x0044, coarray_type)
+HANDLE_DW_TAG(0x0045, generic_subrange)
+HANDLE_DW_TAG(0x0046, dynamic_type)
+
+// User-defined tags.
+HANDLE_DW_TAG(0x4081, MIPS_loop)
+HANDLE_DW_TAG(0x4101, format_label)
+HANDLE_DW_TAG(0x4102, function_template)
+HANDLE_DW_TAG(0x4103, class_template)
+HANDLE_DW_TAG(0x4106, GNU_template_template_param)
+HANDLE_DW_TAG(0x4107, GNU_template_parameter_pack)
+HANDLE_DW_TAG(0x4108, GNU_formal_parameter_pack)
+HANDLE_DW_TAG(0x4200, APPLE_property)
+
+HANDLE_DW_OP(0x03, addr)
+HANDLE_DW_OP(0x06, deref)
+HANDLE_DW_OP(0x08, const1u)
+HANDLE_DW_OP(0x09, const1s)
+HANDLE_DW_OP(0x0a, const2u)
+HANDLE_DW_OP(0x0b, const2s)
+HANDLE_DW_OP(0x0c, const4u)
+HANDLE_DW_OP(0x0d, const4s)
+HANDLE_DW_OP(0x0e, const8u)
+HANDLE_DW_OP(0x0f, const8s)
+HANDLE_DW_OP(0x10, constu)
+HANDLE_DW_OP(0x11, consts)
+HANDLE_DW_OP(0x12, dup)
+HANDLE_DW_OP(0x13, drop)
+HANDLE_DW_OP(0x14, over)
+HANDLE_DW_OP(0x15, pick)
+HANDLE_DW_OP(0x16, swap)
+HANDLE_DW_OP(0x17, rot)
+HANDLE_DW_OP(0x18, xderef)
+HANDLE_DW_OP(0x19, abs)
+HANDLE_DW_OP(0x1a, and)
+HANDLE_DW_OP(0x1b, div)
+HANDLE_DW_OP(0x1c, minus)
+HANDLE_DW_OP(0x1d, mod)
+HANDLE_DW_OP(0x1e, mul)
+HANDLE_DW_OP(0x1f, neg)
+HANDLE_DW_OP(0x20, not)
+HANDLE_DW_OP(0x21, or )
+HANDLE_DW_OP(0x22, plus)
+HANDLE_DW_OP(0x23, plus_uconst)
+HANDLE_DW_OP(0x24, shl)
+HANDLE_DW_OP(0x25, shr)
+HANDLE_DW_OP(0x26, shra)
+HANDLE_DW_OP(0x27, xor)
+HANDLE_DW_OP(0x2f, skip)
+HANDLE_DW_OP(0x28, bra)
+HANDLE_DW_OP(0x29, eq)
+HANDLE_DW_OP(0x2a, ge)
+HANDLE_DW_OP(0x2b, gt)
+HANDLE_DW_OP(0x2c, le)
+HANDLE_DW_OP(0x2d, lt)
+HANDLE_DW_OP(0x2e, ne)
+HANDLE_DW_OP(0x30, lit0)
+HANDLE_DW_OP(0x31, lit1)
+HANDLE_DW_OP(0x32, lit2)
+HANDLE_DW_OP(0x33, lit3)
+HANDLE_DW_OP(0x34, lit4)
+HANDLE_DW_OP(0x35, lit5)
+HANDLE_DW_OP(0x36, lit6)
+HANDLE_DW_OP(0x37, lit7)
+HANDLE_DW_OP(0x38, lit8)
+HANDLE_DW_OP(0x39, lit9)
+HANDLE_DW_OP(0x3a, lit10)
+HANDLE_DW_OP(0x3b, lit11)
+HANDLE_DW_OP(0x3c, lit12)
+HANDLE_DW_OP(0x3d, lit13)
+HANDLE_DW_OP(0x3e, lit14)
+HANDLE_DW_OP(0x3f, lit15)
+HANDLE_DW_OP(0x40, lit16)
+HANDLE_DW_OP(0x41, lit17)
+HANDLE_DW_OP(0x42, lit18)
+HANDLE_DW_OP(0x43, lit19)
+HANDLE_DW_OP(0x44, lit20)
+HANDLE_DW_OP(0x45, lit21)
+HANDLE_DW_OP(0x46, lit22)
+HANDLE_DW_OP(0x47, lit23)
+HANDLE_DW_OP(0x48, lit24)
+HANDLE_DW_OP(0x49, lit25)
+HANDLE_DW_OP(0x4a, lit26)
+HANDLE_DW_OP(0x4b, lit27)
+HANDLE_DW_OP(0x4c, lit28)
+HANDLE_DW_OP(0x4d, lit29)
+HANDLE_DW_OP(0x4e, lit30)
+HANDLE_DW_OP(0x4f, lit31)
+HANDLE_DW_OP(0x50, reg0)
+HANDLE_DW_OP(0x51, reg1)
+HANDLE_DW_OP(0x52, reg2)
+HANDLE_DW_OP(0x53, reg3)
+HANDLE_DW_OP(0x54, reg4)
+HANDLE_DW_OP(0x55, reg5)
+HANDLE_DW_OP(0x56, reg6)
+HANDLE_DW_OP(0x57, reg7)
+HANDLE_DW_OP(0x58, reg8)
+HANDLE_DW_OP(0x59, reg9)
+HANDLE_DW_OP(0x5a, reg10)
+HANDLE_DW_OP(0x5b, reg11)
+HANDLE_DW_OP(0x5c, reg12)
+HANDLE_DW_OP(0x5d, reg13)
+HANDLE_DW_OP(0x5e, reg14)
+HANDLE_DW_OP(0x5f, reg15)
+HANDLE_DW_OP(0x60, reg16)
+HANDLE_DW_OP(0x61, reg17)
+HANDLE_DW_OP(0x62, reg18)
+HANDLE_DW_OP(0x63, reg19)
+HANDLE_DW_OP(0x64, reg20)
+HANDLE_DW_OP(0x65, reg21)
+HANDLE_DW_OP(0x66, reg22)
+HANDLE_DW_OP(0x67, reg23)
+HANDLE_DW_OP(0x68, reg24)
+HANDLE_DW_OP(0x69, reg25)
+HANDLE_DW_OP(0x6a, reg26)
+HANDLE_DW_OP(0x6b, reg27)
+HANDLE_DW_OP(0x6c, reg28)
+HANDLE_DW_OP(0x6d, reg29)
+HANDLE_DW_OP(0x6e, reg30)
+HANDLE_DW_OP(0x6f, reg31)
+HANDLE_DW_OP(0x70, breg0)
+HANDLE_DW_OP(0x71, breg1)
+HANDLE_DW_OP(0x72, breg2)
+HANDLE_DW_OP(0x73, breg3)
+HANDLE_DW_OP(0x74, breg4)
+HANDLE_DW_OP(0x75, breg5)
+HANDLE_DW_OP(0x76, breg6)
+HANDLE_DW_OP(0x77, breg7)
+HANDLE_DW_OP(0x78, breg8)
+HANDLE_DW_OP(0x79, breg9)
+HANDLE_DW_OP(0x7a, breg10)
+HANDLE_DW_OP(0x7b, breg11)
+HANDLE_DW_OP(0x7c, breg12)
+HANDLE_DW_OP(0x7d, breg13)
+HANDLE_DW_OP(0x7e, breg14)
+HANDLE_DW_OP(0x7f, breg15)
+HANDLE_DW_OP(0x80, breg16)
+HANDLE_DW_OP(0x81, breg17)
+HANDLE_DW_OP(0x82, breg18)
+HANDLE_DW_OP(0x83, breg19)
+HANDLE_DW_OP(0x84, breg20)
+HANDLE_DW_OP(0x85, breg21)
+HANDLE_DW_OP(0x86, breg22)
+HANDLE_DW_OP(0x87, breg23)
+HANDLE_DW_OP(0x88, breg24)
+HANDLE_DW_OP(0x89, breg25)
+HANDLE_DW_OP(0x8a, breg26)
+HANDLE_DW_OP(0x8b, breg27)
+HANDLE_DW_OP(0x8c, breg28)
+HANDLE_DW_OP(0x8d, breg29)
+HANDLE_DW_OP(0x8e, breg30)
+HANDLE_DW_OP(0x8f, breg31)
+HANDLE_DW_OP(0x90, regx)
+HANDLE_DW_OP(0x91, fbreg)
+HANDLE_DW_OP(0x92, bregx)
+HANDLE_DW_OP(0x93, piece)
+HANDLE_DW_OP(0x94, deref_size)
+HANDLE_DW_OP(0x95, xderef_size)
+HANDLE_DW_OP(0x96, nop)
+HANDLE_DW_OP(0x97, push_object_address)
+HANDLE_DW_OP(0x98, call2)
+HANDLE_DW_OP(0x99, call4)
+HANDLE_DW_OP(0x9a, call_ref)
+HANDLE_DW_OP(0x9b, form_tls_address)
+HANDLE_DW_OP(0x9c, call_frame_cfa)
+HANDLE_DW_OP(0x9d, bit_piece)
+HANDLE_DW_OP(0x9e, implicit_value)
+HANDLE_DW_OP(0x9f, stack_value)
+
+// Extensions for GNU-style thread-local storage.
+HANDLE_DW_OP(0xe0, GNU_push_tls_address)
+
+// Extensions for Fission proposal.
+HANDLE_DW_OP(0xfb, GNU_addr_index)
+HANDLE_DW_OP(0xfc, GNU_const_index)
+
+// DWARF languages.
+HANDLE_DW_LANG(0x0001, C89)
+HANDLE_DW_LANG(0x0002, C)
+HANDLE_DW_LANG(0x0003, Ada83)
+HANDLE_DW_LANG(0x0004, C_plus_plus)
+HANDLE_DW_LANG(0x0005, Cobol74)
+HANDLE_DW_LANG(0x0006, Cobol85)
+HANDLE_DW_LANG(0x0007, Fortran77)
+HANDLE_DW_LANG(0x0008, Fortran90)
+HANDLE_DW_LANG(0x0009, Pascal83)
+HANDLE_DW_LANG(0x000a, Modula2)
+HANDLE_DW_LANG(0x000b, Java)
+HANDLE_DW_LANG(0x000c, C99)
+HANDLE_DW_LANG(0x000d, Ada95)
+HANDLE_DW_LANG(0x000e, Fortran95)
+HANDLE_DW_LANG(0x000f, PLI)
+HANDLE_DW_LANG(0x0010, ObjC)
+HANDLE_DW_LANG(0x0011, ObjC_plus_plus)
+HANDLE_DW_LANG(0x0012, UPC)
+HANDLE_DW_LANG(0x0013, D)
+
+// New in DWARF 5:
+HANDLE_DW_LANG(0x0014, Python)
+HANDLE_DW_LANG(0x0015, OpenCL)
+HANDLE_DW_LANG(0x0016, Go)
+HANDLE_DW_LANG(0x0017, Modula3)
+HANDLE_DW_LANG(0x0018, Haskell)
+HANDLE_DW_LANG(0x0019, C_plus_plus_03)
+HANDLE_DW_LANG(0x001a, C_plus_plus_11)
+HANDLE_DW_LANG(0x001b, OCaml)
+HANDLE_DW_LANG(0x001c, Rust)
+HANDLE_DW_LANG(0x001d, C11)
+HANDLE_DW_LANG(0x001e, Swift)
+HANDLE_DW_LANG(0x001f, Julia)
+HANDLE_DW_LANG(0x0020, Dylan)
+HANDLE_DW_LANG(0x0021, C_plus_plus_14)
+HANDLE_DW_LANG(0x0022, Fortran03)
+HANDLE_DW_LANG(0x0023, Fortran08)
+HANDLE_DW_LANG(0x8001, Mips_Assembler)
+
+// DWARF attribute type encodings.
+HANDLE_DW_ATE(0x01, address)
+HANDLE_DW_ATE(0x02, boolean)
+HANDLE_DW_ATE(0x03, complex_float)
+HANDLE_DW_ATE(0x04, float)
+HANDLE_DW_ATE(0x05, signed)
+HANDLE_DW_ATE(0x06, signed_char)
+HANDLE_DW_ATE(0x07, unsigned)
+HANDLE_DW_ATE(0x08, unsigned_char)
+HANDLE_DW_ATE(0x09, imaginary_float)
+HANDLE_DW_ATE(0x0a, packed_decimal)
+HANDLE_DW_ATE(0x0b, numeric_string)
+HANDLE_DW_ATE(0x0c, edited)
+HANDLE_DW_ATE(0x0d, signed_fixed)
+HANDLE_DW_ATE(0x0e, unsigned_fixed)
+HANDLE_DW_ATE(0x0f, decimal_float)
+HANDLE_DW_ATE(0x10, UTF)
+
+// DWARF virtuality codes.
+HANDLE_DW_VIRTUALITY(0x00, none)
+HANDLE_DW_VIRTUALITY(0x01, virtual)
+HANDLE_DW_VIRTUALITY(0x02, pure_virtual)
+
+#undef HANDLE_DW_TAG
+#undef HANDLE_DW_OP
+#undef HANDLE_DW_LANG
+#undef HANDLE_DW_ATE
+#undef HANDLE_DW_VIRTUALITY
diff --git a/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h
index 47b00b1f09d8..c3d94d19f919 100644
--- a/include/llvm/Support/Dwarf.h
+++ b/include/llvm/Support/Dwarf.h
@@ -20,6 +20,7 @@
#ifndef LLVM_SUPPORT_DWARF_H
#define LLVM_SUPPORT_DWARF_H
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
@@ -36,15 +37,11 @@ namespace dwarf {
// enumeration base type.
enum LLVMConstants : uint32_t {
- // llvm mock tags
- DW_TAG_invalid = ~0U, // Tag for invalid results.
-
- DW_TAG_auto_variable = 0x100, // Tag for local (auto) variables.
- DW_TAG_arg_variable = 0x101, // Tag for argument variables.
- DW_TAG_expression = 0x102, // Tag for complex address expressions.
-
- DW_TAG_user_base = 0x1000, // Recommended base for user tags.
+ // LLVM mock tags (see also llvm/Support/Dwarf.def).
+ DW_TAG_invalid = ~0U, // Tag for invalid results.
+ DW_VIRTUALITY_invalid = ~0U, // Virtuality for invalid results.
+ // Other constants.
DWARF_VERSION = 4, // Default dwarf version we output.
DW_PUBTYPES_VERSION = 2, // Section version number for .debug_pubtypes.
DW_PUBNAMES_VERSION = 2, // Section version number for .debug_pubnames.
@@ -57,82 +54,11 @@ const uint32_t DW_CIE_ID = UINT32_MAX;
const uint64_t DW64_CIE_ID = UINT64_MAX;
enum Tag : uint16_t {
- DW_TAG_array_type = 0x01,
- DW_TAG_class_type = 0x02,
- DW_TAG_entry_point = 0x03,
- DW_TAG_enumeration_type = 0x04,
- DW_TAG_formal_parameter = 0x05,
- DW_TAG_imported_declaration = 0x08,
- DW_TAG_label = 0x0a,
- DW_TAG_lexical_block = 0x0b,
- DW_TAG_member = 0x0d,
- DW_TAG_pointer_type = 0x0f,
- DW_TAG_reference_type = 0x10,
- DW_TAG_compile_unit = 0x11,
- DW_TAG_string_type = 0x12,
- DW_TAG_structure_type = 0x13,
- DW_TAG_subroutine_type = 0x15,
- DW_TAG_typedef = 0x16,
- DW_TAG_union_type = 0x17,
- DW_TAG_unspecified_parameters = 0x18,
- DW_TAG_variant = 0x19,
- DW_TAG_common_block = 0x1a,
- DW_TAG_common_inclusion = 0x1b,
- DW_TAG_inheritance = 0x1c,
- DW_TAG_inlined_subroutine = 0x1d,
- DW_TAG_module = 0x1e,
- DW_TAG_ptr_to_member_type = 0x1f,
- DW_TAG_set_type = 0x20,
- DW_TAG_subrange_type = 0x21,
- DW_TAG_with_stmt = 0x22,
- DW_TAG_access_declaration = 0x23,
- DW_TAG_base_type = 0x24,
- DW_TAG_catch_block = 0x25,
- DW_TAG_const_type = 0x26,
- DW_TAG_constant = 0x27,
- DW_TAG_enumerator = 0x28,
- DW_TAG_file_type = 0x29,
- DW_TAG_friend = 0x2a,
- DW_TAG_namelist = 0x2b,
- DW_TAG_namelist_item = 0x2c,
- DW_TAG_packed_type = 0x2d,
- DW_TAG_subprogram = 0x2e,
- DW_TAG_template_type_parameter = 0x2f,
- DW_TAG_template_value_parameter = 0x30,
- DW_TAG_thrown_type = 0x31,
- DW_TAG_try_block = 0x32,
- DW_TAG_variant_part = 0x33,
- DW_TAG_variable = 0x34,
- DW_TAG_volatile_type = 0x35,
- DW_TAG_dwarf_procedure = 0x36,
- DW_TAG_restrict_type = 0x37,
- DW_TAG_interface_type = 0x38,
- DW_TAG_namespace = 0x39,
- DW_TAG_imported_module = 0x3a,
- DW_TAG_unspecified_type = 0x3b,
- DW_TAG_partial_unit = 0x3c,
- DW_TAG_imported_unit = 0x3d,
- DW_TAG_condition = 0x3f,
- DW_TAG_shared_type = 0x40,
- DW_TAG_type_unit = 0x41,
- DW_TAG_rvalue_reference_type = 0x42,
- DW_TAG_template_alias = 0x43,
-
- // New in DWARF 5:
- DW_TAG_coarray_type = 0x44,
- DW_TAG_generic_subrange = 0x45,
- DW_TAG_dynamic_type = 0x46,
-
- DW_TAG_MIPS_loop = 0x4081,
- DW_TAG_format_label = 0x4101,
- DW_TAG_function_template = 0x4102,
- DW_TAG_class_template = 0x4103,
- DW_TAG_GNU_template_template_param = 0x4106,
- DW_TAG_GNU_template_parameter_pack = 0x4107,
- DW_TAG_GNU_formal_parameter_pack = 0x4108,
+#define HANDLE_DW_TAG(ID, NAME) DW_TAG_##NAME = ID,
+#include "llvm/Support/Dwarf.def"
DW_TAG_lo_user = 0x4080,
- DW_TAG_APPLE_property = 0x4200,
- DW_TAG_hi_user = 0xffff
+ DW_TAG_hi_user = 0xffff,
+ DW_TAG_user_base = 0x1000 // Recommended base for user tags.
};
inline bool isType(Tag T) {
@@ -359,194 +285,23 @@ enum Form : uint16_t {
// Extensions for Fission proposal
DW_FORM_GNU_addr_index = 0x1f01,
- DW_FORM_GNU_str_index = 0x1f02
+ DW_FORM_GNU_str_index = 0x1f02,
+
+ // Alternate debug sections proposal (output of "dwz" tool).
+ DW_FORM_GNU_ref_alt = 0x1f20,
+ DW_FORM_GNU_strp_alt = 0x1f21
};
enum LocationAtom {
- // Operation encodings
- DW_OP_addr = 0x03,
- DW_OP_deref = 0x06,
- DW_OP_const1u = 0x08,
- DW_OP_const1s = 0x09,
- DW_OP_const2u = 0x0a,
- DW_OP_const2s = 0x0b,
- DW_OP_const4u = 0x0c,
- DW_OP_const4s = 0x0d,
- DW_OP_const8u = 0x0e,
- DW_OP_const8s = 0x0f,
- DW_OP_constu = 0x10,
- DW_OP_consts = 0x11,
- DW_OP_dup = 0x12,
- DW_OP_drop = 0x13,
- DW_OP_over = 0x14,
- DW_OP_pick = 0x15,
- DW_OP_swap = 0x16,
- DW_OP_rot = 0x17,
- DW_OP_xderef = 0x18,
- DW_OP_abs = 0x19,
- DW_OP_and = 0x1a,
- DW_OP_div = 0x1b,
- DW_OP_minus = 0x1c,
- DW_OP_mod = 0x1d,
- DW_OP_mul = 0x1e,
- DW_OP_neg = 0x1f,
- DW_OP_not = 0x20,
- DW_OP_or = 0x21,
- DW_OP_plus = 0x22,
- DW_OP_plus_uconst = 0x23,
- DW_OP_shl = 0x24,
- DW_OP_shr = 0x25,
- DW_OP_shra = 0x26,
- DW_OP_xor = 0x27,
- DW_OP_skip = 0x2f,
- DW_OP_bra = 0x28,
- DW_OP_eq = 0x29,
- DW_OP_ge = 0x2a,
- DW_OP_gt = 0x2b,
- DW_OP_le = 0x2c,
- DW_OP_lt = 0x2d,
- DW_OP_ne = 0x2e,
- DW_OP_lit0 = 0x30,
- DW_OP_lit1 = 0x31,
- DW_OP_lit2 = 0x32,
- DW_OP_lit3 = 0x33,
- DW_OP_lit4 = 0x34,
- DW_OP_lit5 = 0x35,
- DW_OP_lit6 = 0x36,
- DW_OP_lit7 = 0x37,
- DW_OP_lit8 = 0x38,
- DW_OP_lit9 = 0x39,
- DW_OP_lit10 = 0x3a,
- DW_OP_lit11 = 0x3b,
- DW_OP_lit12 = 0x3c,
- DW_OP_lit13 = 0x3d,
- DW_OP_lit14 = 0x3e,
- DW_OP_lit15 = 0x3f,
- DW_OP_lit16 = 0x40,
- DW_OP_lit17 = 0x41,
- DW_OP_lit18 = 0x42,
- DW_OP_lit19 = 0x43,
- DW_OP_lit20 = 0x44,
- DW_OP_lit21 = 0x45,
- DW_OP_lit22 = 0x46,
- DW_OP_lit23 = 0x47,
- DW_OP_lit24 = 0x48,
- DW_OP_lit25 = 0x49,
- DW_OP_lit26 = 0x4a,
- DW_OP_lit27 = 0x4b,
- DW_OP_lit28 = 0x4c,
- DW_OP_lit29 = 0x4d,
- DW_OP_lit30 = 0x4e,
- DW_OP_lit31 = 0x4f,
- DW_OP_reg0 = 0x50,
- DW_OP_reg1 = 0x51,
- DW_OP_reg2 = 0x52,
- DW_OP_reg3 = 0x53,
- DW_OP_reg4 = 0x54,
- DW_OP_reg5 = 0x55,
- DW_OP_reg6 = 0x56,
- DW_OP_reg7 = 0x57,
- DW_OP_reg8 = 0x58,
- DW_OP_reg9 = 0x59,
- DW_OP_reg10 = 0x5a,
- DW_OP_reg11 = 0x5b,
- DW_OP_reg12 = 0x5c,
- DW_OP_reg13 = 0x5d,
- DW_OP_reg14 = 0x5e,
- DW_OP_reg15 = 0x5f,
- DW_OP_reg16 = 0x60,
- DW_OP_reg17 = 0x61,
- DW_OP_reg18 = 0x62,
- DW_OP_reg19 = 0x63,
- DW_OP_reg20 = 0x64,
- DW_OP_reg21 = 0x65,
- DW_OP_reg22 = 0x66,
- DW_OP_reg23 = 0x67,
- DW_OP_reg24 = 0x68,
- DW_OP_reg25 = 0x69,
- DW_OP_reg26 = 0x6a,
- DW_OP_reg27 = 0x6b,
- DW_OP_reg28 = 0x6c,
- DW_OP_reg29 = 0x6d,
- DW_OP_reg30 = 0x6e,
- DW_OP_reg31 = 0x6f,
- DW_OP_breg0 = 0x70,
- DW_OP_breg1 = 0x71,
- DW_OP_breg2 = 0x72,
- DW_OP_breg3 = 0x73,
- DW_OP_breg4 = 0x74,
- DW_OP_breg5 = 0x75,
- DW_OP_breg6 = 0x76,
- DW_OP_breg7 = 0x77,
- DW_OP_breg8 = 0x78,
- DW_OP_breg9 = 0x79,
- DW_OP_breg10 = 0x7a,
- DW_OP_breg11 = 0x7b,
- DW_OP_breg12 = 0x7c,
- DW_OP_breg13 = 0x7d,
- DW_OP_breg14 = 0x7e,
- DW_OP_breg15 = 0x7f,
- DW_OP_breg16 = 0x80,
- DW_OP_breg17 = 0x81,
- DW_OP_breg18 = 0x82,
- DW_OP_breg19 = 0x83,
- DW_OP_breg20 = 0x84,
- DW_OP_breg21 = 0x85,
- DW_OP_breg22 = 0x86,
- DW_OP_breg23 = 0x87,
- DW_OP_breg24 = 0x88,
- DW_OP_breg25 = 0x89,
- DW_OP_breg26 = 0x8a,
- DW_OP_breg27 = 0x8b,
- DW_OP_breg28 = 0x8c,
- DW_OP_breg29 = 0x8d,
- DW_OP_breg30 = 0x8e,
- DW_OP_breg31 = 0x8f,
- DW_OP_regx = 0x90,
- DW_OP_fbreg = 0x91,
- DW_OP_bregx = 0x92,
- DW_OP_piece = 0x93,
- DW_OP_deref_size = 0x94,
- DW_OP_xderef_size = 0x95,
- DW_OP_nop = 0x96,
- DW_OP_push_object_address = 0x97,
- DW_OP_call2 = 0x98,
- DW_OP_call4 = 0x99,
- DW_OP_call_ref = 0x9a,
- DW_OP_form_tls_address = 0x9b,
- DW_OP_call_frame_cfa = 0x9c,
- DW_OP_bit_piece = 0x9d,
- DW_OP_implicit_value = 0x9e,
- DW_OP_stack_value = 0x9f,
+#define HANDLE_DW_OP(ID, NAME) DW_OP_##NAME = ID,
+#include "llvm/Support/Dwarf.def"
DW_OP_lo_user = 0xe0,
- DW_OP_hi_user = 0xff,
-
- // Extensions for GNU-style thread-local storage.
- DW_OP_GNU_push_tls_address = 0xe0,
-
- // Extensions for Fission proposal.
- DW_OP_GNU_addr_index = 0xfb,
- DW_OP_GNU_const_index = 0xfc
+ DW_OP_hi_user = 0xff
};
enum TypeKind {
- // Encoding attribute values
- DW_ATE_address = 0x01,
- DW_ATE_boolean = 0x02,
- DW_ATE_complex_float = 0x03,
- DW_ATE_float = 0x04,
- DW_ATE_signed = 0x05,
- DW_ATE_signed_char = 0x06,
- DW_ATE_unsigned = 0x07,
- DW_ATE_unsigned_char = 0x08,
- DW_ATE_imaginary_float = 0x09,
- DW_ATE_packed_decimal = 0x0a,
- DW_ATE_numeric_string = 0x0b,
- DW_ATE_edited = 0x0c,
- DW_ATE_signed_fixed = 0x0d,
- DW_ATE_unsigned_fixed = 0x0e,
- DW_ATE_decimal_float = 0x0f,
- DW_ATE_UTF = 0x10,
+#define HANDLE_DW_ATE(ID, NAME) DW_ATE_##NAME = ID,
+#include "llvm/Support/Dwarf.def"
DW_ATE_lo_user = 0x80,
DW_ATE_hi_user = 0xff
};
@@ -584,45 +339,15 @@ enum VisibilityAttribute {
};
enum VirtualityAttribute {
- // Virtuality codes
- DW_VIRTUALITY_none = 0x00,
- DW_VIRTUALITY_virtual = 0x01,
- DW_VIRTUALITY_pure_virtual = 0x02
+#define HANDLE_DW_VIRTUALITY(ID, NAME) DW_VIRTUALITY_##NAME = ID,
+#include "llvm/Support/Dwarf.def"
+ DW_VIRTUALITY_max = 0x02
};
enum SourceLanguage {
- // Language names
- DW_LANG_C89 = 0x0001,
- DW_LANG_C = 0x0002,
- DW_LANG_Ada83 = 0x0003,
- DW_LANG_C_plus_plus = 0x0004,
- DW_LANG_Cobol74 = 0x0005,
- DW_LANG_Cobol85 = 0x0006,
- DW_LANG_Fortran77 = 0x0007,
- DW_LANG_Fortran90 = 0x0008,
- DW_LANG_Pascal83 = 0x0009,
- DW_LANG_Modula2 = 0x000a,
- DW_LANG_Java = 0x000b,
- DW_LANG_C99 = 0x000c,
- DW_LANG_Ada95 = 0x000d,
- DW_LANG_Fortran95 = 0x000e,
- DW_LANG_PLI = 0x000f,
- DW_LANG_ObjC = 0x0010,
- DW_LANG_ObjC_plus_plus = 0x0011,
- DW_LANG_UPC = 0x0012,
- DW_LANG_D = 0x0013,
- // New in DWARF 5:
- DW_LANG_Python = 0x0014,
- DW_LANG_OpenCL = 0x0015,
- DW_LANG_Go = 0x0016,
- DW_LANG_Modula3 = 0x0017,
- DW_LANG_Haskell = 0x0018,
- DW_LANG_C_plus_plus_03 = 0x0019,
- DW_LANG_C_plus_plus_11 = 0x001a,
- DW_LANG_OCaml = 0x001b,
-
+#define HANDLE_DW_LANG(ID, NAME) DW_LANG_##NAME = ID,
+#include "llvm/Support/Dwarf.def"
DW_LANG_lo_user = 0x8000,
- DW_LANG_Mips_Assembler = 0x8001,
DW_LANG_hi_user = 0xffff
};
@@ -859,6 +584,22 @@ const char *GDBIndexEntryKindString(GDBIndexEntryKind Kind);
const char *GDBIndexEntryLinkageString(GDBIndexEntryLinkage Linkage);
/// @}
+/// \defgroup DwarfConstantsParsing Dwarf constants parsing functions
+///
+/// These functions map their strings back to the corresponding enumeration
+/// value or return 0 if there is none, except for these exceptions:
+///
+/// \li \a getTag() returns \a DW_TAG_invalid on invalid input.
+/// \li \a getVirtuality() returns \a DW_VIRTUALITY_invalid on invalid input.
+///
+/// @{
+unsigned getTag(StringRef TagString);
+unsigned getOperationEncoding(StringRef OperationEncodingString);
+unsigned getVirtuality(StringRef VirtualityString);
+unsigned getLanguage(StringRef LanguageString);
+unsigned getAttributeEncoding(StringRef EncodingString);
+/// @}
+
/// \brief Returns the symbolic string representing Val when used as a value
/// for attribute Attr.
const char *AttributeValueString(uint16_t Attr, unsigned Val);
diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h
index 3d49205fa168..8b915ff0581d 100644
--- a/include/llvm/Support/ELF.h
+++ b/include/llvm/Support/ELF.h
@@ -344,6 +344,7 @@ enum {
ELFOSABI_NSK = 14, // Hewlett-Packard Non-Stop Kernel
ELFOSABI_AROS = 15, // AROS
ELFOSABI_FENIXOS = 16, // FenixOS
+ ELFOSABI_CLOUDABI = 17, // Nuxi CloudABI
ELFOSABI_C6000_ELFABI = 64, // Bare-metal TMS320C6000
ELFOSABI_C6000_LINUX = 65, // Linux TMS320C6000
ELFOSABI_ARM = 97, // ARM
@@ -431,22 +432,50 @@ enum : unsigned {
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_ABI2 = 0x00000020,
- EF_MIPS_32BITMODE = 0x00000100,
+ EF_MIPS_ABI2 = 0x00000020, // File uses N32 ABI
+ EF_MIPS_32BITMODE = 0x00000100, // Code compiled for a 64-bit machine
+ // in 32-bit mode
+ EF_MIPS_FP64 = 0x00000200, // Code compiled for a 32-bit machine
+ // but uses 64-bit FP registers
EF_MIPS_NAN2008 = 0x00000400, // Uses IEE 754-2008 NaN encoding
// ABI flags
- EF_MIPS_ABI_O32 = 0x00001000, // This file follows the first MIPS 32 bit ABI
+ EF_MIPS_ABI_O32 = 0x00001000, // This file follows the first MIPS 32 bit ABI
EF_MIPS_ABI_O64 = 0x00002000, // O32 ABI extended for 64-bit architecture.
EF_MIPS_ABI_EABI32 = 0x00003000, // EABI in 32 bit mode.
EF_MIPS_ABI_EABI64 = 0x00004000, // EABI in 64 bit mode.
EF_MIPS_ABI = 0x0000f000, // Mask for selecting EF_MIPS_ABI_ variant.
- //ARCH_ASE
+ // MIPS machine variant
+ EF_MIPS_MACH_3900 = 0x00810000, // Toshiba R3900
+ EF_MIPS_MACH_4010 = 0x00820000, // LSI R4010
+ EF_MIPS_MACH_4100 = 0x00830000, // NEC VR4100
+ EF_MIPS_MACH_4650 = 0x00850000, // MIPS R4650
+ EF_MIPS_MACH_4120 = 0x00870000, // NEC VR4120
+ EF_MIPS_MACH_4111 = 0x00880000, // NEC VR4111/VR4181
+ EF_MIPS_MACH_SB1 = 0x008a0000, // Broadcom SB-1
+ EF_MIPS_MACH_OCTEON = 0x008b0000, // Cavium Networks Octeon
+ EF_MIPS_MACH_XLR = 0x008c0000, // RMI Xlr
+ EF_MIPS_MACH_OCTEON2 = 0x008d0000, // Cavium Networks Octeon2
+ EF_MIPS_MACH_OCTEON3 = 0x008e0000, // Cavium Networks Octeon3
+ EF_MIPS_MACH_5400 = 0x00910000, // NEC VR5400
+ EF_MIPS_MACH_5900 = 0x00920000, // MIPS R5900
+ EF_MIPS_MACH_5500 = 0x00980000, // NEC VR5500
+ EF_MIPS_MACH_9000 = 0x00990000, // Unknown
+ EF_MIPS_MACH_LS2E = 0x00a00000, // ST Microelectronics Loongson 2E
+ EF_MIPS_MACH_LS2F = 0x00a10000, // ST Microelectronics Loongson 2F
+ EF_MIPS_MACH_LS3A = 0x00a20000, // Loongson 3A
+ EF_MIPS_MACH = 0x00ff0000, // EF_MIPS_MACH_xxx selection mask
+
+ // ARCH_ASE
EF_MIPS_MICROMIPS = 0x02000000, // microMIPS
EF_MIPS_ARCH_ASE_M16 =
0x04000000, // Has Mips-16 ISA extensions
- //ARCH
+ EF_MIPS_ARCH_ASE_MDMX =
+ 0x08000000, // Has MDMX multimedia extensions
+ EF_MIPS_ARCH_ASE = 0x0f000000, // Mask for EF_MIPS_ARCH_ASE_xxx flags
+
+ // ARCH
EF_MIPS_ARCH_1 = 0x00000000, // MIPS1 instruction set
EF_MIPS_ARCH_2 = 0x10000000, // MIPS2 instruction set
EF_MIPS_ARCH_3 = 0x20000000, // MIPS3 instruction set
@@ -454,8 +483,8 @@ enum : unsigned {
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_32R2 = 0x70000000, // mips32r2, mips32r3, mips32r5
+ EF_MIPS_ARCH_64R2 = 0x80000000, // mips64r2, mips64r3, mips64r5
EF_MIPS_ARCH_32R6 = 0x90000000, // mips32r6
EF_MIPS_ARCH_64R6 = 0xa0000000, // mips64r6
EF_MIPS_ARCH = 0xf0000000 // Mask for applying EF_MIPS_ARCH_ variant
@@ -475,6 +504,22 @@ enum {
STO_MIPS_MIPS16 = 0xf0 // MIPS Specific ISA for Mips16
};
+// .MIPS.options section descriptor kinds
+enum {
+ ODK_NULL = 0, // Undefined
+ ODK_REGINFO = 1, // Register usage information
+ ODK_EXCEPTIONS = 2, // Exception processing options
+ ODK_PAD = 3, // Section padding options
+ ODK_HWPATCH = 4, // Hardware patches applied
+ ODK_FILL = 5, // Linker fill value
+ ODK_TAGS = 6, // Space for tool identification
+ ODK_HWAND = 7, // Hardware AND patches applied
+ ODK_HWOR = 8, // Hardware OR patches applied
+ ODK_GP_GROUP = 9, // GP group to use for text/data sections
+ ODK_IDENT = 10, // ID information
+ ODK_PAGESIZE = 11 // Page size information
+};
+
// Hexagon Specific e_flags
// Release 5 ABI
enum {
@@ -761,6 +806,7 @@ enum {
STB_LOCAL = 0, // Local symbol, not visible outside obj file containing def
STB_GLOBAL = 1, // Global symbol, visible to all object files being combined
STB_WEAK = 2, // Weak symbol, like global but lower-precedence
+ STB_GNU_UNIQUE = 10,
STB_LOOS = 10, // Lowest operating system-specific binding type
STB_HIOS = 12, // Highest operating system-specific binding type
STB_LOPROC = 13, // Lowest processor-specific binding type
@@ -795,6 +841,14 @@ enum {
STN_UNDEF = 0
};
+// Special relocation symbols used in the MIPS64 ELF relocation entries
+enum {
+ RSS_UNDEF = 0, // None
+ RSS_GP = 1, // Value of gp
+ RSS_GP0 = 2, // Value of gp used to create object being relocated
+ RSS_LOC = 3 // Address of location being relocated
+};
+
// Relocation entry, without explicit addend.
struct Elf32_Rel {
Elf32_Addr r_offset; // Location (file byte offset, or program virtual addr)
@@ -1114,7 +1168,16 @@ enum {
DF_1_CONFALT = 0x00002000, // Configuration alternative created.
DF_1_ENDFILTEE = 0x00004000, // Filtee terminates filters search.
DF_1_DISPRELDNE = 0x00008000, // Disp reloc applied at build time.
- DF_1_DISPRELPND = 0x00010000 // Disp reloc applied at run-time.
+ DF_1_DISPRELPND = 0x00010000, // Disp reloc applied at run-time.
+ DF_1_NODIRECT = 0x00020000, // Object has no-direct binding.
+ DF_1_IGNMULDEF = 0x00040000,
+ DF_1_NOKSYMS = 0x00080000,
+ DF_1_NOHDR = 0x00100000,
+ DF_1_EDITED = 0x00200000, // Object is modified after built.
+ DF_1_NORELOC = 0x00400000,
+ DF_1_SYMINTPOSE = 0x00800000, // Object has individual interposers.
+ DF_1_GLOBAUDIT = 0x01000000, // Global auditing required.
+ DF_1_SINGLETON = 0x02000000 // Singleton symbols are used.
};
// DT_MIPS_FLAGS values.
diff --git a/include/llvm/Support/ELFRelocs/Mips.def b/include/llvm/Support/ELFRelocs/Mips.def
index dc573464dcf2..77e7f8e8712b 100644
--- a/include/llvm/Support/ELFRelocs/Mips.def
+++ b/include/llvm/Support/ELFRelocs/Mips.def
@@ -108,5 +108,10 @@ ELF_RELOC(R_MICROMIPS_TLS_TPREL_HI16, 169)
ELF_RELOC(R_MICROMIPS_TLS_TPREL_LO16, 170)
ELF_RELOC(R_MICROMIPS_GPREL7_S2, 172)
ELF_RELOC(R_MICROMIPS_PC23_S2, 173)
+ELF_RELOC(R_MICROMIPS_PC21_S2, 174)
+ELF_RELOC(R_MICROMIPS_PC26_S2, 175)
+ELF_RELOC(R_MICROMIPS_PC18_S3, 176)
+ELF_RELOC(R_MICROMIPS_PC19_S2, 177)
ELF_RELOC(R_MIPS_NUM, 218)
ELF_RELOC(R_MIPS_PC32, 248)
+ELF_RELOC(R_MIPS_EH, 249)
diff --git a/include/llvm/Support/Endian.h b/include/llvm/Support/Endian.h
index 47b82fdc4975..e9fe22e5eda8 100644
--- a/include/llvm/Support/Endian.h
+++ b/include/llvm/Support/Endian.h
@@ -58,8 +58,9 @@ inline value_type read(const void *memory) {
/// Read a value of a particular endianness from a buffer, and increment the
/// buffer past that value.
-template<typename value_type, endianness endian, std::size_t alignment>
-inline value_type readNext(const unsigned char *&memory) {
+template<typename value_type, endianness endian, std::size_t alignment,
+ typename CharT>
+inline value_type readNext(const CharT *&memory) {
value_type ret = read<value_type, endian, alignment>(memory);
memory += sizeof(value_type);
return ret;
@@ -195,7 +196,23 @@ typedef detail::packed_endian_specific_integral
<int32_t, native, unaligned> unaligned_int32_t;
typedef detail::packed_endian_specific_integral
<int64_t, native, unaligned> unaligned_int64_t;
-} // end namespace llvm
+
+namespace endian {
+inline uint16_t read16le(const void *p) { return *(const ulittle16_t *)p; }
+inline uint32_t read32le(const void *p) { return *(const ulittle32_t *)p; }
+inline uint64_t read64le(const void *p) { return *(const ulittle64_t *)p; }
+inline uint16_t read16be(const void *p) { return *(const ubig16_t *)p; }
+inline uint32_t read32be(const void *p) { return *(const ubig32_t *)p; }
+inline uint64_t read64be(const void *p) { return *(const ubig64_t *)p; }
+
+inline void write16le(void *p, uint16_t v) { *(ulittle16_t *)p = v; }
+inline void write32le(void *p, uint32_t v) { *(ulittle32_t *)p = v; }
+inline void write64le(void *p, uint64_t v) { *(ulittle64_t *)p = v; }
+inline void write16be(void *p, uint16_t v) { *(ubig16_t *)p = v; }
+inline void write32be(void *p, uint32_t v) { *(ubig32_t *)p = v; }
+inline void write64be(void *p, uint64_t v) { *(ubig64_t *)p = v; }
+} // end namespace endian
} // end namespace support
+} // end namespace llvm
#endif
diff --git a/include/llvm/Support/EndianStream.h b/include/llvm/Support/EndianStream.h
index 94f372f020b4..d44a9b3b7ce8 100644
--- a/include/llvm/Support/EndianStream.h
+++ b/include/llvm/Support/EndianStream.h
@@ -31,6 +31,31 @@ template <endianness endian> struct Writer {
OS.write((const char *)&Val, sizeof(value_type));
}
};
+
+template <>
+template <>
+inline void Writer<little>::write<float>(float Val) {
+ write(FloatToBits(Val));
+}
+
+template <>
+template <>
+inline void Writer<little>::write<double>(double Val) {
+ write(DoubleToBits(Val));
+}
+
+template <>
+template <>
+inline void Writer<big>::write<float>(float Val) {
+ write(FloatToBits(Val));
+}
+
+template <>
+template <>
+inline void Writer<big>::write<double>(double Val) {
+ write(DoubleToBits(Val));
+}
+
} // end namespace endian
} // end namespace support
diff --git a/include/llvm/Support/ErrorOr.h b/include/llvm/Support/ErrorOr.h
index 84763deea0f9..589404f9b4ee 100644
--- a/include/llvm/Support/ErrorOr.h
+++ b/include/llvm/Support/ErrorOr.h
@@ -168,7 +168,7 @@ public:
}
/// \brief Return false if there is an error.
- LLVM_EXPLICIT operator bool() const {
+ explicit operator bool() const {
return !HasError;
}
@@ -281,8 +281,8 @@ template <class T, class E>
typename std::enable_if<std::is_error_code_enum<E>::value ||
std::is_error_condition_enum<E>::value,
bool>::type
-operator==(ErrorOr<T> &Err, E Code) {
- return std::error_code(Err) == Code;
+operator==(const ErrorOr<T> &Err, E Code) {
+ return Err.getError() == Code;
}
} // end namespace llvm
diff --git a/include/llvm/Support/FileOutputBuffer.h b/include/llvm/Support/FileOutputBuffer.h
index 9f02a16e3d65..fd8879c84622 100644
--- a/include/llvm/Support/FileOutputBuffer.h
+++ b/include/llvm/Support/FileOutputBuffer.h
@@ -74,8 +74,8 @@ public:
~FileOutputBuffer();
private:
- FileOutputBuffer(const FileOutputBuffer &) LLVM_DELETED_FUNCTION;
- FileOutputBuffer &operator=(const FileOutputBuffer &) LLVM_DELETED_FUNCTION;
+ FileOutputBuffer(const FileOutputBuffer &) = delete;
+ FileOutputBuffer &operator=(const FileOutputBuffer &) = delete;
FileOutputBuffer(std::unique_ptr<llvm::sys::fs::mapped_file_region> R,
StringRef Path, StringRef TempPath);
diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h
index b60c1b07043b..a736c324f8aa 100644
--- a/include/llvm/Support/FileSystem.h
+++ b/include/llvm/Support/FileSystem.h
@@ -120,7 +120,7 @@ class UniqueID {
uint64_t File;
public:
- UniqueID() {}
+ UniqueID() = default;
UniqueID(uint64_t Device, uint64_t File) : Device(Device), File(File) {}
bool operator==(const UniqueID &Other) const {
return Device == Other.Device && File == Other.File;
@@ -241,6 +241,7 @@ struct file_magic {
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
+ macho_kext_bundle, ///< Mach-O kext bundle file
macho_universal_binary, ///< Mach-O universal binary
coff_object, ///< COFF object file
coff_import_library, ///< COFF import library
@@ -624,9 +625,9 @@ std::error_code getUniqueID(const Twine Path, UniqueID &Result);
/// This class represents a memory mapped file. It is based on
/// boost::iostreams::mapped_file.
class mapped_file_region {
- mapped_file_region() LLVM_DELETED_FUNCTION;
- mapped_file_region(mapped_file_region&) LLVM_DELETED_FUNCTION;
- mapped_file_region &operator =(mapped_file_region&) LLVM_DELETED_FUNCTION;
+ mapped_file_region() = delete;
+ mapped_file_region(mapped_file_region&) = delete;
+ mapped_file_region &operator =(mapped_file_region&) = delete;
public:
enum mapmode {
diff --git a/include/llvm/Support/FileUtilities.h b/include/llvm/Support/FileUtilities.h
index 3f2f176eb469..2ee2c60b9964 100644
--- a/include/llvm/Support/FileUtilities.h
+++ b/include/llvm/Support/FileUtilities.h
@@ -51,7 +51,7 @@ namespace llvm {
~FileRemover() {
if (DeleteIt) {
// Ignore problems deleting the file.
- sys::fs::remove(Filename.str());
+ sys::fs::remove(Filename);
}
}
@@ -61,7 +61,7 @@ namespace llvm {
void setFile(const Twine& filename, bool deleteIt = true) {
if (DeleteIt) {
// Ignore problems deleting the file.
- sys::fs::remove(Filename.str());
+ sys::fs::remove(Filename);
}
Filename.clear();
diff --git a/include/llvm/Support/Format.h b/include/llvm/Support/Format.h
index 5d599e96ec3a..4319a3ba2745 100644
--- a/include/llvm/Support/Format.h
+++ b/include/llvm/Support/Format.h
@@ -23,18 +23,12 @@
#ifndef LLVM_SUPPORT_FORMAT_H
#define LLVM_SUPPORT_FORMAT_H
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataTypes.h"
#include <cassert>
#include <cstdio>
-#ifdef _MSC_VER
-// FIXME: This define is wrong:
-// - _snprintf does not guarantee that trailing null is always added - if
-// there is no space for null, it does not report any error.
-// - According to C++ standard, snprintf should be visible in the 'std'
-// namespace - this define makes this impossible.
-#define snprintf _snprintf
-#endif
+#include <tuple>
namespace llvm {
@@ -43,7 +37,8 @@ namespace llvm {
class format_object_base {
protected:
const char *Fmt;
- ~format_object_base() {} // Disallow polymorphic deletion.
+ ~format_object_base() = default; // Disallow polymorphic deletion.
+ format_object_base(const format_object_base &) = default;
virtual void home(); // Out of line virtual method.
/// Call snprintf() for this object, on the given buffer and size.
@@ -80,101 +75,26 @@ public:
/// printed, this synthesizes the string into a temporary buffer provided and
/// returns whether or not it is big enough.
-template <typename T>
-class format_object1 final : public format_object_base {
- T Val;
-public:
- format_object1(const char *fmt, const T &val)
- : format_object_base(fmt), Val(val) {
- }
-
- int snprint(char *Buffer, unsigned BufferSize) const override {
- return snprintf(Buffer, BufferSize, Fmt, Val);
- }
-};
-
-template <typename T1, typename T2>
-class format_object2 final : public format_object_base {
- T1 Val1;
- T2 Val2;
-public:
- format_object2(const char *fmt, const T1 &val1, const T2 &val2)
- : format_object_base(fmt), Val1(val1), Val2(val2) {
- }
-
- int snprint(char *Buffer, unsigned BufferSize) const override {
- return snprintf(Buffer, BufferSize, Fmt, Val1, Val2);
- }
-};
-
-template <typename T1, typename T2, typename T3>
-class format_object3 final : public format_object_base {
- T1 Val1;
- T2 Val2;
- T3 Val3;
-public:
- format_object3(const char *fmt, const T1 &val1, const T2 &val2,const T3 &val3)
- : format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3) {
- }
-
- int snprint(char *Buffer, unsigned BufferSize) const override {
- return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3);
- }
-};
-
-template <typename T1, typename T2, typename T3, typename T4>
-class format_object4 final : public format_object_base {
- T1 Val1;
- T2 Val2;
- T3 Val3;
- T4 Val4;
-public:
- format_object4(const char *fmt, const T1 &val1, const T2 &val2,
- const T3 &val3, const T4 &val4)
- : format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3), Val4(val4) {
- }
+template <typename... Ts>
+class format_object final : public format_object_base {
+ std::tuple<Ts...> Vals;
- int snprint(char *Buffer, unsigned BufferSize) const override {
- return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3, Val4);
- }
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5>
-class format_object5 final : public format_object_base {
- T1 Val1;
- T2 Val2;
- T3 Val3;
- T4 Val4;
- T5 Val5;
-public:
- format_object5(const char *fmt, const T1 &val1, const T2 &val2,
- const T3 &val3, const T4 &val4, const T5 &val5)
- : format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3), Val4(val4),
- Val5(val5) {
- }
-
- int snprint(char *Buffer, unsigned BufferSize) const override {
- return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3, Val4, Val5);
+ template <std::size_t... Is>
+ int snprint_tuple(char *Buffer, unsigned BufferSize,
+ index_sequence<Is...>) const {
+#ifdef _MSC_VER
+ return _snprintf(Buffer, BufferSize, Fmt, std::get<Is>(Vals)...);
+#else
+ return snprintf(Buffer, BufferSize, Fmt, std::get<Is>(Vals)...);
+#endif
}
-};
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6>
-class format_object6 final : public format_object_base {
- T1 Val1;
- T2 Val2;
- T3 Val3;
- T4 Val4;
- T5 Val5;
- T6 Val6;
public:
- format_object6(const char *Fmt, const T1 &Val1, const T2 &Val2,
- const T3 &Val3, const T4 &Val4, const T5 &Val5, const T6 &Val6)
- : format_object_base(Fmt), Val1(Val1), Val2(Val2), Val3(Val3), Val4(Val4),
- Val5(Val5), Val6(Val6) { }
+ format_object(const char *fmt, const Ts &... vals)
+ : format_object_base(fmt), Vals(vals...) {}
int snprint(char *Buffer, unsigned BufferSize) const override {
- return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3, Val4, Val5, Val6);
+ return snprint_tuple(Buffer, BufferSize, index_sequence_for<Ts...>());
}
};
@@ -187,44 +107,9 @@ public:
/// OS << format("%0.4f", myfloat) << '\n';
/// \endcode
-template <typename T>
-inline format_object1<T> format(const char *Fmt, const T &Val) {
- return format_object1<T>(Fmt, Val);
-}
-
-template <typename T1, typename T2>
-inline format_object2<T1, T2> format(const char *Fmt, const T1 &Val1,
- const T2 &Val2) {
- return format_object2<T1, T2>(Fmt, Val1, Val2);
-}
-
-template <typename T1, typename T2, typename T3>
- inline format_object3<T1, T2, T3> format(const char *Fmt, const T1 &Val1,
- const T2 &Val2, const T3 &Val3) {
- return format_object3<T1, T2, T3>(Fmt, Val1, Val2, Val3);
-}
-
-template <typename T1, typename T2, typename T3, typename T4>
-inline format_object4<T1, T2, T3, T4> format(const char *Fmt, const T1 &Val1,
- const T2 &Val2, const T3 &Val3,
- const T4 &Val4) {
- return format_object4<T1, T2, T3, T4>(Fmt, Val1, Val2, Val3, Val4);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5>
-inline format_object5<T1, T2, T3, T4, T5> format(const char *Fmt,const T1 &Val1,
- const T2 &Val2, const T3 &Val3,
- const T4 &Val4, const T5 &Val5) {
- return format_object5<T1, T2, T3, T4, T5>(Fmt, Val1, Val2, Val3, Val4, Val5);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6>
-inline format_object6<T1, T2, T3, T4, T5, T6>
-format(const char *Fmt, const T1 &Val1, const T2 &Val2, const T3 &Val3,
- const T4 &Val4, const T5 &Val5, const T6 &Val6) {
- return format_object6<T1, T2, T3, T4, T5, T6>(Fmt, Val1, Val2, Val3, Val4,
- Val5, Val6);
+template <typename... Ts>
+inline format_object<Ts...> format(const char *Fmt, const Ts &... Vals) {
+ return format_object<Ts...>(Fmt, Vals...);
}
/// This is a helper class used for left_justify() and right_justify().
@@ -259,21 +144,38 @@ class FormattedNumber {
unsigned Width;
bool Hex;
bool Upper;
+ bool HexPrefix;
friend class raw_ostream;
public:
- FormattedNumber(uint64_t HV, int64_t DV, unsigned W, bool H, bool U)
- : HexValue(HV), DecValue(DV), Width(W), Hex(H), Upper(U) { }
+ FormattedNumber(uint64_t HV, int64_t DV, unsigned W, bool H, bool U,
+ bool Prefix)
+ : HexValue(HV), DecValue(DV), Width(W), Hex(H), Upper(U),
+ HexPrefix(Prefix) {}
};
/// format_hex - Output \p N as a fixed width hexadecimal. If number will not
/// fit in width, full number is still printed. Examples:
-/// OS << format_hex(255, 4) => 0xff
-/// OS << format_hex(255, 4, true) => 0xFF
-/// OS << format_hex(255, 6) => 0x00ff
-/// OS << format_hex(255, 2) => 0xff
-inline FormattedNumber format_hex(uint64_t N, unsigned Width, bool Upper=false) {
+/// OS << format_hex(255, 4) => 0xff
+/// OS << format_hex(255, 4, true) => 0xFF
+/// OS << format_hex(255, 6) => 0x00ff
+/// OS << format_hex(255, 2) => 0xff
+inline FormattedNumber format_hex(uint64_t N, unsigned Width,
+ bool Upper = false) {
+ assert(Width <= 18 && "hex width must be <= 18");
+ return FormattedNumber(N, 0, Width, true, Upper, true);
+}
+
+/// format_hex_no_prefix - Output \p N as a fixed width hexadecimal. Does not
+/// prepend '0x' to the outputted string. If number will not fit in width,
+/// full number is still printed. Examples:
+/// OS << format_hex_no_prefix(255, 4) => ff
+/// OS << format_hex_no_prefix(255, 4, true) => FF
+/// OS << format_hex_no_prefix(255, 6) => 00ff
+/// OS << format_hex_no_prefix(255, 2) => ff
+inline FormattedNumber format_hex_no_prefix(uint64_t N, unsigned Width,
+ bool Upper = false) {
assert(Width <= 18 && "hex width must be <= 18");
- return FormattedNumber(N, 0, Width, true, Upper);
+ return FormattedNumber(N, 0, Width, true, Upper, false);
}
/// format_decimal - Output \p N as a right justified, fixed-width decimal. If
@@ -283,7 +185,7 @@ inline FormattedNumber format_hex(uint64_t N, unsigned Width, bool Upper=false)
/// OS << format_decimal(-1, 3) => " -1"
/// OS << format_decimal(12345, 3) => "12345"
inline FormattedNumber format_decimal(int64_t N, unsigned Width) {
- return FormattedNumber(0, N, Width, false, false);
+ return FormattedNumber(0, N, Width, false, false, false);
}
diff --git a/include/llvm/Support/FormattedStream.h b/include/llvm/Support/FormattedStream.h
index 8137daaff1f8..4a135cd23174 100644
--- a/include/llvm/Support/FormattedStream.h
+++ b/include/llvm/Support/FormattedStream.h
@@ -25,27 +25,11 @@ namespace llvm {
/// boundaries and querying the number of lines written to the stream.
///
class formatted_raw_ostream : public raw_ostream {
-public:
- /// DELETE_STREAM - Tell the destructor to delete the held stream.
- ///
- static const bool DELETE_STREAM = true;
-
- /// PRESERVE_STREAM - Tell the destructor to not delete the held
- /// stream.
- ///
- static const bool PRESERVE_STREAM = false;
-
-private:
/// TheStream - The real stream we output to. We set it to be
/// unbuffered, since we're already doing our own buffering.
///
raw_ostream *TheStream;
- /// DeleteStream - Do we need to delete TheStream in the
- /// destructor?
- ///
- bool DeleteStream;
-
/// Position - The current output column and line of the data that's
/// been flushed and the portion of the buffer that's been
/// scanned. The line and column scheme is zero-based.
@@ -73,6 +57,24 @@ private:
///
void ComputePosition(const char *Ptr, size_t size);
+ void setStream(raw_ostream &Stream) {
+ releaseStream();
+
+ TheStream = &Stream;
+
+ // This formatted_raw_ostream inherits from raw_ostream, so it'll do its
+ // own buffering, and it doesn't need or want TheStream to do another
+ // layer of buffering underneath. Resize the buffer to what TheStream
+ // had been using, and tell TheStream not to do its own buffering.
+ if (size_t BufferSize = TheStream->GetBufferSize())
+ SetBufferSize(BufferSize);
+ else
+ SetUnbuffered();
+ TheStream->SetUnbuffered();
+
+ Scanned = nullptr;
+ }
+
public:
/// formatted_raw_ostream - Open the specified file for
/// writing. If an error occurs, information about the error is
@@ -84,39 +86,19 @@ public:
/// so it doesn't want another layer of buffering to be happening
/// underneath it.
///
- formatted_raw_ostream(raw_ostream &Stream, bool Delete = false)
- : raw_ostream(), TheStream(nullptr), DeleteStream(false), Position(0, 0) {
- setStream(Stream, Delete);
+ formatted_raw_ostream(raw_ostream &Stream)
+ : TheStream(nullptr), Position(0, 0) {
+ setStream(Stream);
}
- explicit formatted_raw_ostream()
- : raw_ostream(), TheStream(nullptr), DeleteStream(false), Position(0, 0) {
+ explicit formatted_raw_ostream() : TheStream(nullptr), Position(0, 0) {
Scanned = nullptr;
}
- ~formatted_raw_ostream() {
+ ~formatted_raw_ostream() override {
flush();
releaseStream();
}
- void setStream(raw_ostream &Stream, bool Delete = false) {
- releaseStream();
-
- TheStream = &Stream;
- DeleteStream = Delete;
-
- // This formatted_raw_ostream inherits from raw_ostream, so it'll do its
- // own buffering, and it doesn't need or want TheStream to do another
- // layer of buffering underneath. Resize the buffer to what TheStream
- // had been using, and tell TheStream not to do its own buffering.
- if (size_t BufferSize = TheStream->GetBufferSize())
- SetBufferSize(BufferSize);
- else
- SetUnbuffered();
- TheStream->SetUnbuffered();
-
- Scanned = nullptr;
- }
-
/// PadToColumn - Align the output to some column number. If the current
/// column is already equal to or more than NewCol, PadToColumn inserts one
/// space.
@@ -151,13 +133,11 @@ public:
private:
void releaseStream() {
- // Delete the stream if needed. Otherwise, transfer the buffer
- // settings from this raw_ostream back to the underlying stream.
+ // Transfer the buffer settings from this raw_ostream back to the underlying
+ // stream.
if (!TheStream)
return;
- if (DeleteStream)
- delete TheStream;
- else if (size_t BufferSize = GetBufferSize())
+ if (size_t BufferSize = GetBufferSize())
TheStream->SetBufferSize(BufferSize);
else
TheStream->SetUnbuffered();
diff --git a/include/llvm/Support/GCOV.h b/include/llvm/Support/GCOV.h
index e378602c7bb3..c2e34bd3eaeb 100644
--- a/include/llvm/Support/GCOV.h
+++ b/include/llvm/Support/GCOV.h
@@ -19,6 +19,7 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/iterator.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
@@ -29,10 +30,7 @@ class GCOVBlock;
class FileInfo;
namespace GCOV {
- enum GCOVVersion {
- V402,
- V404
- };
+enum GCOVVersion { V402, V404 };
} // end GCOV namespace
/// GCOVOptions - A struct for passing gcov options between functions.
@@ -56,7 +54,7 @@ struct GCOVOptions {
class GCOVBuffer {
public:
GCOVBuffer(MemoryBuffer *B) : Buffer(B), Cursor(0) {}
-
+
/// readGCNOFormat - Check GCNO signature is valid at the beginning of buffer.
bool readGCNOFormat() {
StringRef File = Buffer->getBuffer().slice(0, 4);
@@ -81,7 +79,7 @@ public:
/// readGCOVVersion - Read GCOV version.
bool readGCOVVersion(GCOV::GCOVVersion &Version) {
- StringRef VersionStr = Buffer->getBuffer().slice(Cursor, Cursor+4);
+ StringRef VersionStr = Buffer->getBuffer().slice(Cursor, Cursor + 4);
if (VersionStr == "*204") {
Cursor += 4;
Version = GCOV::V402;
@@ -99,10 +97,9 @@ public:
/// readFunctionTag - If cursor points to a function tag then increment the
/// cursor and return true otherwise return false.
bool readFunctionTag() {
- StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
- if (Tag.empty() ||
- Tag[0] != '\0' || Tag[1] != '\0' ||
- Tag[2] != '\0' || Tag[3] != '\1') {
+ StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor + 4);
+ if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\0' ||
+ Tag[3] != '\1') {
return false;
}
Cursor += 4;
@@ -112,10 +109,9 @@ public:
/// readBlockTag - If cursor points to a block tag then increment the
/// cursor and return true otherwise return false.
bool readBlockTag() {
- StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
- if (Tag.empty() ||
- Tag[0] != '\0' || Tag[1] != '\0' ||
- Tag[2] != '\x41' || Tag[3] != '\x01') {
+ StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor + 4);
+ if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\x41' ||
+ Tag[3] != '\x01') {
return false;
}
Cursor += 4;
@@ -125,10 +121,9 @@ public:
/// readEdgeTag - If cursor points to an edge tag then increment the
/// cursor and return true otherwise return false.
bool readEdgeTag() {
- StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
- if (Tag.empty() ||
- Tag[0] != '\0' || Tag[1] != '\0' ||
- Tag[2] != '\x43' || Tag[3] != '\x01') {
+ StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor + 4);
+ if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\x43' ||
+ Tag[3] != '\x01') {
return false;
}
Cursor += 4;
@@ -138,10 +133,9 @@ public:
/// readLineTag - If cursor points to a line tag then increment the
/// cursor and return true otherwise return false.
bool readLineTag() {
- StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
- if (Tag.empty() ||
- Tag[0] != '\0' || Tag[1] != '\0' ||
- Tag[2] != '\x45' || Tag[3] != '\x01') {
+ StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor + 4);
+ if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\x45' ||
+ Tag[3] != '\x01') {
return false;
}
Cursor += 4;
@@ -151,10 +145,9 @@ public:
/// readArcTag - If cursor points to an gcda arc tag then increment the
/// cursor and return true otherwise return false.
bool readArcTag() {
- StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
- if (Tag.empty() ||
- Tag[0] != '\0' || Tag[1] != '\0' ||
- Tag[2] != '\xa1' || Tag[3] != '\1') {
+ StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor + 4);
+ if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\xa1' ||
+ Tag[3] != '\1') {
return false;
}
Cursor += 4;
@@ -164,10 +157,9 @@ public:
/// readObjectTag - If cursor points to an object summary tag then increment
/// the cursor and return true otherwise return false.
bool readObjectTag() {
- StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
- if (Tag.empty() ||
- Tag[0] != '\0' || Tag[1] != '\0' ||
- Tag[2] != '\0' || Tag[3] != '\xa1') {
+ StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor + 4);
+ if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\0' ||
+ Tag[3] != '\xa1') {
return false;
}
Cursor += 4;
@@ -177,10 +169,9 @@ public:
/// readProgramTag - If cursor points to a program summary tag then increment
/// the cursor and return true otherwise return false.
bool readProgramTag() {
- StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
- if (Tag.empty() ||
- Tag[0] != '\0' || Tag[1] != '\0' ||
- Tag[2] != '\0' || Tag[3] != '\xa3') {
+ StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor + 4);
+ if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\0' ||
+ Tag[3] != '\xa3') {
return false;
}
Cursor += 4;
@@ -188,11 +179,11 @@ public:
}
bool readInt(uint32_t &Val) {
- if (Buffer->getBuffer().size() < Cursor+4) {
- errs() << "Unexpected end of memory buffer: " << Cursor+4 << ".\n";
+ if (Buffer->getBuffer().size() < Cursor + 4) {
+ errs() << "Unexpected end of memory buffer: " << Cursor + 4 << ".\n";
return false;
}
- StringRef Str = Buffer->getBuffer().slice(Cursor, Cursor+4);
+ StringRef Str = Buffer->getBuffer().slice(Cursor, Cursor + 4);
Cursor += 4;
Val = *(const uint32_t *)(Str.data());
return true;
@@ -200,7 +191,8 @@ public:
bool readInt64(uint64_t &Val) {
uint32_t Lo, Hi;
- if (!readInt(Lo) || !readInt(Hi)) return false;
+ if (!readInt(Lo) || !readInt(Hi))
+ return false;
Val = ((uint64_t)Hi << 32) | Lo;
return true;
}
@@ -210,19 +202,21 @@ public:
// Keep reading until we find a non-zero length. This emulates gcov's
// behaviour, which appears to do the same.
while (Len == 0)
- if (!readInt(Len)) return false;
+ if (!readInt(Len))
+ return false;
Len *= 4;
- if (Buffer->getBuffer().size() < Cursor+Len) {
- errs() << "Unexpected end of memory buffer: " << Cursor+Len << ".\n";
+ if (Buffer->getBuffer().size() < Cursor + Len) {
+ errs() << "Unexpected end of memory buffer: " << Cursor + Len << ".\n";
return false;
}
- Str = Buffer->getBuffer().slice(Cursor, Cursor+Len).split('\0').first;
+ Str = Buffer->getBuffer().slice(Cursor, Cursor + Len).split('\0').first;
Cursor += Len;
return true;
}
uint64_t getCursor() const { return Cursor; }
- void advanceCursor(uint32_t n) { Cursor += n*4; }
+ void advanceCursor(uint32_t n) { Cursor += n * 4; }
+
private:
MemoryBuffer *Buffer;
uint64_t Cursor;
@@ -232,13 +226,15 @@ private:
/// (.gcno and .gcda).
class GCOVFile {
public:
- GCOVFile() : GCNOInitialized(false), Checksum(0), Functions(), RunCount(0),
- ProgramCount(0) {}
+ GCOVFile()
+ : GCNOInitialized(false), Checksum(0), Functions(), RunCount(0),
+ ProgramCount(0) {}
bool readGCNO(GCOVBuffer &Buffer);
bool readGCDA(GCOVBuffer &Buffer);
uint32_t getChecksum() const { return Checksum; }
void dump() const;
void collectLineCounts(FileInfo &FI);
+
private:
bool GCNOInitialized;
GCOV::GCOVVersion Version;
@@ -260,8 +256,8 @@ struct GCOVEdge {
/// GCOVFunction - Collects function information.
class GCOVFunction {
public:
- typedef SmallVectorImpl<std::unique_ptr<GCOVBlock>>::const_iterator
- BlockIterator;
+ typedef pointee_iterator<SmallVectorImpl<
+ std::unique_ptr<GCOVBlock>>::const_iterator> BlockIterator;
GCOVFunction(GCOVFile &P) : Parent(P), Ident(0), LineNumber(0) {}
bool readGCNO(GCOVBuffer &Buffer, GCOV::GCOVVersion Version);
@@ -274,9 +270,13 @@ public:
BlockIterator block_begin() const { return Blocks.begin(); }
BlockIterator block_end() const { return Blocks.end(); }
+ iterator_range<BlockIterator> blocks() const {
+ return make_range(block_begin(), block_end());
+ }
void dump() const;
void collectLineCounts(FileInfo &FI);
+
private:
GCOVFile &Parent;
uint32_t Ident;
@@ -291,7 +291,7 @@ private:
/// GCOVBlock - Collects block information.
class GCOVBlock {
struct EdgeWeight {
- EdgeWeight(GCOVBlock *D): Dst(D), Count(0) {}
+ EdgeWeight(GCOVBlock *D) : Dst(D), Count(0) {}
GCOVBlock *Dst;
uint64_t Count;
@@ -302,11 +302,13 @@ class GCOVBlock {
return E1->Dst.Number < E2->Dst.Number;
}
};
+
public:
typedef SmallVectorImpl<GCOVEdge *>::const_iterator EdgeIterator;
- GCOVBlock(GCOVFunction &P, uint32_t N) : Parent(P), Number(N), Counter(0),
- DstEdgesAreSorted(true), SrcEdges(), DstEdges(), Lines() {}
+ GCOVBlock(GCOVFunction &P, uint32_t N)
+ : Parent(P), Number(N), Counter(0), DstEdgesAreSorted(true), SrcEdges(),
+ DstEdges(), Lines() {}
~GCOVBlock();
const GCOVFunction &getParent() const { return Parent; }
void addLine(uint32_t N) { Lines.push_back(N); }
@@ -331,11 +333,19 @@ public:
EdgeIterator src_begin() const { return SrcEdges.begin(); }
EdgeIterator src_end() const { return SrcEdges.end(); }
+ iterator_range<EdgeIterator> srcs() const {
+ return make_range(src_begin(), src_end());
+ }
+
EdgeIterator dst_begin() const { return DstEdges.begin(); }
EdgeIterator dst_end() const { return DstEdges.end(); }
+ iterator_range<EdgeIterator> dsts() const {
+ return make_range(dst_begin(), dst_end());
+ }
void dump() const;
void collectLineCounts(FileInfo &FI);
+
private:
GCOVFunction &Parent;
uint32_t Number;
@@ -347,8 +357,10 @@ private:
};
class FileInfo {
- // It is unlikely--but possible--for multiple functions to be on the same line.
- // Therefore this typedef allows LineData.Functions to store multiple functions
+ // It is unlikely--but possible--for multiple functions to be on the same
+ // line.
+ // Therefore this typedef allows LineData.Functions to store multiple
+ // functions
// per instance. This is rare, however, so optimize for the common case.
typedef SmallVector<const GCOVFunction *, 1> FunctionVector;
typedef DenseMap<uint32_t, FunctionVector> FunctionLines;
@@ -363,9 +375,9 @@ class FileInfo {
};
struct GCOVCoverage {
- GCOVCoverage(StringRef Name) :
- Name(Name), LogicalLines(0), LinesExec(0), Branches(0), BranchesExec(0),
- BranchesTaken(0) {}
+ GCOVCoverage(StringRef Name)
+ : Name(Name), LogicalLines(0), LinesExec(0), Branches(0),
+ BranchesExec(0), BranchesTaken(0) {}
StringRef Name;
@@ -376,30 +388,31 @@ class FileInfo {
uint32_t BranchesExec;
uint32_t BranchesTaken;
};
+
public:
- FileInfo(const GCOVOptions &Options) :
- Options(Options), LineInfo(), RunCount(0), ProgramCount(0) {}
+ FileInfo(const GCOVOptions &Options)
+ : Options(Options), LineInfo(), RunCount(0), ProgramCount(0) {}
void addBlockLine(StringRef Filename, uint32_t Line, const GCOVBlock *Block) {
if (Line > LineInfo[Filename].LastLine)
LineInfo[Filename].LastLine = Line;
- LineInfo[Filename].Blocks[Line-1].push_back(Block);
+ LineInfo[Filename].Blocks[Line - 1].push_back(Block);
}
void addFunctionLine(StringRef Filename, uint32_t Line,
const GCOVFunction *Function) {
if (Line > LineInfo[Filename].LastLine)
LineInfo[Filename].LastLine = Line;
- LineInfo[Filename].Functions[Line-1].push_back(Function);
+ LineInfo[Filename].Functions[Line - 1].push_back(Function);
}
void setRunCount(uint32_t Runs) { RunCount = Runs; }
void setProgramCount(uint32_t Programs) { ProgramCount = Programs; }
- void print(StringRef MainFilename, StringRef GCNOFile, StringRef GCDAFile);
+ void print(raw_ostream &OS, StringRef MainFilename, StringRef GCNOFile,
+ StringRef GCDAFile);
private:
std::string getCoveragePath(StringRef Filename, StringRef MainFilename);
std::unique_ptr<raw_ostream> openCoveragePath(StringRef CoveragePath);
- void printFunctionSummary(raw_ostream &OS,
- const FunctionVector &Funcs) const;
+ void printFunctionSummary(raw_ostream &OS, const FunctionVector &Funcs) const;
void printBlockInfo(raw_ostream &OS, const GCOVBlock &Block,
uint32_t LineIndex, uint32_t &BlockNo) const;
void printBranchInfo(raw_ostream &OS, const GCOVBlock &Block,
@@ -407,23 +420,21 @@ private:
void printUncondBranchInfo(raw_ostream &OS, uint32_t &EdgeNo,
uint64_t Count) const;
- void printCoverage(const GCOVCoverage &Coverage) const;
- void printFuncCoverage() const;
- void printFileCoverage() const;
+ void printCoverage(raw_ostream &OS, const GCOVCoverage &Coverage) const;
+ void printFuncCoverage(raw_ostream &OS) const;
+ void printFileCoverage(raw_ostream &OS) const;
const GCOVOptions &Options;
StringMap<LineData> LineInfo;
uint32_t RunCount;
uint32_t ProgramCount;
- typedef SmallVector<std::pair<std::string, GCOVCoverage>, 4>
- FileCoverageList;
+ typedef SmallVector<std::pair<std::string, GCOVCoverage>, 4> FileCoverageList;
typedef MapVector<const GCOVFunction *, GCOVCoverage> FuncCoverageMap;
FileCoverageList FileCoverages;
FuncCoverageMap FuncCoverages;
};
-
}
#endif
diff --git a/include/llvm/Support/GenericDomTree.h b/include/llvm/Support/GenericDomTree.h
index fde56135a962..63678bb98bb1 100644
--- a/include/llvm/Support/GenericDomTree.h
+++ b/include/llvm/Support/GenericDomTree.h
@@ -21,6 +21,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Compiler.h"
@@ -93,8 +94,9 @@ public:
DomTreeNodeBase(NodeT *BB, DomTreeNodeBase<NodeT> *iDom)
: TheBB(BB), IDom(iDom), DFSNumIn(-1), DFSNumOut(-1) {}
- DomTreeNodeBase<NodeT> *addChild(DomTreeNodeBase<NodeT> *C) {
- Children.push_back(C);
+ std::unique_ptr<DomTreeNodeBase<NodeT>>
+ addChild(std::unique_ptr<DomTreeNodeBase<NodeT>> C) {
+ Children.push_back(C.get());
return C;
}
@@ -182,8 +184,8 @@ void Calculate(DominatorTreeBase<typename GraphTraits<N>::NodeType> &DT,
/// This class is a generic template over graph nodes. It is instantiated for
/// various graphs in the LLVM IR or in the code generator.
template <class NodeT> class DominatorTreeBase : public DominatorBase<NodeT> {
- DominatorTreeBase(const DominatorTreeBase &) LLVM_DELETED_FUNCTION;
- DominatorTreeBase &operator=(const DominatorTreeBase &) LLVM_DELETED_FUNCTION;
+ DominatorTreeBase(const DominatorTreeBase &) = delete;
+ DominatorTreeBase &operator=(const DominatorTreeBase &) = delete;
bool dominatedBySlowTreeWalk(const DomTreeNodeBase<NodeT> *A,
const DomTreeNodeBase<NodeT> *B) const {
@@ -210,7 +212,8 @@ template <class NodeT> class DominatorTreeBase : public DominatorBase<NodeT> {
}
protected:
- typedef DenseMap<NodeT *, DomTreeNodeBase<NodeT> *> DomTreeNodeMapType;
+ typedef DenseMap<NodeT *, std::unique_ptr<DomTreeNodeBase<NodeT>>>
+ DomTreeNodeMapType;
DomTreeNodeMapType DomTreeNodes;
DomTreeNodeBase<NodeT> *RootNode;
@@ -235,15 +238,13 @@ protected:
DenseMap<NodeT *, InfoRec> Info;
void reset() {
- for (typename DomTreeNodeMapType::iterator I = this->DomTreeNodes.begin(),
- E = DomTreeNodes.end();
- I != E; ++I)
- delete I->second;
DomTreeNodes.clear();
IDoms.clear();
this->Roots.clear();
Vertex.clear();
RootNode = nullptr;
+ DFSInfoValid = false;
+ SlowQueries = 0;
}
// NewBB is split and now it has one successor. Update dominator tree to
@@ -314,7 +315,6 @@ protected:
public:
explicit DominatorTreeBase(bool isPostDom)
: DominatorBase<NodeT>(isPostDom), DFSInfoValid(false), SlowQueries(0) {}
- ~DominatorTreeBase() { reset(); }
DominatorTreeBase(DominatorTreeBase &&Arg)
: DominatorBase<NodeT>(
@@ -358,10 +358,10 @@ public:
if (OI == OtherDomTreeNodes.end())
return true;
- DomTreeNodeBase<NodeT> *MyNd = I->second;
- DomTreeNodeBase<NodeT> *OtherNd = OI->second;
+ DomTreeNodeBase<NodeT> &MyNd = *I->second;
+ DomTreeNodeBase<NodeT> &OtherNd = *OI->second;
- if (MyNd->compare(OtherNd))
+ if (MyNd.compare(&OtherNd))
return true;
}
@@ -374,7 +374,10 @@ public:
/// block. This is the same as using operator[] on this class.
///
DomTreeNodeBase<NodeT> *getNode(NodeT *BB) const {
- return DomTreeNodes.lookup(BB);
+ auto I = DomTreeNodes.find(BB);
+ if (I != DomTreeNodes.end())
+ return I->second.get();
+ return nullptr;
}
DomTreeNodeBase<NodeT> *operator[](NodeT *BB) const { return getNode(BB); }
@@ -555,8 +558,8 @@ public:
DomTreeNodeBase<NodeT> *IDomNode = getNode(DomBB);
assert(IDomNode && "Not immediate dominator specified for block!");
DFSInfoValid = false;
- return DomTreeNodes[BB] =
- IDomNode->addChild(new DomTreeNodeBase<NodeT>(BB, IDomNode));
+ return (DomTreeNodes[BB] = IDomNode->addChild(
+ llvm::make_unique<DomTreeNodeBase<NodeT>>(BB, IDomNode))).get();
}
/// changeImmediateDominator - This method is used to update the dominator
@@ -593,15 +596,6 @@ public:
}
DomTreeNodes.erase(BB);
- delete Node;
- }
-
- /// removeNode - Removes a node from the dominator tree. Block must not
- /// dominate any other blocks. Invalidates any node pointing to removed
- /// block.
- void removeNode(NodeT *BB) {
- assert(getNode(BB) && "Removing node that isn't in dominator tree.");
- DomTreeNodes.erase(BB);
}
/// splitBlock - BB is split and now it has one successor. Update dominator
@@ -645,9 +639,38 @@ protected:
friend void
Calculate(DominatorTreeBase<typename GraphTraits<N>::NodeType> &DT, FuncT &F);
+
+ DomTreeNodeBase<NodeT> *getNodeForBlock(NodeT *BB) {
+ if (DomTreeNodeBase<NodeT> *Node = getNode(BB))
+ return Node;
+
+ // Haven't calculated this node yet? Get or calculate the node for the
+ // immediate dominator.
+ NodeT *IDom = getIDom(BB);
+
+ assert(IDom || this->DomTreeNodes[nullptr]);
+ DomTreeNodeBase<NodeT> *IDomNode = getNodeForBlock(IDom);
+
+ // Add a new tree node for this NodeT, and link it as a child of
+ // IDomNode
+ return (this->DomTreeNodes[BB] = IDomNode->addChild(
+ llvm::make_unique<DomTreeNodeBase<NodeT>>(BB, IDomNode))).get();
+ }
+
+ NodeT *getIDom(NodeT *BB) const { return IDoms.lookup(BB); }
+
+ void addRoot(NodeT *BB) { this->Roots.push_back(BB); }
+
+public:
/// updateDFSNumbers - Assign In and Out numbers to the nodes while walking
/// dominator tree in dfs order.
void updateDFSNumbers() const {
+
+ if (DFSInfoValid) {
+ SlowQueries = 0;
+ return;
+ }
+
unsigned DFSNum = 0;
SmallVector<std::pair<const DomTreeNodeBase<NodeT> *,
@@ -690,28 +713,6 @@ protected:
DFSInfoValid = true;
}
- DomTreeNodeBase<NodeT> *getNodeForBlock(NodeT *BB) {
- if (DomTreeNodeBase<NodeT> *Node = getNode(BB))
- return Node;
-
- // Haven't calculated this node yet? Get or calculate the node for the
- // immediate dominator.
- NodeT *IDom = getIDom(BB);
-
- assert(IDom || this->DomTreeNodes[nullptr]);
- DomTreeNodeBase<NodeT> *IDomNode = getNodeForBlock(IDom);
-
- // Add a new tree node for this NodeT, and link it as a child of
- // IDomNode
- DomTreeNodeBase<NodeT> *C = new DomTreeNodeBase<NodeT>(BB, IDomNode);
- return this->DomTreeNodes[BB] = IDomNode->addChild(C);
- }
-
- NodeT *getIDom(NodeT *BB) const { return IDoms.lookup(BB); }
-
- void addRoot(NodeT *BB) { this->Roots.push_back(BB); }
-
-public:
/// recalculate - compute a dominator tree for the given function
template <class FT> void recalculate(FT &F) {
typedef GraphTraits<FT *> TraitsTy;
diff --git a/include/llvm/Support/GenericDomTreeConstruction.h b/include/llvm/Support/GenericDomTreeConstruction.h
index ad4f8a9f429a..7c065f939256 100644
--- a/include/llvm/Support/GenericDomTreeConstruction.h
+++ b/include/llvm/Support/GenericDomTreeConstruction.h
@@ -251,15 +251,18 @@ void Calculate(DominatorTreeBase<typename GraphTraits<NodeT>::NodeType>& DT,
// an infinite loop.
typename GraphT::NodeType* Root = !MultipleRoots ? DT.Roots[0] : nullptr;
- DT.DomTreeNodes[Root] = DT.RootNode =
- new DomTreeNodeBase<typename GraphT::NodeType>(Root, nullptr);
+ DT.RootNode =
+ (DT.DomTreeNodes[Root] =
+ llvm::make_unique<DomTreeNodeBase<typename GraphT::NodeType>>(
+ Root, nullptr)).get();
// Loop over all of the reachable blocks in the function...
for (unsigned i = 2; i <= N; ++i) {
typename GraphT::NodeType* W = DT.Vertex[i];
- DomTreeNodeBase<typename GraphT::NodeType> *BBNode = DT.DomTreeNodes[W];
- if (BBNode) continue; // Haven't calculated this node yet?
+ // Don't replace this with 'count', the insertion side effect is important
+ if (DT.DomTreeNodes[W])
+ continue; // Haven't calculated this node yet?
typename GraphT::NodeType* ImmDom = DT.getIDom(W);
@@ -271,15 +274,16 @@ void Calculate(DominatorTreeBase<typename GraphTraits<NodeT>::NodeType>& DT,
// Add a new tree node for this BasicBlock, and link it as a child of
// IDomNode
- DomTreeNodeBase<typename GraphT::NodeType> *C =
- new DomTreeNodeBase<typename GraphT::NodeType>(W, IDomNode);
- DT.DomTreeNodes[W] = IDomNode->addChild(C);
+ DT.DomTreeNodes[W] = IDomNode->addChild(
+ llvm::make_unique<DomTreeNodeBase<typename GraphT::NodeType>>(
+ W, IDomNode));
}
// Free temporary memory used to construct idom's
DT.IDoms.clear();
DT.Info.clear();
- std::vector<typename GraphT::NodeType*>().swap(DT.Vertex);
+ DT.Vertex.clear();
+ DT.Vertex.shrink_to_fit();
DT.updateDFSNumbers();
}
diff --git a/include/llvm/Support/GraphWriter.h b/include/llvm/Support/GraphWriter.h
index 2f02aa7a1c19..7d1c273c988d 100644
--- a/include/llvm/Support/GraphWriter.h
+++ b/include/llvm/Support/GraphWriter.h
@@ -24,10 +24,9 @@
#define LLVM_SUPPORT_GRAPHWRITER_H
#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/Twine.h"
#include "llvm/Support/DOTGraphTraits.h"
-#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
-#include <cassert>
#include <vector>
namespace llvm {
diff --git a/include/llvm/Support/LockFileManager.h b/include/llvm/Support/LockFileManager.h
index 61c65dabae3c..8e88d4279bd8 100644
--- a/include/llvm/Support/LockFileManager.h
+++ b/include/llvm/Support/LockFileManager.h
@@ -57,8 +57,8 @@ private:
Optional<std::pair<std::string, int> > Owner;
Optional<std::error_code> Error;
- LockFileManager(const LockFileManager &) LLVM_DELETED_FUNCTION;
- LockFileManager &operator=(const LockFileManager &) LLVM_DELETED_FUNCTION;
+ LockFileManager(const LockFileManager &) = delete;
+ LockFileManager &operator=(const LockFileManager &) = delete;
static Optional<std::pair<std::string, int> >
readLockFile(StringRef LockFileName);
@@ -77,6 +77,10 @@ public:
/// \brief For a shared lock, wait until the owner releases the lock.
WaitForUnlockResult waitForUnlock();
+
+ /// \brief Remove the lock file. This may delete a different lock file than
+ /// the one previously read if there is a race.
+ std::error_code unsafeRemoveLockFile();
};
} // end namespace llvm
diff --git a/include/llvm/Support/MathExtras.h b/include/llvm/Support/MathExtras.h
index 698363614ac5..e3166165a483 100644
--- a/include/llvm/Support/MathExtras.h
+++ b/include/llvm/Support/MathExtras.h
@@ -24,6 +24,10 @@
#include <intrin.h>
#endif
+#ifdef __ANDROID_NDK__
+#include <android/api-level.h>
+#endif
+
namespace llvm {
/// \brief The behavior an operation has on an input of 0.
enum ZeroBehavior {
@@ -35,78 +39,66 @@ enum ZeroBehavior {
ZB_Width
};
-/// \brief Count number of 0's from the least significant bit to the most
-/// stopping at the first 1.
-///
-/// Only unsigned integral types are allowed.
-///
-/// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are
-/// valid arguments.
-template <typename T>
-typename std::enable_if<std::numeric_limits<T>::is_integer &&
- !std::numeric_limits<T>::is_signed, std::size_t>::type
-countTrailingZeros(T Val, ZeroBehavior ZB = ZB_Width) {
- (void)ZB;
-
- if (!Val)
- return std::numeric_limits<T>::digits;
- if (Val & 0x1)
- return 0;
-
- // Bisection method.
- std::size_t ZeroBits = 0;
- T Shift = std::numeric_limits<T>::digits >> 1;
- T Mask = std::numeric_limits<T>::max() >> Shift;
- while (Shift) {
- if ((Val & Mask) == 0) {
- Val >>= Shift;
- ZeroBits |= Shift;
+namespace detail {
+template <typename T, std::size_t SizeOfT> struct TrailingZerosCounter {
+ static std::size_t count(T Val, ZeroBehavior) {
+ if (!Val)
+ return std::numeric_limits<T>::digits;
+ if (Val & 0x1)
+ return 0;
+
+ // Bisection method.
+ std::size_t ZeroBits = 0;
+ T Shift = std::numeric_limits<T>::digits >> 1;
+ T Mask = std::numeric_limits<T>::max() >> Shift;
+ while (Shift) {
+ if ((Val & Mask) == 0) {
+ Val >>= Shift;
+ ZeroBits |= Shift;
+ }
+ Shift >>= 1;
+ Mask >>= Shift;
}
- Shift >>= 1;
- Mask >>= Shift;
+ return ZeroBits;
}
- return ZeroBits;
-}
-
-// Disable signed.
-template <typename T>
-typename std::enable_if<std::numeric_limits<T>::is_integer &&
- std::numeric_limits<T>::is_signed, std::size_t>::type
-countTrailingZeros(T, ZeroBehavior = ZB_Width) LLVM_DELETED_FUNCTION;
+};
#if __GNUC__ >= 4 || _MSC_VER
-template <>
-inline std::size_t countTrailingZeros<uint32_t>(uint32_t Val, ZeroBehavior ZB) {
- if (ZB != ZB_Undefined && Val == 0)
- return 32;
+template <typename T> struct TrailingZerosCounter<T, 4> {
+ static std::size_t count(T Val, ZeroBehavior ZB) {
+ if (ZB != ZB_Undefined && Val == 0)
+ return 32;
#if __has_builtin(__builtin_ctz) || LLVM_GNUC_PREREQ(4, 0, 0)
- return __builtin_ctz(Val);
+ return __builtin_ctz(Val);
#elif _MSC_VER
- unsigned long Index;
- _BitScanForward(&Index, Val);
- return Index;
+ unsigned long Index;
+ _BitScanForward(&Index, Val);
+ return Index;
#endif
-}
+ }
+};
#if !defined(_MSC_VER) || defined(_M_X64)
-template <>
-inline std::size_t countTrailingZeros<uint64_t>(uint64_t Val, ZeroBehavior ZB) {
- if (ZB != ZB_Undefined && Val == 0)
- return 64;
+template <typename T> struct TrailingZerosCounter<T, 8> {
+ static std::size_t count(T Val, ZeroBehavior ZB) {
+ if (ZB != ZB_Undefined && Val == 0)
+ return 64;
#if __has_builtin(__builtin_ctzll) || LLVM_GNUC_PREREQ(4, 0, 0)
- return __builtin_ctzll(Val);
+ return __builtin_ctzll(Val);
#elif _MSC_VER
- unsigned long Index;
- _BitScanForward64(&Index, Val);
- return Index;
+ unsigned long Index;
+ _BitScanForward64(&Index, Val);
+ return Index;
#endif
-}
+ }
+};
#endif
#endif
+} // namespace detail
-/// \brief Count number of 0's from the most significant bit to the least
+/// \brief Count number of 0's from the least significant bit to the most
/// stopping at the first 1.
///
/// Only unsigned integral types are allowed.
@@ -114,63 +106,81 @@ inline std::size_t countTrailingZeros<uint64_t>(uint64_t Val, ZeroBehavior ZB) {
/// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are
/// valid arguments.
template <typename T>
-typename std::enable_if<std::numeric_limits<T>::is_integer &&
- !std::numeric_limits<T>::is_signed, std::size_t>::type
-countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) {
- (void)ZB;
-
- if (!Val)
- return std::numeric_limits<T>::digits;
-
- // Bisection method.
- std::size_t ZeroBits = 0;
- for (T Shift = std::numeric_limits<T>::digits >> 1; Shift; Shift >>= 1) {
- T Tmp = Val >> Shift;
- if (Tmp)
- Val = Tmp;
- else
- ZeroBits |= Shift;
+std::size_t countTrailingZeros(T Val, ZeroBehavior ZB = ZB_Width) {
+ static_assert(std::numeric_limits<T>::is_integer &&
+ !std::numeric_limits<T>::is_signed,
+ "Only unsigned integral types are allowed.");
+ return detail::TrailingZerosCounter<T, sizeof(T)>::count(Val, ZB);
+}
+
+namespace detail {
+template <typename T, std::size_t SizeOfT> struct LeadingZerosCounter {
+ static std::size_t count(T Val, ZeroBehavior) {
+ if (!Val)
+ return std::numeric_limits<T>::digits;
+
+ // Bisection method.
+ std::size_t ZeroBits = 0;
+ for (T Shift = std::numeric_limits<T>::digits >> 1; Shift; Shift >>= 1) {
+ T Tmp = Val >> Shift;
+ if (Tmp)
+ Val = Tmp;
+ else
+ ZeroBits |= Shift;
+ }
+ return ZeroBits;
}
- return ZeroBits;
-}
-
-// Disable signed.
-template <typename T>
-typename std::enable_if<std::numeric_limits<T>::is_integer &&
- std::numeric_limits<T>::is_signed, std::size_t>::type
-countLeadingZeros(T, ZeroBehavior = ZB_Width) LLVM_DELETED_FUNCTION;
+};
#if __GNUC__ >= 4 || _MSC_VER
-template <>
-inline std::size_t countLeadingZeros<uint32_t>(uint32_t Val, ZeroBehavior ZB) {
- if (ZB != ZB_Undefined && Val == 0)
- return 32;
+template <typename T> struct LeadingZerosCounter<T, 4> {
+ static std::size_t count(T Val, ZeroBehavior ZB) {
+ if (ZB != ZB_Undefined && Val == 0)
+ return 32;
#if __has_builtin(__builtin_clz) || LLVM_GNUC_PREREQ(4, 0, 0)
- return __builtin_clz(Val);
+ return __builtin_clz(Val);
#elif _MSC_VER
- unsigned long Index;
- _BitScanReverse(&Index, Val);
- return Index ^ 31;
+ unsigned long Index;
+ _BitScanReverse(&Index, Val);
+ return Index ^ 31;
#endif
-}
+ }
+};
#if !defined(_MSC_VER) || defined(_M_X64)
-template <>
-inline std::size_t countLeadingZeros<uint64_t>(uint64_t Val, ZeroBehavior ZB) {
- if (ZB != ZB_Undefined && Val == 0)
- return 64;
+template <typename T> struct LeadingZerosCounter<T, 8> {
+ static std::size_t count(T Val, ZeroBehavior ZB) {
+ if (ZB != ZB_Undefined && Val == 0)
+ return 64;
#if __has_builtin(__builtin_clzll) || LLVM_GNUC_PREREQ(4, 0, 0)
- return __builtin_clzll(Val);
+ return __builtin_clzll(Val);
#elif _MSC_VER
- unsigned long Index;
- _BitScanReverse64(&Index, Val);
- return Index ^ 63;
+ unsigned long Index;
+ _BitScanReverse64(&Index, Val);
+ return Index ^ 63;
#endif
-}
+ }
+};
#endif
#endif
+} // namespace detail
+
+/// \brief Count number of 0's from the most significant bit to the least
+/// stopping at the first 1.
+///
+/// Only unsigned integral types are allowed.
+///
+/// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are
+/// valid arguments.
+template <typename T>
+std::size_t countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) {
+ static_assert(std::numeric_limits<T>::is_integer &&
+ !std::numeric_limits<T>::is_signed,
+ "Only unsigned integral types are allowed.");
+ return detail::LeadingZerosCounter<T, sizeof(T)>::count(Val, ZB);
+}
/// \brief Get the index of the first set bit starting from the least
/// significant bit.
@@ -179,22 +189,13 @@ inline std::size_t countLeadingZeros<uint64_t>(uint64_t Val, ZeroBehavior ZB) {
///
/// \param ZB the behavior on an input of 0. Only ZB_Max and ZB_Undefined are
/// valid arguments.
-template <typename T>
-typename std::enable_if<std::numeric_limits<T>::is_integer &&
- !std::numeric_limits<T>::is_signed, T>::type
-findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) {
+template <typename T> T findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) {
if (ZB == ZB_Max && Val == 0)
return std::numeric_limits<T>::max();
return countTrailingZeros(Val, ZB_Undefined);
}
-// Disable signed.
-template <typename T>
-typename std::enable_if<std::numeric_limits<T>::is_integer &&
- std::numeric_limits<T>::is_signed, T>::type
-findFirstSet(T, ZeroBehavior = ZB_Max) LLVM_DELETED_FUNCTION;
-
/// \brief Get the index of the last set bit starting from the least
/// significant bit.
///
@@ -202,10 +203,7 @@ findFirstSet(T, ZeroBehavior = ZB_Max) LLVM_DELETED_FUNCTION;
///
/// \param ZB the behavior on an input of 0. Only ZB_Max and ZB_Undefined are
/// valid arguments.
-template <typename T>
-typename std::enable_if<std::numeric_limits<T>::is_integer &&
- !std::numeric_limits<T>::is_signed, T>::type
-findLastSet(T Val, ZeroBehavior ZB = ZB_Max) {
+template <typename T> T findLastSet(T Val, ZeroBehavior ZB = ZB_Max) {
if (ZB == ZB_Max && Val == 0)
return std::numeric_limits<T>::max();
@@ -215,12 +213,6 @@ findLastSet(T Val, ZeroBehavior ZB = ZB_Max) {
(std::numeric_limits<T>::digits - 1);
}
-// Disable signed.
-template <typename T>
-typename std::enable_if<std::numeric_limits<T>::is_integer &&
- std::numeric_limits<T>::is_signed, T>::type
-findLastSet(T, ZeroBehavior = ZB_Max) LLVM_DELETED_FUNCTION;
-
/// \brief Macro compressed bit reversal table for 256 bits.
///
/// http://graphics.stanford.edu/~seander/bithacks.html#BitReverseTable
@@ -330,31 +322,31 @@ inline bool isIntN(unsigned N, int64_t x) {
return N >= 64 || (-(INT64_C(1)<<(N-1)) <= x && x < (INT64_C(1)<<(N-1)));
}
-/// isMask_32 - This function returns true if the argument is a sequence of ones
-/// starting at the least significant bit with the remainder zero (32 bit
-/// version). Ex. isMask_32(0x0000FFFFU) == true.
+/// isMask_32 - This function returns true if the argument is a non-empty
+/// sequence of ones starting at the least significant bit with the remainder
+/// zero (32 bit version). Ex. isMask_32(0x0000FFFFU) == true.
inline bool isMask_32(uint32_t Value) {
return Value && ((Value + 1) & Value) == 0;
}
-/// isMask_64 - This function returns true if the argument is a sequence of ones
-/// starting at the least significant bit with the remainder zero (64 bit
-/// version).
+/// isMask_64 - This function returns true if the argument is a non-empty
+/// sequence of ones starting at the least significant bit with the remainder
+/// zero (64 bit version).
inline bool isMask_64(uint64_t Value) {
return Value && ((Value + 1) & Value) == 0;
}
/// isShiftedMask_32 - This function returns true if the argument contains a
-/// sequence of ones with the remainder zero (32 bit version.)
+/// non-empty sequence of ones with the remainder zero (32 bit version.)
/// Ex. isShiftedMask_32(0x0000FF00U) == true.
inline bool isShiftedMask_32(uint32_t Value) {
- return isMask_32((Value - 1) | Value);
+ return Value && isMask_32((Value - 1) | Value);
}
/// isShiftedMask_64 - This function returns true if the argument contains a
-/// sequence of ones with the remainder zero (64 bit version.)
+/// non-empty sequence of ones with the remainder zero (64 bit version.)
inline bool isShiftedMask_64(uint64_t Value) {
- return isMask_64((Value - 1) | Value);
+ return Value && isMask_64((Value - 1) | Value);
}
/// isPowerOf2_32 - This function returns true if the argument is a power of
@@ -387,61 +379,86 @@ inline uint64_t ByteSwap_64(uint64_t Value) {
return sys::SwapByteOrder_64(Value);
}
-/// CountLeadingOnes_32 - this function performs the operation of
-/// counting the number of ones from the most significant bit to the first zero
-/// bit. Ex. CountLeadingOnes_32(0xFF0FFF00) == 8.
-/// Returns 32 if the word is all ones.
-inline unsigned CountLeadingOnes_32(uint32_t Value) {
- return countLeadingZeros(~Value);
-}
-
-/// CountLeadingOnes_64 - This function performs the operation
-/// of counting the number of ones from the most significant bit to the first
-/// zero bit (64 bit edition.)
-/// Returns 64 if the word is all ones.
-inline unsigned CountLeadingOnes_64(uint64_t Value) {
- return countLeadingZeros(~Value);
-}
-
-/// CountTrailingOnes_32 - this function performs the operation of
-/// counting the number of ones from the least significant bit to the first zero
-/// bit. Ex. CountTrailingOnes_32(0x00FF00FF) == 8.
-/// Returns 32 if the word is all ones.
-inline unsigned CountTrailingOnes_32(uint32_t Value) {
- return countTrailingZeros(~Value);
+/// \brief Count the number of ones from the most significant bit to the first
+/// zero bit.
+///
+/// Ex. CountLeadingOnes(0xFF0FFF00) == 8.
+/// Only unsigned integral types are allowed.
+///
+/// \param ZB the behavior on an input of all ones. Only ZB_Width and
+/// ZB_Undefined are valid arguments.
+template <typename T>
+std::size_t countLeadingOnes(T Value, ZeroBehavior ZB = ZB_Width) {
+ static_assert(std::numeric_limits<T>::is_integer &&
+ !std::numeric_limits<T>::is_signed,
+ "Only unsigned integral types are allowed.");
+ return countLeadingZeros(~Value, ZB);
}
-/// CountTrailingOnes_64 - This function performs the operation
-/// of counting the number of ones from the least significant bit to the first
-/// zero bit (64 bit edition.)
-/// Returns 64 if the word is all ones.
-inline unsigned CountTrailingOnes_64(uint64_t Value) {
- return countTrailingZeros(~Value);
-}
+/// \brief Count the number of ones from the least significant bit to the first
+/// zero bit.
+///
+/// Ex. countTrailingOnes(0x00FF00FF) == 8.
+/// Only unsigned integral types are allowed.
+///
+/// \param ZB the behavior on an input of all ones. Only ZB_Width and
+/// ZB_Undefined are valid arguments.
+template <typename T>
+std::size_t countTrailingOnes(T Value, ZeroBehavior ZB = ZB_Width) {
+ static_assert(std::numeric_limits<T>::is_integer &&
+ !std::numeric_limits<T>::is_signed,
+ "Only unsigned integral types are allowed.");
+ return countTrailingZeros(~Value, ZB);
+}
+
+namespace detail {
+template <typename T, std::size_t SizeOfT> struct PopulationCounter {
+ static unsigned count(T Value) {
+ // Generic version, forward to 32 bits.
+ static_assert(SizeOfT <= 4, "Not implemented!");
+#if __GNUC__ >= 4
+ return __builtin_popcount(Value);
+#else
+ uint32_t v = Value;
+ v = v - ((v >> 1) & 0x55555555);
+ v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
+ return ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24;
+#endif
+ }
+};
-/// CountPopulation_32 - this function counts the number of set bits in a value.
-/// Ex. CountPopulation(0xF000F000) = 8
-/// Returns 0 if the word is zero.
-inline unsigned CountPopulation_32(uint32_t Value) {
+template <typename T> struct PopulationCounter<T, 8> {
+ static unsigned count(T Value) {
#if __GNUC__ >= 4
- return __builtin_popcount(Value);
+ return __builtin_popcountll(Value);
#else
- uint32_t v = Value - ((Value >> 1) & 0x55555555);
- v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
- return ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24;
+ uint64_t v = Value;
+ v = v - ((v >> 1) & 0x5555555555555555ULL);
+ v = (v & 0x3333333333333333ULL) + ((v >> 2) & 0x3333333333333333ULL);
+ v = (v + (v >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
+ return unsigned((uint64_t)(v * 0x0101010101010101ULL) >> 56);
#endif
+ }
+};
+} // namespace detail
+
+/// \brief Count the number of set bits in a value.
+/// Ex. countPopulation(0xF000F000) = 8
+/// Returns 0 if the word is zero.
+template <typename T>
+inline unsigned countPopulation(T Value) {
+ static_assert(std::numeric_limits<T>::is_integer &&
+ !std::numeric_limits<T>::is_signed,
+ "Only unsigned integral types are allowed.");
+ return detail::PopulationCounter<T, sizeof(T)>::count(Value);
}
-/// CountPopulation_64 - this function counts the number of set bits in a value,
-/// (64 bit edition.)
-inline unsigned CountPopulation_64(uint64_t Value) {
-#if __GNUC__ >= 4
- return __builtin_popcountll(Value);
+/// Log2 - This function returns the log base 2 of the specified value
+inline double Log2(double Value) {
+#if defined(__ANDROID_API__) && __ANDROID_API__ < 18
+ return __builtin_log(Value) / __builtin_log(2.0);
#else
- uint64_t v = Value - ((Value >> 1) & 0x5555555555555555ULL);
- v = (v & 0x3333333333333333ULL) + ((v >> 2) & 0x3333333333333333ULL);
- v = (v + (v >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
- return unsigned((uint64_t)(v * 0x0101010101010101ULL) >> 56);
+ return log2(Value);
#endif
}
@@ -530,14 +547,6 @@ inline uint32_t FloatToBits(float Float) {
return T.I;
}
-/// Platform-independent wrappers for the C99 isnan() function.
-int IsNAN(float f);
-int IsNAN(double d);
-
-/// Platform-independent wrappers for the C99 isinf() function.
-int IsInf(float f);
-int IsInf(double d);
-
/// MinAlign - A and B are either alignments or offsets. Return the minimum
/// alignment that may be assumed after adding the two together.
inline uint64_t MinAlign(uint64_t A, uint64_t B) {
@@ -608,13 +617,6 @@ inline uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align) {
return RoundUpToAlignment(Value, Align) - Value;
}
-/// abs64 - absolute value of a 64-bit int. Not all environments support
-/// "abs" on whatever their name for the 64-bit int type is. The absolute
-/// value of the largest negative number is undefined, as with "abs".
-inline int64_t abs64(int64_t x) {
- return (x < 0) ? -x : x;
-}
-
/// SignExtend32 - Sign extend B-bit number x to 32-bit int.
/// Usage int32_t r = SignExtend32<5>(x);
template <unsigned B> inline int32_t SignExtend32(uint32_t x) {
diff --git a/include/llvm/Support/MemoryBuffer.h b/include/llvm/Support/MemoryBuffer.h
index e2f8d7e90fef..35a7bdb004a9 100644
--- a/include/llvm/Support/MemoryBuffer.h
+++ b/include/llvm/Support/MemoryBuffer.h
@@ -17,11 +17,9 @@
#include "llvm-c/Support.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/CBindingWrapping.h"
-#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorOr.h"
#include <memory>
-#include <system_error>
namespace llvm {
class MemoryBufferRef;
@@ -40,8 +38,8 @@ class MemoryBuffer {
const char *BufferStart; // Start of the buffer.
const char *BufferEnd; // End of the buffer.
- MemoryBuffer(const MemoryBuffer &) LLVM_DELETED_FUNCTION;
- MemoryBuffer &operator=(const MemoryBuffer &) LLVM_DELETED_FUNCTION;
+ MemoryBuffer(const MemoryBuffer &) = delete;
+ MemoryBuffer &operator=(const MemoryBuffer &) = delete;
protected:
MemoryBuffer() {}
void init(const char *BufStart, const char *BufEnd,
diff --git a/include/llvm/Support/MipsABIFlags.h b/include/llvm/Support/MipsABIFlags.h
new file mode 100644
index 000000000000..93f6b416ba88
--- /dev/null
+++ b/include/llvm/Support/MipsABIFlags.h
@@ -0,0 +1,102 @@
+//===--- MipsABIFlags.h - MIPS ABI flags ----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the constants for the ABI flags structure contained
+// in the .MIPS.abiflags section.
+//
+// https://dmz-portal.mips.com/wiki/MIPS_O32_ABI_-_FR0_and_FR1_Interlinking
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_MIPSABIFLAGS_H
+#define LLVM_SUPPORT_MIPSABIFLAGS_H
+
+namespace llvm {
+namespace Mips {
+
+// Values for the xxx_size bytes of an ABI flags structure.
+enum AFL_REG {
+ AFL_REG_NONE = 0x00, // No registers
+ AFL_REG_32 = 0x01, // 32-bit registers
+ AFL_REG_64 = 0x02, // 64-bit registers
+ AFL_REG_128 = 0x03 // 128-bit registers
+};
+
+// Masks for the ases word of an ABI flags structure.
+enum AFL_ASE {
+ AFL_ASE_DSP = 0x00000001, // DSP ASE
+ AFL_ASE_DSPR2 = 0x00000002, // DSP R2 ASE
+ AFL_ASE_EVA = 0x00000004, // Enhanced VA Scheme
+ AFL_ASE_MCU = 0x00000008, // MCU (MicroController) ASE
+ AFL_ASE_MDMX = 0x00000010, // MDMX ASE
+ AFL_ASE_MIPS3D = 0x00000020, // MIPS-3D ASE
+ AFL_ASE_MT = 0x00000040, // MT ASE
+ AFL_ASE_SMARTMIPS = 0x00000080, // SmartMIPS ASE
+ AFL_ASE_VIRT = 0x00000100, // VZ ASE
+ AFL_ASE_MSA = 0x00000200, // MSA ASE
+ AFL_ASE_MIPS16 = 0x00000400, // MIPS16 ASE
+ AFL_ASE_MICROMIPS = 0x00000800, // MICROMIPS ASE
+ AFL_ASE_XPA = 0x00001000 // XPA ASE
+};
+
+// Values for the isa_ext word of an ABI flags structure.
+enum AFL_EXT {
+ AFL_EXT_NONE = 0, // None
+ AFL_EXT_XLR = 1, // RMI Xlr instruction
+ AFL_EXT_OCTEON2 = 2, // Cavium Networks Octeon2
+ AFL_EXT_OCTEONP = 3, // Cavium Networks OcteonP
+ AFL_EXT_LOONGSON_3A = 4, // Loongson 3A
+ AFL_EXT_OCTEON = 5, // Cavium Networks Octeon
+ AFL_EXT_5900 = 6, // MIPS R5900 instruction
+ AFL_EXT_4650 = 7, // MIPS R4650 instruction
+ AFL_EXT_4010 = 8, // LSI R4010 instruction
+ AFL_EXT_4100 = 9, // NEC VR4100 instruction
+ AFL_EXT_3900 = 10, // Toshiba R3900 instruction
+ AFL_EXT_10000 = 11, // MIPS R10000 instruction
+ AFL_EXT_SB1 = 12, // Broadcom SB-1 instruction
+ AFL_EXT_4111 = 13, // NEC VR4111/VR4181 instruction
+ AFL_EXT_4120 = 14, // NEC VR4120 instruction
+ AFL_EXT_5400 = 15, // NEC VR5400 instruction
+ AFL_EXT_5500 = 16, // NEC VR5500 instruction
+ AFL_EXT_LOONGSON_2E = 17, // ST Microelectronics Loongson 2E
+ AFL_EXT_LOONGSON_2F = 18, // ST Microelectronics Loongson 2F
+ AFL_EXT_OCTEON3 = 19 // Cavium Networks Octeon3
+};
+
+// Values for the flags1 word of an ABI flags structure.
+enum AFL_FLAGS1 { AFL_FLAGS1_ODDSPREG = 1 };
+
+// MIPS object attribute tags
+enum {
+ Tag_GNU_MIPS_ABI_FP = 4, // Floating-point ABI used by this object file
+ Tag_GNU_MIPS_ABI_MSA = 8, // MSA ABI used by this object file
+};
+
+// Values for the fp_abi word of an ABI flags structure
+// and for the Tag_GNU_MIPS_ABI_FP attribute tag.
+enum Val_GNU_MIPS_ABI_FP {
+ Val_GNU_MIPS_ABI_FP_ANY = 0, // not tagged
+ Val_GNU_MIPS_ABI_FP_DOUBLE = 1, // hard float / -mdouble-float
+ Val_GNU_MIPS_ABI_FP_SINGLE = 2, // hard float / -msingle-float
+ Val_GNU_MIPS_ABI_FP_SOFT = 3, // soft float
+ Val_GNU_MIPS_ABI_FP_OLD_64 = 4, // -mips32r2 -mfp64
+ Val_GNU_MIPS_ABI_FP_XX = 5, // -mfpxx
+ Val_GNU_MIPS_ABI_FP_64 = 6, // -mips32r2 -mfp64
+ Val_GNU_MIPS_ABI_FP_64A = 7 // -mips32r2 -mfp64 -mno-odd-spreg
+};
+
+// Values for the Tag_GNU_MIPS_ABI_MSA attribute tag.
+enum Val_GNU_MIPS_ABI_MSA {
+ Val_GNU_MIPS_ABI_MSA_ANY = 0, // not tagged
+ Val_GNU_MIPS_ABI_MSA_128 = 1 // 128-bit MSA
+};
+}
+}
+
+#endif
diff --git a/include/llvm/Support/Mutex.h b/include/llvm/Support/Mutex.h
index 97dd50115322..0f4e61af4439 100644
--- a/include/llvm/Support/Mutex.h
+++ b/include/llvm/Support/Mutex.h
@@ -70,14 +70,16 @@ namespace llvm
/// @name Platform Dependent Data
/// @{
private:
+#if defined(LLVM_ENABLE_THREADS) && LLVM_ENABLE_THREADS != 0
void* data_; ///< We don't know what the data will be
+#endif
/// @}
/// @name Do Not Implement
/// @{
private:
- MutexImpl(const MutexImpl &) LLVM_DELETED_FUNCTION;
- void operator=(const MutexImpl &) LLVM_DELETED_FUNCTION;
+ MutexImpl(const MutexImpl &) = delete;
+ void operator=(const MutexImpl &) = delete;
/// @}
};
diff --git a/include/llvm/Support/MutexGuard.h b/include/llvm/Support/MutexGuard.h
index b9f941dab323..07b64b611960 100644
--- a/include/llvm/Support/MutexGuard.h
+++ b/include/llvm/Support/MutexGuard.h
@@ -26,8 +26,8 @@ namespace llvm {
/// @brief Guard a section of code with a Mutex.
class MutexGuard {
sys::Mutex &M;
- MutexGuard(const MutexGuard &) LLVM_DELETED_FUNCTION;
- void operator=(const MutexGuard &) LLVM_DELETED_FUNCTION;
+ MutexGuard(const MutexGuard &) = delete;
+ void operator=(const MutexGuard &) = delete;
public:
MutexGuard(sys::Mutex &m) : M(m) { M.lock(); }
~MutexGuard() { M.unlock(); }
diff --git a/include/llvm/Support/OnDiskHashTable.h b/include/llvm/Support/OnDiskHashTable.h
index 52f133ccff68..0f097f287286 100644
--- a/include/llvm/Support/OnDiskHashTable.h
+++ b/include/llvm/Support/OnDiskHashTable.h
@@ -75,13 +75,10 @@ template <typename Info> class OnDiskChainedHashTableGenerator {
llvm::SpecificBumpPtrAllocator<Item> BA;
/// \brief A linked list of values in a particular hash bucket.
- class Bucket {
- public:
+ struct Bucket {
offset_type Off;
- Item *Head;
unsigned Length;
-
- Bucket() {}
+ Item *Head;
};
Bucket *Buckets;
diff --git a/include/llvm/Support/Options.h b/include/llvm/Support/Options.h
index 4fd1bff358fd..2742d3907c62 100644
--- a/include/llvm/Support/Options.h
+++ b/include/llvm/Support/Options.h
@@ -61,7 +61,7 @@ char OptionKey<ValT, Base, Mem>::ID = 0;
/// The OptionRegistry is responsible for managing lifetimes of the options and
/// provides interfaces for option registration and reading values from options.
/// This object is a singleton, only one instance should ever exist so that all
-/// options are registered in teh same place.
+/// options are registered in the same place.
class OptionRegistry {
private:
DenseMap<void *, cl::Option *> Options;
diff --git a/include/llvm/Support/PrettyStackTrace.h b/include/llvm/Support/PrettyStackTrace.h
index 914141ad3c4b..96afb60d8e51 100644
--- a/include/llvm/Support/PrettyStackTrace.h
+++ b/include/llvm/Support/PrettyStackTrace.h
@@ -30,8 +30,8 @@ namespace llvm {
/// virtual stack trace. This gets dumped out if the program crashes.
class PrettyStackTraceEntry {
const PrettyStackTraceEntry *NextEntry;
- PrettyStackTraceEntry(const PrettyStackTraceEntry &) LLVM_DELETED_FUNCTION;
- void operator=(const PrettyStackTraceEntry&) LLVM_DELETED_FUNCTION;
+ PrettyStackTraceEntry(const PrettyStackTraceEntry &) = delete;
+ void operator=(const PrettyStackTraceEntry&) = delete;
public:
PrettyStackTraceEntry();
virtual ~PrettyStackTraceEntry();
diff --git a/include/llvm/Support/Program.h b/include/llvm/Support/Program.h
index 40dc60fa30d6..b89a0f73ec68 100644
--- a/include/llvm/Support/Program.h
+++ b/include/llvm/Support/Program.h
@@ -16,10 +16,11 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/ErrorOr.h"
-#include "llvm/Support/Path.h"
#include <system_error>
namespace llvm {
+class StringRef;
+
namespace sys {
/// This is the OS-specific separator for PATH like environment variables:
diff --git a/include/llvm/Support/RWMutex.h b/include/llvm/Support/RWMutex.h
index b80b8557576b..4be931337765 100644
--- a/include/llvm/Support/RWMutex.h
+++ b/include/llvm/Support/RWMutex.h
@@ -70,14 +70,16 @@ namespace llvm
/// @name Platform Dependent Data
/// @{
private:
+#if defined(LLVM_ENABLE_THREADS) && LLVM_ENABLE_THREADS != 0
void* data_; ///< We don't know what the data will be
+#endif
/// @}
/// @name Do Not Implement
/// @{
private:
- RWMutexImpl(const RWMutexImpl & original) LLVM_DELETED_FUNCTION;
- void operator=(const RWMutexImpl &) LLVM_DELETED_FUNCTION;
+ RWMutexImpl(const RWMutexImpl & original) = delete;
+ void operator=(const RWMutexImpl &) = delete;
/// @}
};
diff --git a/include/llvm/Support/RandomNumberGenerator.h b/include/llvm/Support/RandomNumberGenerator.h
index 7ada34f075e4..7446558f0c88 100644
--- a/include/llvm/Support/RandomNumberGenerator.h
+++ b/include/llvm/Support/RandomNumberGenerator.h
@@ -48,10 +48,8 @@ private:
std::mt19937_64 Generator;
// Noncopyable.
- RandomNumberGenerator(const RandomNumberGenerator &other)
- LLVM_DELETED_FUNCTION;
- RandomNumberGenerator &
- operator=(const RandomNumberGenerator &other) LLVM_DELETED_FUNCTION;
+ RandomNumberGenerator(const RandomNumberGenerator &other) = delete;
+ RandomNumberGenerator &operator=(const RandomNumberGenerator &other) = delete;
friend class Module;
};
diff --git a/include/llvm/Support/Regex.h b/include/llvm/Support/Regex.h
index bf533ca1aa60..31b35ed0cad6 100644
--- a/include/llvm/Support/Regex.h
+++ b/include/llvm/Support/Regex.h
@@ -17,7 +17,6 @@
#ifndef LLVM_SUPPORT_REGEX_H
#define LLVM_SUPPORT_REGEX_H
-#include "llvm/Support/Compiler.h"
#include <string>
struct llvm_regex;
@@ -46,7 +45,7 @@ namespace llvm {
/// Compiles the given regular expression \p Regex.
Regex(StringRef Regex, unsigned Flags = NoFlags);
- Regex(const Regex &) LLVM_DELETED_FUNCTION;
+ Regex(const Regex &) = delete;
Regex &operator=(Regex regex) {
std::swap(preg, regex.preg);
std::swap(error, regex.error);
diff --git a/include/llvm/Support/Registry.h b/include/llvm/Support/Registry.h
index e21269b2f1d5..95c4e96f7f29 100644
--- a/include/llvm/Support/Registry.h
+++ b/include/llvm/Support/Registry.h
@@ -14,6 +14,7 @@
#ifndef LLVM_SUPPORT_REGISTRY_H
#define LLVM_SUPPORT_REGISTRY_H
+#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Compiler.h"
#include <memory>
@@ -41,7 +42,7 @@ namespace llvm {
/// is necessary to define an alternate traits class.
template <typename T>
class RegistryTraits {
- RegistryTraits() LLVM_DELETED_FUNCTION;
+ RegistryTraits() = delete;
public:
typedef SimpleRegistryEntry<T> entry;
@@ -67,7 +68,7 @@ namespace llvm {
class iterator;
private:
- Registry() LLVM_DELETED_FUNCTION;
+ Registry() = delete;
static void Announce(const entry &E) {
for (listener *Cur = ListenerHead; Cur; Cur = Cur->Next)
@@ -120,6 +121,10 @@ namespace llvm {
static iterator begin() { return iterator(Head); }
static iterator end() { return iterator(nullptr); }
+ static iterator_range<iterator> entries() {
+ return iterator_range<iterator>(begin(), end());
+ }
+
/// Abstract base class for registry listeners, which are informed when new
/// entries are added to the registry. Simply subclass and instantiate:
diff --git a/include/llvm/Support/ScaledNumber.h b/include/llvm/Support/ScaledNumber.h
index a1c4c80c356f..0a4262b7eec5 100644
--- a/include/llvm/Support/ScaledNumber.h
+++ b/include/llvm/Support/ScaledNumber.h
@@ -514,7 +514,7 @@ public:
: Digits(Digits), Scale(Scale) {}
private:
- ScaledNumber(const std::pair<uint64_t, int16_t> &X)
+ ScaledNumber(const std::pair<DigitsT, int16_t> &X)
: Digits(X.first), Scale(X.second) {}
public:
@@ -670,14 +670,7 @@ public:
return ScaledNumbers::compare(Digits, Scale, X.Digits, X.Scale);
}
int compareTo(uint64_t N) const {
- ScaledNumber Scaled = get(N);
- int Compare = compare(Scaled);
- if (Width == 64 || Compare != 0)
- return Compare;
-
- // Check for precision loss. We know *this == RoundTrip.
- uint64_t RoundTrip = Scaled.template toInt<uint64_t>();
- return N == RoundTrip ? 0 : RoundTrip < N ? -1 : 1;
+ return ScaledNumbers::compare<uint64_t>(Digits, Scale, N, 0);
}
int compareTo(int64_t N) const { return N < 0 ? 1 : compareTo(uint64_t(N)); }
@@ -732,11 +725,21 @@ SCALED_NUMBER_BOP(+, += )
SCALED_NUMBER_BOP(-, -= )
SCALED_NUMBER_BOP(*, *= )
SCALED_NUMBER_BOP(/, /= )
-SCALED_NUMBER_BOP(<<, <<= )
-SCALED_NUMBER_BOP(>>, >>= )
#undef SCALED_NUMBER_BOP
template <class DigitsT>
+ScaledNumber<DigitsT> operator<<(const ScaledNumber<DigitsT> &L,
+ int16_t Shift) {
+ return ScaledNumber<DigitsT>(L) <<= Shift;
+}
+
+template <class DigitsT>
+ScaledNumber<DigitsT> operator>>(const ScaledNumber<DigitsT> &L,
+ int16_t Shift) {
+ return ScaledNumber<DigitsT>(L) >>= Shift;
+}
+
+template <class DigitsT>
raw_ostream &operator<<(raw_ostream &OS, const ScaledNumber<DigitsT> &X) {
return X.print(OS, 10);
}
diff --git a/include/llvm/Support/Signals.h b/include/llvm/Support/Signals.h
index 6cbc1f6854a6..7e165d7f3a42 100644
--- a/include/llvm/Support/Signals.h
+++ b/include/llvm/Support/Signals.h
@@ -15,10 +15,12 @@
#ifndef LLVM_SUPPORT_SIGNALS_H
#define LLVM_SUPPORT_SIGNALS_H
-#include "llvm/Support/Path.h"
-#include <cstdio>
+#include <string>
namespace llvm {
+class StringRef;
+class raw_ostream;
+
namespace sys {
/// This function runs all the registered interrupt handlers, including the
@@ -37,10 +39,13 @@ namespace sys {
/// When an error signal (such as SIBABRT or SIGSEGV) is delivered to the
/// process, print a stack trace and then exit.
/// @brief Print a stack trace if a fatal signal occurs.
- void PrintStackTraceOnErrorSignal();
+ void PrintStackTraceOnErrorSignal(bool DisableCrashReporting = false);
+
+ /// Disable all system dialog boxes that appear when the process crashes.
+ void DisableSystemDialogsOnCrash();
- /// \brief Print the stack trace using the given \c FILE object.
- void PrintStackTrace(FILE *);
+ /// \brief Print the stack trace using the given \c raw_ostream object.
+ void PrintStackTrace(raw_ostream &OS);
/// AddSignalHandler - Add a function to be called when an abort/kill signal
/// is delivered to the process. The handler can have a cookie passed to it
diff --git a/include/llvm/Support/SourceMgr.h b/include/llvm/Support/SourceMgr.h
index f9e114b67cb4..d492748e7781 100644
--- a/include/llvm/Support/SourceMgr.h
+++ b/include/llvm/Support/SourceMgr.h
@@ -73,8 +73,8 @@ private:
bool isValidBufferID(unsigned i) const { return i && i <= Buffers.size(); }
- SourceMgr(const SourceMgr&) LLVM_DELETED_FUNCTION;
- void operator=(const SourceMgr&) LLVM_DELETED_FUNCTION;
+ SourceMgr(const SourceMgr&) = delete;
+ void operator=(const SourceMgr&) = delete;
public:
SourceMgr()
: LineNoCache(nullptr), DiagHandler(nullptr), DiagContext(nullptr) {}
diff --git a/include/llvm/Support/SpecialCaseList.h b/include/llvm/Support/SpecialCaseList.h
index 313212e59dd2..ce693c501312 100644
--- a/include/llvm/Support/SpecialCaseList.h
+++ b/include/llvm/Support/SpecialCaseList.h
@@ -49,6 +49,8 @@
#define LLVM_SUPPORT_SPECIALCASELIST_H
#include "llvm/ADT/StringMap.h"
+#include <string>
+#include <vector>
namespace llvm {
class MemoryBuffer;
@@ -57,18 +59,18 @@ class StringRef;
class SpecialCaseList {
public:
- /// Parses the special case list from a file. If Path is empty, returns
- /// an empty special case list. On failure, returns 0 and writes an error
- /// message to string.
- static std::unique_ptr<SpecialCaseList> create(StringRef Path,
- std::string &Error);
+ /// Parses the special case list entries from files. On failure, returns
+ /// 0 and writes an error message to string.
+ static std::unique_ptr<SpecialCaseList>
+ create(const std::vector<std::string> &Paths, std::string &Error);
/// Parses the special case list from a memory buffer. On failure, returns
/// 0 and writes an error message to string.
static std::unique_ptr<SpecialCaseList> create(const MemoryBuffer *MB,
- std::string &Error);
- /// Parses the special case list from a file. On failure, reports a fatal
- /// error.
- static std::unique_ptr<SpecialCaseList> createOrDie(StringRef Path);
+ std::string &Error);
+ /// Parses the special case list entries from files. On failure, reports a
+ /// fatal error.
+ static std::unique_ptr<SpecialCaseList>
+ createOrDie(const std::vector<std::string> &Paths);
~SpecialCaseList();
@@ -81,15 +83,19 @@ public:
StringRef Category = StringRef()) const;
private:
- SpecialCaseList(SpecialCaseList const &) LLVM_DELETED_FUNCTION;
- SpecialCaseList &operator=(SpecialCaseList const &) LLVM_DELETED_FUNCTION;
+ SpecialCaseList(SpecialCaseList const &) = delete;
+ SpecialCaseList &operator=(SpecialCaseList const &) = delete;
struct Entry;
- StringMap<StringMap<Entry> > Entries;
+ StringMap<StringMap<Entry>> Entries;
+ StringMap<StringMap<std::string>> Regexps;
+ bool IsCompiled;
SpecialCaseList();
/// Parses just-constructed SpecialCaseList entries from a memory buffer.
bool parse(const MemoryBuffer *MB, std::string &Error);
+ /// compile() should be called once, after parsing all the memory buffers.
+ void compile();
};
} // namespace llvm
diff --git a/include/llvm/Support/StreamingMemoryObject.h b/include/llvm/Support/StreamingMemoryObject.h
index 66ed521a411c..932e635cd072 100644
--- a/include/llvm/Support/StreamingMemoryObject.h
+++ b/include/llvm/Support/StreamingMemoryObject.h
@@ -14,7 +14,6 @@
#include "llvm/Support/DataStream.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MemoryObject.h"
-#include <cassert>
#include <memory>
#include <vector>
@@ -30,11 +29,12 @@ public:
uint64_t readBytes(uint8_t *Buf, uint64_t Size,
uint64_t Address) const override;
const uint8_t *getPointer(uint64_t address, uint64_t size) const override {
- // 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.
- llvm_unreachable("getPointer in streaming memory objects not allowed");
+ // FIXME: 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 (any
+ // that need Blobs) don't stream.
+ report_fatal_error("getPointer in streaming memory objects not allowed");
return nullptr;
}
bool isValidAddress(uint64_t address) const override;
@@ -59,30 +59,31 @@ private:
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
+ // Fetch enough bytes such that Pos can be read (i.e. BytesRead >
+ // Pos). Returns 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) {
+ if (EOFReached)
+ return false;
Bytes.resize(BytesRead + BytesSkipped + kChunkSize);
size_t bytes = Streamer->GetBytes(&Bytes[BytesRead + BytesSkipped],
kChunkSize);
BytesRead += bytes;
- if (bytes != kChunkSize) { // reached EOF/ran out of bytes
- ObjectSize = BytesRead;
+ if (bytes == 0) { // reached EOF/ran out of bytes
+ if (ObjectSize == 0)
+ ObjectSize = BytesRead;
EOFReached = true;
- break;
}
}
- return Pos < BytesRead;
+ return !ObjectSize || Pos < ObjectSize;
}
- StreamingMemoryObject(const StreamingMemoryObject&) LLVM_DELETED_FUNCTION;
- void operator=(const StreamingMemoryObject&) LLVM_DELETED_FUNCTION;
+ StreamingMemoryObject(const StreamingMemoryObject&) = delete;
+ void operator=(const StreamingMemoryObject&) = delete;
};
MemoryObject *getNonStreamedMemoryObject(
diff --git a/include/llvm/Support/StringPool.h b/include/llvm/Support/StringPool.h
index b51974c946e0..2ec0c3b76c11 100644
--- a/include/llvm/Support/StringPool.h
+++ b/include/llvm/Support/StringPool.h
@@ -30,9 +30,7 @@
#define LLVM_SUPPORT_STRINGPOOL_H
#include "llvm/ADT/StringMap.h"
-#include "llvm/Support/Compiler.h"
#include <cassert>
-#include <new>
namespace llvm {
@@ -129,7 +127,7 @@ namespace llvm {
}
inline const char *operator*() const { return begin(); }
- inline LLVM_EXPLICIT operator bool() const { return S != nullptr; }
+ inline explicit operator bool() const { return S != nullptr; }
inline bool operator==(const PooledStringPtr &That) const { return S == That.S; }
inline bool operator!=(const PooledStringPtr &That) const { return S != That.S; }
diff --git a/include/llvm/Support/SwapByteOrder.h b/include/llvm/Support/SwapByteOrder.h
index 9c5a3c59122e..7761fa1d7e01 100644
--- a/include/llvm/Support/SwapByteOrder.h
+++ b/include/llvm/Support/SwapByteOrder.h
@@ -94,6 +94,26 @@ inline signed long long getSwappedBytes(signed long long C) {
return SwapByteOrder_64(C);
}
+inline float getSwappedBytes(float C) {
+ union {
+ uint32_t i;
+ float f;
+ } in, out;
+ in.f = C;
+ out.i = SwapByteOrder_32(in.i);
+ return out.f;
+}
+
+inline double getSwappedBytes(double C) {
+ union {
+ uint64_t i;
+ double d;
+ } in, out;
+ in.d = C;
+ out.i = SwapByteOrder_64(in.i);
+ return out.d;
+}
+
template<typename T>
inline void swapByteOrder(T &Value) {
Value = getSwappedBytes(Value);
diff --git a/include/llvm/Support/SystemUtils.h b/include/llvm/Support/SystemUtils.h
index d2d08b234272..2997b1b0c9cf 100644
--- a/include/llvm/Support/SystemUtils.h
+++ b/include/llvm/Support/SystemUtils.h
@@ -15,8 +15,6 @@
#ifndef LLVM_SUPPORT_SYSTEMUTILS_H
#define LLVM_SUPPORT_SYSTEMUTILS_H
-#include <string>
-
namespace llvm {
class raw_ostream;
diff --git a/include/llvm/Support/TargetParser.h b/include/llvm/Support/TargetParser.h
new file mode 100644
index 000000000000..ca626f271d51
--- /dev/null
+++ b/include/llvm/Support/TargetParser.h
@@ -0,0 +1,155 @@
+//===-- TargetParser - Parser for target features ---------------*- 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 target parser to recognise hardware features such as
+// FPU/CPU/ARCH names as well as specific support such as HDIV, etc.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_TARGETPARSER_H
+#define LLVM_SUPPORT_TARGETPARSER_H
+
+namespace llvm {
+ class StringRef;
+
+// Target specific information into their own namespaces. These should be
+// generated from TableGen because the information is already there, and there
+// is where new information about targets will be added.
+// FIXME: To TableGen this we need to make some table generated files available
+// even if the back-end is not compiled with LLVM, plus we need to create a new
+// back-end to TableGen to create these clean tables.
+namespace ARM {
+ // FPU names.
+ enum FPUKind {
+ FK_INVALID = 0,
+ FK_VFP,
+ FK_VFPV2,
+ FK_VFPV3,
+ FK_VFPV3_D16,
+ FK_VFPV4,
+ FK_VFPV4_D16,
+ FK_FPV5_D16,
+ FK_FP_ARMV8,
+ FK_NEON,
+ FK_NEON_VFPV4,
+ FK_NEON_FP_ARMV8,
+ FK_CRYPTO_NEON_FP_ARMV8,
+ FK_SOFTVFP,
+ FK_LAST
+ };
+
+ // Arch names.
+ enum ArchKind {
+ AK_INVALID = 0,
+ AK_ARMV2,
+ AK_ARMV2A,
+ AK_ARMV3,
+ AK_ARMV3M,
+ AK_ARMV4,
+ AK_ARMV4T,
+ AK_ARMV5,
+ AK_ARMV5T,
+ AK_ARMV5TE,
+ AK_ARMV6,
+ AK_ARMV6J,
+ AK_ARMV6K,
+ AK_ARMV6T2,
+ AK_ARMV6Z,
+ AK_ARMV6ZK,
+ AK_ARMV6M,
+ AK_ARMV7,
+ AK_ARMV7A,
+ AK_ARMV7R,
+ AK_ARMV7M,
+ AK_ARMV8A,
+ AK_ARMV8_1A,
+ // Non-standard Arch names.
+ AK_IWMMXT,
+ AK_IWMMXT2,
+ AK_XSCALE,
+ AK_ARMV5E,
+ AK_ARMV5TEJ,
+ AK_ARMV6SM,
+ AK_ARMV6HL,
+ AK_ARMV7L,
+ AK_ARMV7HL,
+ AK_ARMV7S,
+ AK_ARMV7EM,
+ AK_LAST
+ };
+
+ // Arch extension modifiers for CPUs.
+ enum ArchExtKind {
+ AEK_INVALID = 0,
+ AEK_CRC,
+ AEK_CRYPTO,
+ AEK_FP,
+ AEK_HWDIV,
+ AEK_MP,
+ AEK_SEC,
+ AEK_VIRT,
+ AEK_LAST
+ };
+
+ // ISA kinds.
+ enum ISAKind {
+ IK_INVALID = 0,
+ IK_ARM,
+ IK_THUMB,
+ IK_AARCH64
+ };
+
+ // Endianness
+ // FIXME: BE8 vs. BE32?
+ enum EndianKind {
+ EK_INVALID = 0,
+ EK_LITTLE,
+ EK_BIG
+ };
+
+ // v6/v7/v8 Profile
+ enum ProfileKind {
+ PK_INVALID = 0,
+ PK_A,
+ PK_R,
+ PK_M
+ };
+} // namespace ARM
+
+// Target Parsers, one per architecture.
+class ARMTargetParser {
+ static StringRef getFPUSynonym(StringRef FPU);
+ static StringRef getArchSynonym(StringRef Arch);
+
+public:
+ static StringRef getCanonicalArchName(StringRef Arch);
+
+ // Information by ID
+ static const char * getFPUName(unsigned FPUKind);
+ static const char * getArchName(unsigned ArchKind);
+ static unsigned getArchDefaultCPUArch(unsigned ArchKind);
+ static const char * getArchDefaultCPUName(unsigned ArchKind);
+ static const char * getArchExtName(unsigned ArchExtKind);
+ static const char * getDefaultCPU(StringRef Arch);
+
+ // Parser
+ static unsigned parseFPU(StringRef FPU);
+ static unsigned parseArch(StringRef Arch);
+ static unsigned parseArchExt(StringRef ArchExt);
+ static unsigned parseCPUArch(StringRef CPU);
+ static unsigned parseArchISA(StringRef Arch);
+ static unsigned parseArchEndian(StringRef Arch);
+ static unsigned parseArchProfile(StringRef Arch);
+ static unsigned parseArchVersion(StringRef Arch);
+
+};
+
+} // namespace llvm
+
+#endif
diff --git a/include/llvm/Support/TargetRegistry.h b/include/llvm/Support/TargetRegistry.h
index 8ac4b904bb88..408e908aa04c 100644
--- a/include/llvm/Support/TargetRegistry.h
+++ b/include/llvm/Support/TargetRegistry.h
@@ -22,1133 +22,1161 @@
#include "llvm-c/Disassembler.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/CodeGen.h"
+#include "llvm/Support/FormattedStream.h"
#include <cassert>
+#include <memory>
#include <string>
namespace llvm {
- class AsmPrinter;
- class Module;
- class MCAssembler;
- class MCAsmBackend;
- class MCAsmInfo;
- class MCAsmParser;
- class MCCodeEmitter;
- class MCCodeGenInfo;
- class MCContext;
- class MCDisassembler;
- class MCInstrAnalysis;
- class MCInstPrinter;
- class MCInstrInfo;
- class MCRegisterInfo;
- class MCStreamer;
- class MCSubtargetInfo;
- class MCSymbolizer;
- class MCRelocationInfo;
- class MCTargetAsmParser;
- class MCTargetOptions;
- class TargetMachine;
- class TargetOptions;
- class raw_ostream;
- class formatted_raw_ostream;
-
- MCStreamer *createNullStreamer(MCContext &Ctx);
- MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
- bool isVerboseAsm, bool useDwarfDirectory,
- MCInstPrinter *InstPrint, MCCodeEmitter *CE,
- MCAsmBackend *TAB, bool ShowInst);
-
- MCRelocationInfo *createMCRelocationInfo(StringRef TT, MCContext &Ctx);
-
- MCSymbolizer *createMCSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo,
- LLVMSymbolLookupCallback SymbolLookUp,
- void *DisInfo,
- MCContext *Ctx,
- MCRelocationInfo *RelInfo);
-
- /// Target - Wrapper for Target specific information.
- ///
- /// For registration purposes, this is a POD type so that targets can be
- /// registered without the use of static constructors.
- ///
- /// Targets should implement a single global instance of this class (which
- /// will be zero initialized), and pass that instance to the TargetRegistry as
- /// part of their initialization.
- class Target {
- public:
- friend struct TargetRegistry;
-
- typedef bool (*ArchMatchFnTy)(Triple::ArchType Arch);
-
- typedef MCAsmInfo *(*MCAsmInfoCtorFnTy)(const MCRegisterInfo &MRI,
- StringRef TT);
- typedef MCCodeGenInfo *(*MCCodeGenInfoCtorFnTy)(StringRef TT,
- Reloc::Model RM,
- CodeModel::Model CM,
- CodeGenOpt::Level OL);
- typedef MCInstrInfo *(*MCInstrInfoCtorFnTy)(void);
- typedef MCInstrAnalysis *(*MCInstrAnalysisCtorFnTy)(const MCInstrInfo*Info);
- typedef MCRegisterInfo *(*MCRegInfoCtorFnTy)(StringRef TT);
- typedef MCSubtargetInfo *(*MCSubtargetInfoCtorFnTy)(StringRef TT,
- StringRef CPU,
- StringRef Features);
- typedef TargetMachine *(*TargetMachineCtorTy)(const Target &T,
- StringRef TT,
- StringRef CPU,
- StringRef Features,
- const TargetOptions &Options,
- Reloc::Model RM,
+class AsmPrinter;
+class MCAsmBackend;
+class MCAsmInfo;
+class MCAsmParser;
+class MCCodeEmitter;
+class MCCodeGenInfo;
+class MCContext;
+class MCDisassembler;
+class MCInstrAnalysis;
+class MCInstPrinter;
+class MCInstrInfo;
+class MCRegisterInfo;
+class MCStreamer;
+class MCSubtargetInfo;
+class MCSymbolizer;
+class MCRelocationInfo;
+class MCTargetAsmParser;
+class MCTargetOptions;
+class MCTargetStreamer;
+class TargetMachine;
+class TargetOptions;
+class raw_ostream;
+class raw_pwrite_stream;
+class formatted_raw_ostream;
+
+MCStreamer *createNullStreamer(MCContext &Ctx);
+MCStreamer *createAsmStreamer(MCContext &Ctx,
+ std::unique_ptr<formatted_raw_ostream> OS,
+ bool isVerboseAsm, bool useDwarfDirectory,
+ MCInstPrinter *InstPrint, MCCodeEmitter *CE,
+ MCAsmBackend *TAB, bool ShowInst);
+
+/// Takes ownership of \p TAB and \p CE.
+MCStreamer *createELFStreamer(MCContext &Ctx, MCAsmBackend &TAB,
+ raw_pwrite_stream &OS, MCCodeEmitter *CE,
+ bool RelaxAll);
+MCStreamer *createMachOStreamer(MCContext &Ctx, MCAsmBackend &TAB,
+ raw_pwrite_stream &OS, MCCodeEmitter *CE,
+ bool RelaxAll, bool DWARFMustBeAtTheEnd,
+ bool LabelSections = false);
+
+MCRelocationInfo *createMCRelocationInfo(StringRef TT, MCContext &Ctx);
+
+MCSymbolizer *createMCSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo,
+ LLVMSymbolLookupCallback SymbolLookUp,
+ void *DisInfo, MCContext *Ctx,
+ std::unique_ptr<MCRelocationInfo> &&RelInfo);
+
+/// Target - Wrapper for Target specific information.
+///
+/// For registration purposes, this is a POD type so that targets can be
+/// registered without the use of static constructors.
+///
+/// Targets should implement a single global instance of this class (which
+/// will be zero initialized), and pass that instance to the TargetRegistry as
+/// part of their initialization.
+class Target {
+public:
+ friend struct TargetRegistry;
+
+ typedef bool (*ArchMatchFnTy)(Triple::ArchType Arch);
+
+ typedef MCAsmInfo *(*MCAsmInfoCtorFnTy)(const MCRegisterInfo &MRI,
+ StringRef TT);
+ typedef MCCodeGenInfo *(*MCCodeGenInfoCtorFnTy)(StringRef TT, Reloc::Model RM,
CodeModel::Model CM,
CodeGenOpt::Level OL);
- typedef AsmPrinter *(*AsmPrinterCtorTy)(TargetMachine &TM,
- MCStreamer &Streamer);
- typedef MCAsmBackend *(*MCAsmBackendCtorTy)(const Target &T,
- const MCRegisterInfo &MRI,
- StringRef TT,
- StringRef CPU);
- typedef MCTargetAsmParser *(*MCAsmParserCtorTy)(
- MCSubtargetInfo &STI,
- MCAsmParser &P,
- const MCInstrInfo &MII,
- const MCTargetOptions &Options);
- typedef MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T,
- const MCSubtargetInfo &STI,
- MCContext &Ctx);
- 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 MCRegisterInfo &MRI,
+ typedef MCInstrInfo *(*MCInstrInfoCtorFnTy)(void);
+ typedef MCInstrAnalysis *(*MCInstrAnalysisCtorFnTy)(const MCInstrInfo *Info);
+ typedef MCRegisterInfo *(*MCRegInfoCtorFnTy)(StringRef TT);
+ typedef MCSubtargetInfo *(*MCSubtargetInfoCtorFnTy)(StringRef TT,
+ StringRef CPU,
+ StringRef Features);
+ typedef TargetMachine *(*TargetMachineCtorTy)(
+ const Target &T, StringRef TT, StringRef CPU, StringRef Features,
+ const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM,
+ CodeGenOpt::Level OL);
+ // If it weren't for layering issues (this header is in llvm/Support, but
+ // depends on MC?) this should take the Streamer by value rather than rvalue
+ // reference.
+ typedef AsmPrinter *(*AsmPrinterCtorTy)(
+ TargetMachine &TM, std::unique_ptr<MCStreamer> &&Streamer);
+ typedef MCAsmBackend *(*MCAsmBackendCtorTy)(const Target &T,
+ const MCRegisterInfo &MRI,
+ StringRef TT, StringRef CPU);
+ typedef MCTargetAsmParser *(*MCAsmParserCtorTy)(
+ MCSubtargetInfo &STI, MCAsmParser &P, const MCInstrInfo &MII,
+ const MCTargetOptions &Options);
+ typedef MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T,
const MCSubtargetInfo &STI,
MCContext &Ctx);
- typedef MCStreamer *(*MCObjectStreamerCtorTy)(
- const Target &T, StringRef TT, MCContext &Ctx, MCAsmBackend &TAB,
- raw_ostream &_OS, MCCodeEmitter *_Emitter, const MCSubtargetInfo &STI,
- bool RelaxAll);
- typedef MCStreamer *(*AsmStreamerCtorTy)(MCContext &Ctx,
- formatted_raw_ostream &OS,
- bool isVerboseAsm,
- bool useDwarfDirectory,
- MCInstPrinter *InstPrint,
- MCCodeEmitter *CE,
- MCAsmBackend *TAB,
- bool ShowInst);
- typedef MCStreamer *(*NullStreamerCtorTy)(MCContext &Ctx);
- typedef MCRelocationInfo *(*MCRelocationInfoCtorTy)(StringRef TT,
- MCContext &Ctx);
- typedef MCSymbolizer *(*MCSymbolizerCtorTy)(StringRef TT,
- LLVMOpInfoCallback GetOpInfo,
- LLVMSymbolLookupCallback SymbolLookUp,
- void *DisInfo,
- MCContext *Ctx,
- MCRelocationInfo *RelInfo);
-
- private:
- /// Next - The next registered target in the linked list, maintained by the
- /// TargetRegistry.
- Target *Next;
-
- /// The target function for checking if an architecture is supported.
- ArchMatchFnTy ArchMatchFn;
-
- /// Name - The target name.
- const char *Name;
-
- /// ShortDesc - A short description of the target.
- const char *ShortDesc;
-
- /// HasJIT - Whether this target supports the JIT.
- bool HasJIT;
-
- /// MCAsmInfoCtorFn - Constructor function for this target's MCAsmInfo, if
- /// registered.
- MCAsmInfoCtorFnTy MCAsmInfoCtorFn;
-
- /// MCCodeGenInfoCtorFn - Constructor function for this target's
- /// MCCodeGenInfo, if registered.
- MCCodeGenInfoCtorFnTy MCCodeGenInfoCtorFn;
-
- /// MCInstrInfoCtorFn - Constructor function for this target's MCInstrInfo,
- /// if registered.
- MCInstrInfoCtorFnTy MCInstrInfoCtorFn;
-
- /// MCInstrAnalysisCtorFn - Constructor function for this target's
- /// MCInstrAnalysis, if registered.
- MCInstrAnalysisCtorFnTy MCInstrAnalysisCtorFn;
-
- /// MCRegInfoCtorFn - Constructor function for this target's MCRegisterInfo,
- /// if registered.
- MCRegInfoCtorFnTy MCRegInfoCtorFn;
-
- /// MCSubtargetInfoCtorFn - Constructor function for this target's
- /// MCSubtargetInfo, if registered.
- MCSubtargetInfoCtorFnTy MCSubtargetInfoCtorFn;
-
- /// TargetMachineCtorFn - Construction function for this target's
- /// TargetMachine, if registered.
- TargetMachineCtorTy TargetMachineCtorFn;
-
- /// MCAsmBackendCtorFn - Construction function for this target's
- /// MCAsmBackend, if registered.
- MCAsmBackendCtorTy MCAsmBackendCtorFn;
-
- /// MCAsmParserCtorFn - Construction function for this target's
- /// MCTargetAsmParser, if registered.
- MCAsmParserCtorTy MCAsmParserCtorFn;
-
- /// AsmPrinterCtorFn - Construction function for this target's AsmPrinter,
- /// if registered.
- AsmPrinterCtorTy AsmPrinterCtorFn;
-
- /// MCDisassemblerCtorFn - Construction function for this target's
- /// MCDisassembler, if registered.
- MCDisassemblerCtorTy MCDisassemblerCtorFn;
-
- /// MCInstPrinterCtorFn - Construction function for this target's
- /// MCInstPrinter, if registered.
- MCInstPrinterCtorTy MCInstPrinterCtorFn;
-
- /// MCCodeEmitterCtorFn - Construction function for this target's
- /// CodeEmitter, if registered.
- MCCodeEmitterCtorTy MCCodeEmitterCtorFn;
-
- /// MCObjectStreamerCtorFn - Construction function for this target's
- /// MCObjectStreamer, if registered.
- MCObjectStreamerCtorTy MCObjectStreamerCtorFn;
-
- /// AsmStreamerCtorFn - Construction function for this target's
- /// AsmStreamer, if registered (default = llvm::createAsmStreamer).
- AsmStreamerCtorTy AsmStreamerCtorFn;
-
- /// Construction function for this target's NullStreamer, if registered
- /// (default = llvm::createNullStreamer).
- NullStreamerCtorTy NullStreamerCtorFn;
-
- /// MCRelocationInfoCtorFn - Construction function for this target's
- /// MCRelocationInfo, if registered (default = llvm::createMCRelocationInfo)
- MCRelocationInfoCtorTy MCRelocationInfoCtorFn;
-
- /// MCSymbolizerCtorFn - Construction function for this target's
- /// MCSymbolizer, if registered (default = llvm::createMCSymbolizer)
- MCSymbolizerCtorTy MCSymbolizerCtorFn;
+ typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Triple &T,
+ unsigned SyntaxVariant,
+ const MCAsmInfo &MAI,
+ const MCInstrInfo &MII,
+ const MCRegisterInfo &MRI);
+ typedef MCCodeEmitter *(*MCCodeEmitterCtorTy)(const MCInstrInfo &II,
+ const MCRegisterInfo &MRI,
+ MCContext &Ctx);
+ typedef MCStreamer *(*ELFStreamerCtorTy)(const Triple &T, MCContext &Ctx,
+ MCAsmBackend &TAB,
+ raw_pwrite_stream &OS,
+ MCCodeEmitter *Emitter,
+ bool RelaxAll);
+ typedef MCStreamer *(*MachOStreamerCtorTy)(MCContext &Ctx, MCAsmBackend &TAB,
+ raw_pwrite_stream &OS,
+ MCCodeEmitter *Emitter,
+ bool RelaxAll,
+ bool DWARFMustBeAtTheEnd);
+ typedef MCStreamer *(*COFFStreamerCtorTy)(MCContext &Ctx, MCAsmBackend &TAB,
+ raw_pwrite_stream &OS,
+ MCCodeEmitter *Emitter,
+ bool RelaxAll);
+ typedef MCTargetStreamer *(*NullTargetStreamerCtorTy)(MCStreamer &S);
+ typedef MCTargetStreamer *(*AsmTargetStreamerCtorTy)(
+ MCStreamer &S, formatted_raw_ostream &OS, MCInstPrinter *InstPrint,
+ bool IsVerboseAsm);
+ typedef MCTargetStreamer *(*ObjectTargetStreamerCtorTy)(
+ MCStreamer &S, const MCSubtargetInfo &STI);
+ typedef MCRelocationInfo *(*MCRelocationInfoCtorTy)(StringRef TT,
+ MCContext &Ctx);
+ typedef MCSymbolizer *(*MCSymbolizerCtorTy)(
+ StringRef TT, LLVMOpInfoCallback GetOpInfo,
+ LLVMSymbolLookupCallback SymbolLookUp, void *DisInfo, MCContext *Ctx,
+ std::unique_ptr<MCRelocationInfo> &&RelInfo);
+
+private:
+ /// Next - The next registered target in the linked list, maintained by the
+ /// TargetRegistry.
+ Target *Next;
+
+ /// The target function for checking if an architecture is supported.
+ ArchMatchFnTy ArchMatchFn;
+
+ /// Name - The target name.
+ const char *Name;
+
+ /// ShortDesc - A short description of the target.
+ const char *ShortDesc;
+
+ /// HasJIT - Whether this target supports the JIT.
+ bool HasJIT;
+
+ /// MCAsmInfoCtorFn - Constructor function for this target's MCAsmInfo, if
+ /// registered.
+ MCAsmInfoCtorFnTy MCAsmInfoCtorFn;
+
+ /// MCCodeGenInfoCtorFn - Constructor function for this target's
+ /// MCCodeGenInfo, if registered.
+ MCCodeGenInfoCtorFnTy MCCodeGenInfoCtorFn;
+
+ /// MCInstrInfoCtorFn - Constructor function for this target's MCInstrInfo,
+ /// if registered.
+ MCInstrInfoCtorFnTy MCInstrInfoCtorFn;
+
+ /// MCInstrAnalysisCtorFn - Constructor function for this target's
+ /// MCInstrAnalysis, if registered.
+ MCInstrAnalysisCtorFnTy MCInstrAnalysisCtorFn;
+
+ /// MCRegInfoCtorFn - Constructor function for this target's MCRegisterInfo,
+ /// if registered.
+ MCRegInfoCtorFnTy MCRegInfoCtorFn;
+
+ /// MCSubtargetInfoCtorFn - Constructor function for this target's
+ /// MCSubtargetInfo, if registered.
+ MCSubtargetInfoCtorFnTy MCSubtargetInfoCtorFn;
+
+ /// TargetMachineCtorFn - Construction function for this target's
+ /// TargetMachine, if registered.
+ TargetMachineCtorTy TargetMachineCtorFn;
+
+ /// MCAsmBackendCtorFn - Construction function for this target's
+ /// MCAsmBackend, if registered.
+ MCAsmBackendCtorTy MCAsmBackendCtorFn;
+
+ /// MCAsmParserCtorFn - Construction function for this target's
+ /// MCTargetAsmParser, if registered.
+ MCAsmParserCtorTy MCAsmParserCtorFn;
+
+ /// AsmPrinterCtorFn - Construction function for this target's AsmPrinter,
+ /// if registered.
+ AsmPrinterCtorTy AsmPrinterCtorFn;
+
+ /// MCDisassemblerCtorFn - Construction function for this target's
+ /// MCDisassembler, if registered.
+ MCDisassemblerCtorTy MCDisassemblerCtorFn;
+
+ /// MCInstPrinterCtorFn - Construction function for this target's
+ /// MCInstPrinter, if registered.
+ MCInstPrinterCtorTy MCInstPrinterCtorFn;
+
+ /// MCCodeEmitterCtorFn - Construction function for this target's
+ /// CodeEmitter, if registered.
+ MCCodeEmitterCtorTy MCCodeEmitterCtorFn;
+
+ // Construction functions for the various object formats, if registered.
+ COFFStreamerCtorTy COFFStreamerCtorFn;
+ MachOStreamerCtorTy MachOStreamerCtorFn;
+ ELFStreamerCtorTy ELFStreamerCtorFn;
+
+ /// Construction function for this target's null TargetStreamer, if
+ /// registered (default = nullptr).
+ NullTargetStreamerCtorTy NullTargetStreamerCtorFn;
+
+ /// Construction function for this target's asm TargetStreamer, if
+ /// registered (default = nullptr).
+ AsmTargetStreamerCtorTy AsmTargetStreamerCtorFn;
+
+ /// Construction function for this target's obj TargetStreamer, if
+ /// registered (default = nullptr).
+ ObjectTargetStreamerCtorTy ObjectTargetStreamerCtorFn;
+
+ /// MCRelocationInfoCtorFn - Construction function for this target's
+ /// MCRelocationInfo, if registered (default = llvm::createMCRelocationInfo)
+ MCRelocationInfoCtorTy MCRelocationInfoCtorFn;
- public:
- Target()
- : AsmStreamerCtorFn(nullptr), NullStreamerCtorFn(nullptr),
- MCRelocationInfoCtorFn(nullptr), MCSymbolizerCtorFn(nullptr) {}
-
- /// @name Target Information
- /// @{
-
- // getNext - Return the next registered target.
- const Target *getNext() const { return Next; }
-
- /// getName - Get the target name.
- const char *getName() const { return Name; }
-
- /// getShortDescription - Get a short description of the target.
- const char *getShortDescription() const { return ShortDesc; }
-
- /// @}
- /// @name Feature Predicates
- /// @{
-
- /// hasJIT - Check if this targets supports the just-in-time compilation.
- bool hasJIT() const { return HasJIT; }
-
- /// hasTargetMachine - Check if this target supports code generation.
- bool hasTargetMachine() const { return TargetMachineCtorFn != nullptr; }
-
- /// hasMCAsmBackend - Check if this target supports .o generation.
- bool hasMCAsmBackend() const { return MCAsmBackendCtorFn != nullptr; }
-
- /// @}
- /// @name Feature Constructors
- /// @{
-
- /// createMCAsmInfo - Create a MCAsmInfo implementation for the specified
- /// target triple.
- ///
- /// \param Triple This argument is used to determine the target machine
- /// feature set; it should always be provided. Generally this should be
- /// either the target triple from the module, or the target triple of the
- /// host if that does not exist.
- MCAsmInfo *createMCAsmInfo(const MCRegisterInfo &MRI,
- StringRef Triple) const {
- if (!MCAsmInfoCtorFn)
- return nullptr;
- return MCAsmInfoCtorFn(MRI, Triple);
- }
+ /// MCSymbolizerCtorFn - Construction function for this target's
+ /// MCSymbolizer, if registered (default = llvm::createMCSymbolizer)
+ MCSymbolizerCtorTy MCSymbolizerCtorFn;
- /// createMCCodeGenInfo - Create a MCCodeGenInfo implementation.
- ///
- MCCodeGenInfo *createMCCodeGenInfo(StringRef Triple, Reloc::Model RM,
- CodeModel::Model CM,
- CodeGenOpt::Level OL) const {
- if (!MCCodeGenInfoCtorFn)
- return nullptr;
- return MCCodeGenInfoCtorFn(Triple, RM, CM, OL);
- }
+public:
+ Target()
+ : COFFStreamerCtorFn(nullptr), MachOStreamerCtorFn(nullptr),
+ ELFStreamerCtorFn(nullptr), NullTargetStreamerCtorFn(nullptr),
+ AsmTargetStreamerCtorFn(nullptr), ObjectTargetStreamerCtorFn(nullptr),
+ MCRelocationInfoCtorFn(nullptr), MCSymbolizerCtorFn(nullptr) {}
- /// createMCInstrInfo - Create a MCInstrInfo implementation.
- ///
- MCInstrInfo *createMCInstrInfo() const {
- if (!MCInstrInfoCtorFn)
- return nullptr;
- return MCInstrInfoCtorFn();
- }
+ /// @name Target Information
+ /// @{
- /// createMCInstrAnalysis - Create a MCInstrAnalysis implementation.
- ///
- MCInstrAnalysis *createMCInstrAnalysis(const MCInstrInfo *Info) const {
- if (!MCInstrAnalysisCtorFn)
- return nullptr;
- return MCInstrAnalysisCtorFn(Info);
- }
+ // getNext - Return the next registered target.
+ const Target *getNext() const { return Next; }
- /// createMCRegInfo - Create a MCRegisterInfo implementation.
- ///
- MCRegisterInfo *createMCRegInfo(StringRef Triple) const {
- if (!MCRegInfoCtorFn)
- return nullptr;
- return MCRegInfoCtorFn(Triple);
- }
+ /// getName - Get the target name.
+ const char *getName() const { return Name; }
- /// createMCSubtargetInfo - Create a MCSubtargetInfo implementation.
- ///
- /// \param Triple This argument is used to determine the target machine
- /// feature set; it should always be provided. Generally this should be
- /// either the target triple from the module, or the target triple of the
- /// host if that does not exist.
- /// \param CPU This specifies the name of the target CPU.
- /// \param Features This specifies the string representation of the
- /// additional target features.
- MCSubtargetInfo *createMCSubtargetInfo(StringRef Triple, StringRef CPU,
- StringRef Features) const {
- if (!MCSubtargetInfoCtorFn)
- return nullptr;
- return MCSubtargetInfoCtorFn(Triple, CPU, Features);
- }
+ /// getShortDescription - Get a short description of the target.
+ const char *getShortDescription() const { return ShortDesc; }
- /// createTargetMachine - Create a target specific machine implementation
- /// for the specified \p Triple.
- ///
- /// \param Triple This argument is used to determine the target machine
- /// feature set; it should always be provided. Generally this should be
- /// 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, const TargetOptions &Options,
- Reloc::Model RM = Reloc::Default,
- CodeModel::Model CM = CodeModel::Default,
- CodeGenOpt::Level OL = CodeGenOpt::Default) const {
- if (!TargetMachineCtorFn)
- return nullptr;
- return TargetMachineCtorFn(*this, Triple, CPU, Features, Options,
- RM, CM, OL);
- }
+ /// @}
+ /// @name Feature Predicates
+ /// @{
- /// createMCAsmBackend - Create a target specific assembly parser.
- ///
- /// \param Triple The target triple string.
- MCAsmBackend *createMCAsmBackend(const MCRegisterInfo &MRI,
- StringRef Triple, StringRef CPU) const {
- if (!MCAsmBackendCtorFn)
- return nullptr;
- return MCAsmBackendCtorFn(*this, MRI, Triple, CPU);
- }
+ /// hasJIT - Check if this targets supports the just-in-time compilation.
+ bool hasJIT() const { return HasJIT; }
- /// createMCAsmParser - Create a target specific assembly parser.
- ///
- /// \param Parser The target independent parser implementation to use for
- /// parsing and lexing.
- MCTargetAsmParser *createMCAsmParser(
- MCSubtargetInfo &STI,
- MCAsmParser &Parser,
- const MCInstrInfo &MII,
- const MCTargetOptions &Options) const {
- if (!MCAsmParserCtorFn)
- return nullptr;
- return MCAsmParserCtorFn(STI, Parser, MII, Options);
- }
+ /// hasTargetMachine - Check if this target supports code generation.
+ bool hasTargetMachine() const { return TargetMachineCtorFn != nullptr; }
- /// createAsmPrinter - Create a target specific assembly printer pass. This
- /// takes ownership of the MCStreamer object.
- AsmPrinter *createAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) const{
- if (!AsmPrinterCtorFn)
- return nullptr;
- return AsmPrinterCtorFn(TM, Streamer);
- }
+ /// hasMCAsmBackend - Check if this target supports .o generation.
+ bool hasMCAsmBackend() const { return MCAsmBackendCtorFn != nullptr; }
- MCDisassembler *createMCDisassembler(const MCSubtargetInfo &STI,
- MCContext &Ctx) const {
- if (!MCDisassemblerCtorFn)
- return nullptr;
- return MCDisassemblerCtorFn(*this, STI, Ctx);
- }
+ /// @}
+ /// @name Feature Constructors
+ /// @{
- MCInstPrinter *createMCInstPrinter(unsigned SyntaxVariant,
- const MCAsmInfo &MAI,
- const MCInstrInfo &MII,
- const MCRegisterInfo &MRI,
- const MCSubtargetInfo &STI) const {
- if (!MCInstPrinterCtorFn)
- return nullptr;
- return MCInstPrinterCtorFn(*this, SyntaxVariant, MAI, MII, MRI, STI);
- }
+ /// createMCAsmInfo - Create a MCAsmInfo implementation for the specified
+ /// target triple.
+ ///
+ /// \param Triple This argument is used to determine the target machine
+ /// feature set; it should always be provided. Generally this should be
+ /// either the target triple from the module, or the target triple of the
+ /// host if that does not exist.
+ MCAsmInfo *createMCAsmInfo(const MCRegisterInfo &MRI,
+ StringRef Triple) const {
+ if (!MCAsmInfoCtorFn)
+ return nullptr;
+ return MCAsmInfoCtorFn(MRI, Triple);
+ }
+
+ /// createMCCodeGenInfo - Create a MCCodeGenInfo implementation.
+ ///
+ MCCodeGenInfo *createMCCodeGenInfo(StringRef Triple, Reloc::Model RM,
+ CodeModel::Model CM,
+ CodeGenOpt::Level OL) const {
+ if (!MCCodeGenInfoCtorFn)
+ return nullptr;
+ return MCCodeGenInfoCtorFn(Triple, RM, CM, OL);
+ }
+
+ /// createMCInstrInfo - Create a MCInstrInfo implementation.
+ ///
+ MCInstrInfo *createMCInstrInfo() const {
+ if (!MCInstrInfoCtorFn)
+ return nullptr;
+ return MCInstrInfoCtorFn();
+ }
+ /// createMCInstrAnalysis - Create a MCInstrAnalysis implementation.
+ ///
+ MCInstrAnalysis *createMCInstrAnalysis(const MCInstrInfo *Info) const {
+ if (!MCInstrAnalysisCtorFn)
+ return nullptr;
+ return MCInstrAnalysisCtorFn(Info);
+ }
- /// createMCCodeEmitter - Create a target specific code emitter.
- MCCodeEmitter *createMCCodeEmitter(const MCInstrInfo &II,
- const MCRegisterInfo &MRI,
- const MCSubtargetInfo &STI,
+ /// createMCRegInfo - Create a MCRegisterInfo implementation.
+ ///
+ MCRegisterInfo *createMCRegInfo(StringRef Triple) const {
+ if (!MCRegInfoCtorFn)
+ return nullptr;
+ return MCRegInfoCtorFn(Triple);
+ }
+
+ /// createMCSubtargetInfo - Create a MCSubtargetInfo implementation.
+ ///
+ /// \param Triple This argument is used to determine the target machine
+ /// feature set; it should always be provided. Generally this should be
+ /// either the target triple from the module, or the target triple of the
+ /// host if that does not exist.
+ /// \param CPU This specifies the name of the target CPU.
+ /// \param Features This specifies the string representation of the
+ /// additional target features.
+ MCSubtargetInfo *createMCSubtargetInfo(StringRef Triple, StringRef CPU,
+ StringRef Features) const {
+ if (!MCSubtargetInfoCtorFn)
+ return nullptr;
+ return MCSubtargetInfoCtorFn(Triple, CPU, Features);
+ }
+
+ /// createTargetMachine - Create a target specific machine implementation
+ /// for the specified \p Triple.
+ ///
+ /// \param Triple This argument is used to determine the target machine
+ /// feature set; it should always be provided. Generally this should be
+ /// 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,
+ const TargetOptions &Options,
+ Reloc::Model RM = Reloc::Default,
+ CodeModel::Model CM = CodeModel::Default,
+ CodeGenOpt::Level OL = CodeGenOpt::Default) const {
+ if (!TargetMachineCtorFn)
+ return nullptr;
+ return TargetMachineCtorFn(*this, Triple, CPU, Features, Options, RM, CM,
+ OL);
+ }
+
+ /// createMCAsmBackend - Create a target specific assembly parser.
+ ///
+ /// \param Triple The target triple string.
+ MCAsmBackend *createMCAsmBackend(const MCRegisterInfo &MRI, StringRef Triple,
+ StringRef CPU) const {
+ if (!MCAsmBackendCtorFn)
+ return nullptr;
+ return MCAsmBackendCtorFn(*this, MRI, Triple, CPU);
+ }
+
+ /// createMCAsmParser - Create a target specific assembly parser.
+ ///
+ /// \param Parser The target independent parser implementation to use for
+ /// parsing and lexing.
+ MCTargetAsmParser *createMCAsmParser(MCSubtargetInfo &STI,
+ MCAsmParser &Parser,
+ const MCInstrInfo &MII,
+ const MCTargetOptions &Options) const {
+ if (!MCAsmParserCtorFn)
+ return nullptr;
+ return MCAsmParserCtorFn(STI, Parser, MII, Options);
+ }
+
+ /// createAsmPrinter - Create a target specific assembly printer pass. This
+ /// takes ownership of the MCStreamer object.
+ AsmPrinter *createAsmPrinter(TargetMachine &TM,
+ std::unique_ptr<MCStreamer> &&Streamer) const {
+ if (!AsmPrinterCtorFn)
+ return nullptr;
+ return AsmPrinterCtorFn(TM, std::move(Streamer));
+ }
+
+ MCDisassembler *createMCDisassembler(const MCSubtargetInfo &STI,
MCContext &Ctx) const {
- if (!MCCodeEmitterCtorFn)
- return nullptr;
- return MCCodeEmitterCtorFn(II, MRI, STI, Ctx);
- }
+ if (!MCDisassemblerCtorFn)
+ return nullptr;
+ return MCDisassemblerCtorFn(*this, STI, Ctx);
+ }
+
+ MCInstPrinter *createMCInstPrinter(const Triple &T, unsigned SyntaxVariant,
+ const MCAsmInfo &MAI,
+ const MCInstrInfo &MII,
+ const MCRegisterInfo &MRI) const {
+ if (!MCInstPrinterCtorFn)
+ return nullptr;
+ return MCInstPrinterCtorFn(T, SyntaxVariant, MAI, MII, MRI);
+ }
+
+ /// createMCCodeEmitter - Create a target specific code emitter.
+ MCCodeEmitter *createMCCodeEmitter(const MCInstrInfo &II,
+ const MCRegisterInfo &MRI,
+ MCContext &Ctx) const {
+ if (!MCCodeEmitterCtorFn)
+ return nullptr;
+ return MCCodeEmitterCtorFn(II, MRI, Ctx);
+ }
+
+ /// Create a target specific MCStreamer.
+ ///
+ /// \param T The target triple.
+ /// \param Ctx The target context.
+ /// \param TAB The target assembler backend object. Takes ownership.
+ /// \param OS The stream object.
+ /// \param Emitter The target independent assembler object.Takes ownership.
+ /// \param RelaxAll Relax all fixups?
+ MCStreamer *createMCObjectStreamer(const Triple &T, MCContext &Ctx,
+ MCAsmBackend &TAB, raw_pwrite_stream &OS,
+ MCCodeEmitter *Emitter,
+ const MCSubtargetInfo &STI, bool RelaxAll,
+ bool DWARFMustBeAtTheEnd) const {
+ MCStreamer *S;
+ switch (T.getObjectFormat()) {
+ default:
+ llvm_unreachable("Unknown object format");
+ case Triple::COFF:
+ assert(T.isOSWindows() && "only Windows COFF is supported");
+ S = COFFStreamerCtorFn(Ctx, TAB, OS, Emitter, RelaxAll);
+ break;
+ case Triple::MachO:
+ if (MachOStreamerCtorFn)
+ S = MachOStreamerCtorFn(Ctx, TAB, OS, Emitter, RelaxAll,
+ DWARFMustBeAtTheEnd);
+ else
+ S = createMachOStreamer(Ctx, TAB, OS, Emitter, RelaxAll,
+ DWARFMustBeAtTheEnd);
+ break;
+ case Triple::ELF:
+ if (ELFStreamerCtorFn)
+ S = ELFStreamerCtorFn(T, Ctx, TAB, OS, Emitter, RelaxAll);
+ else
+ S = createELFStreamer(Ctx, TAB, OS, Emitter, RelaxAll);
+ break;
+ }
+ if (ObjectTargetStreamerCtorFn)
+ ObjectTargetStreamerCtorFn(*S, STI);
+ return S;
+ }
+
+ MCStreamer *createAsmStreamer(MCContext &Ctx,
+ std::unique_ptr<formatted_raw_ostream> OS,
+ bool IsVerboseAsm, bool UseDwarfDirectory,
+ MCInstPrinter *InstPrint, MCCodeEmitter *CE,
+ MCAsmBackend *TAB, bool ShowInst) const {
+ formatted_raw_ostream &OSRef = *OS;
+ MCStreamer *S = llvm::createAsmStreamer(Ctx, std::move(OS), IsVerboseAsm,
+ UseDwarfDirectory, InstPrint, CE,
+ TAB, ShowInst);
+ createAsmTargetStreamer(*S, OSRef, InstPrint, IsVerboseAsm);
+ return S;
+ }
+
+ MCTargetStreamer *createAsmTargetStreamer(MCStreamer &S,
+ formatted_raw_ostream &OS,
+ MCInstPrinter *InstPrint,
+ bool IsVerboseAsm) const {
+ if (AsmTargetStreamerCtorFn)
+ return AsmTargetStreamerCtorFn(S, OS, InstPrint, IsVerboseAsm);
+ return nullptr;
+ }
+
+ MCStreamer *createNullStreamer(MCContext &Ctx) const {
+ MCStreamer *S = llvm::createNullStreamer(Ctx);
+ createNullTargetStreamer(*S);
+ return S;
+ }
+
+ MCTargetStreamer *createNullTargetStreamer(MCStreamer &S) const {
+ if (NullTargetStreamerCtorFn)
+ return NullTargetStreamerCtorFn(S);
+ return nullptr;
+ }
+
+ /// createMCRelocationInfo - Create a target specific MCRelocationInfo.
+ ///
+ /// \param TT The target triple.
+ /// \param Ctx The target context.
+ MCRelocationInfo *createMCRelocationInfo(StringRef TT, MCContext &Ctx) const {
+ MCRelocationInfoCtorTy Fn = MCRelocationInfoCtorFn
+ ? MCRelocationInfoCtorFn
+ : llvm::createMCRelocationInfo;
+ return Fn(TT, Ctx);
+ }
+
+ /// createMCSymbolizer - Create a target specific MCSymbolizer.
+ ///
+ /// \param TT The target triple.
+ /// \param GetOpInfo The function to get the symbolic information for
+ /// operands.
+ /// \param SymbolLookUp The function to lookup a symbol name.
+ /// \param DisInfo The pointer to the block of symbolic information for above
+ /// call
+ /// back.
+ /// \param Ctx The target context.
+ /// \param RelInfo The relocation information for this target. Takes
+ /// ownership.
+ MCSymbolizer *
+ createMCSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo,
+ LLVMSymbolLookupCallback SymbolLookUp, void *DisInfo,
+ MCContext *Ctx,
+ std::unique_ptr<MCRelocationInfo> &&RelInfo) const {
+ MCSymbolizerCtorTy Fn =
+ MCSymbolizerCtorFn ? MCSymbolizerCtorFn : llvm::createMCSymbolizer;
+ return Fn(TT, GetOpInfo, SymbolLookUp, DisInfo, Ctx, std::move(RelInfo));
+ }
+
+ /// @}
+};
+
+/// TargetRegistry - Generic interface to target specific features.
+struct TargetRegistry {
+ // FIXME: Make this a namespace, probably just move all the Register*
+ // functions into Target (currently they all just set members on the Target
+ // anyway, and Target friends this class so those functions can...
+ // function).
+ TargetRegistry() = delete;
+
+ class iterator
+ : public std::iterator<std::forward_iterator_tag, Target, ptrdiff_t> {
+ const Target *Current;
+ explicit iterator(Target *T) : Current(T) {}
+ friend struct TargetRegistry;
- /// createMCObjectStreamer - Create a target specific MCStreamer.
- ///
- /// \param TT The target triple.
- /// \param Ctx The target context.
- /// \param TAB The target assembler backend object. Takes ownership.
- /// \param _OS The stream object.
- /// \param _Emitter The target independent assembler object.Takes ownership.
- /// \param RelaxAll Relax all fixups?
- MCStreamer *createMCObjectStreamer(StringRef TT, MCContext &Ctx,
- MCAsmBackend &TAB, raw_ostream &_OS,
- MCCodeEmitter *_Emitter,
- const MCSubtargetInfo &STI,
- bool RelaxAll) const {
- if (!MCObjectStreamerCtorFn)
- return nullptr;
- return MCObjectStreamerCtorFn(*this, TT, Ctx, TAB, _OS, _Emitter, STI,
- RelaxAll);
- }
+ public:
+ iterator() : Current(nullptr) {}
- /// createAsmStreamer - Create a target specific MCStreamer.
- MCStreamer *createAsmStreamer(MCContext &Ctx,
- formatted_raw_ostream &OS,
- bool isVerboseAsm,
- bool useDwarfDirectory,
- MCInstPrinter *InstPrint,
- MCCodeEmitter *CE,
- MCAsmBackend *TAB,
- bool ShowInst) const {
- if (AsmStreamerCtorFn)
- return AsmStreamerCtorFn(Ctx, OS, isVerboseAsm, useDwarfDirectory,
- InstPrint, CE, TAB, ShowInst);
- return llvm::createAsmStreamer(Ctx, OS, isVerboseAsm, useDwarfDirectory,
- InstPrint, CE, TAB, ShowInst);
- }
+ bool operator==(const iterator &x) const { return Current == x.Current; }
+ bool operator!=(const iterator &x) const { return !operator==(x); }
- MCStreamer *createNullStreamer(MCContext &Ctx) const {
- if (NullStreamerCtorFn)
- return NullStreamerCtorFn(Ctx);
- return llvm::createNullStreamer(Ctx);
+ // Iterator traversal: forward iteration only
+ iterator &operator++() { // Preincrement
+ assert(Current && "Cannot increment end iterator!");
+ Current = Current->getNext();
+ return *this;
}
-
- /// createMCRelocationInfo - Create a target specific MCRelocationInfo.
- ///
- /// \param TT The target triple.
- /// \param Ctx The target context.
- MCRelocationInfo *
- createMCRelocationInfo(StringRef TT, MCContext &Ctx) const {
- MCRelocationInfoCtorTy Fn = MCRelocationInfoCtorFn
- ? MCRelocationInfoCtorFn
- : llvm::createMCRelocationInfo;
- return Fn(TT, Ctx);
+ iterator operator++(int) { // Postincrement
+ iterator tmp = *this;
+ ++*this;
+ return tmp;
}
- /// createMCSymbolizer - Create a target specific MCSymbolizer.
- ///
- /// \param TT The target triple.
- /// \param GetOpInfo The function to get the symbolic information for operands.
- /// \param SymbolLookUp The function to lookup a symbol name.
- /// \param DisInfo The pointer to the block of symbolic information for above call
- /// back.
- /// \param Ctx The target context.
- /// \param RelInfo The relocation information for this target. Takes ownership.
- MCSymbolizer *
- createMCSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo,
- LLVMSymbolLookupCallback SymbolLookUp,
- void *DisInfo,
- MCContext *Ctx, MCRelocationInfo *RelInfo) const {
- MCSymbolizerCtorTy Fn =
- MCSymbolizerCtorFn ? MCSymbolizerCtorFn : llvm::createMCSymbolizer;
- return Fn(TT, GetOpInfo, SymbolLookUp, DisInfo, Ctx, RelInfo);
+ const Target &operator*() const {
+ assert(Current && "Cannot dereference end iterator!");
+ return *Current;
}
- /// @}
+ const Target *operator->() const { return &operator*(); }
};
- /// TargetRegistry - Generic interface to target specific features.
- struct TargetRegistry {
- class iterator {
- const Target *Current;
- explicit iterator(Target *T) : Current(T) {}
- friend struct TargetRegistry;
- public:
- iterator() : Current(nullptr) {}
-
- bool operator==(const iterator &x) const {
- return Current == x.Current;
- }
- bool operator!=(const iterator &x) const {
- return !operator==(x);
- }
-
- // Iterator traversal: forward iteration only
- iterator &operator++() { // Preincrement
- assert(Current && "Cannot increment end iterator!");
- Current = Current->getNext();
- return *this;
- }
- iterator operator++(int) { // Postincrement
- iterator tmp = *this;
- ++*this;
- return tmp;
- }
-
- const Target &operator*() const {
- assert(Current && "Cannot dereference end iterator!");
- return *Current;
- }
-
- const Target *operator->() const {
- return &operator*();
- }
- };
-
- /// printRegisteredTargetsForVersion - Print the registered targets
- /// appropriately for inclusion in a tool's version output.
- static void printRegisteredTargetsForVersion();
-
- /// @name Registry Access
- /// @{
-
- static iterator begin();
-
- static iterator end() { return iterator(); }
-
- /// lookupTarget - Lookup a target based on a target triple.
- ///
- /// \param Triple - The triple to use for finding a target.
- /// \param Error - On failure, an error string describing why no target was
- /// found.
- static const Target *lookupTarget(const std::string &Triple,
- std::string &Error);
-
- /// lookupTarget - Lookup a target based on an architecture name
- /// and a target triple. If the architecture name is non-empty,
- /// then the lookup is done by architecture. Otherwise, the target
- /// triple is used.
- ///
- /// \param ArchName - The architecture to use for finding a target.
- /// \param TheTriple - The triple to use for finding a target. The
- /// triple is updated with canonical architecture name if a lookup
- /// by architecture is done.
- /// \param Error - On failure, an error string describing why no target was
- /// found.
- static const Target *lookupTarget(const std::string &ArchName,
- Triple &TheTriple,
- std::string &Error);
-
- /// @}
- /// @name Target Registration
- /// @{
-
- /// RegisterTarget - Register the given target. Attempts to register a
- /// target which has already been registered will be ignored.
- ///
- /// Clients are responsible for ensuring that registration doesn't occur
- /// while another thread is attempting to access the registry. Typically
- /// this is done by initializing all targets at program startup.
- ///
- /// @param T - The target being registered.
- /// @param Name - The target name. This should be a static string.
- /// @param ShortDesc - A short target description. This should be a static
- /// string.
- /// @param ArchMatchFn - The arch match checking function for this target.
- /// @param HasJIT - Whether the target supports JIT code
- /// generation.
- static void RegisterTarget(Target &T,
- const char *Name,
- const char *ShortDesc,
- Target::ArchMatchFnTy ArchMatchFn,
- bool HasJIT = false);
-
- /// RegisterMCAsmInfo - Register a MCAsmInfo implementation for the
- /// given target.
- ///
- /// Clients are responsible for ensuring that registration doesn't occur
- /// while another thread is attempting to access the registry. Typically
- /// this is done by initializing all targets at program startup.
- ///
- /// @param T - The target being registered.
- /// @param Fn - A function to construct a MCAsmInfo for the target.
- static void RegisterMCAsmInfo(Target &T, Target::MCAsmInfoCtorFnTy Fn) {
- T.MCAsmInfoCtorFn = Fn;
- }
-
- /// RegisterMCCodeGenInfo - Register a MCCodeGenInfo implementation for the
- /// given target.
- ///
- /// Clients are responsible for ensuring that registration doesn't occur
- /// while another thread is attempting to access the registry. Typically
- /// this is done by initializing all targets at program startup.
- ///
- /// @param T - The target being registered.
- /// @param Fn - A function to construct a MCCodeGenInfo for the target.
- static void RegisterMCCodeGenInfo(Target &T,
- Target::MCCodeGenInfoCtorFnTy Fn) {
- T.MCCodeGenInfoCtorFn = Fn;
- }
-
- /// RegisterMCInstrInfo - Register a MCInstrInfo implementation for the
- /// given target.
- ///
- /// Clients are responsible for ensuring that registration doesn't occur
- /// while another thread is attempting to access the registry. Typically
- /// this is done by initializing all targets at program startup.
- ///
- /// @param T - The target being registered.
- /// @param Fn - A function to construct a MCInstrInfo for the target.
- static void RegisterMCInstrInfo(Target &T, Target::MCInstrInfoCtorFnTy Fn) {
- T.MCInstrInfoCtorFn = Fn;
- }
-
- /// RegisterMCInstrAnalysis - Register a MCInstrAnalysis implementation for
- /// the given target.
- static void RegisterMCInstrAnalysis(Target &T,
- Target::MCInstrAnalysisCtorFnTy Fn) {
- T.MCInstrAnalysisCtorFn = Fn;
- }
-
- /// RegisterMCRegInfo - Register a MCRegisterInfo implementation for the
- /// given target.
- ///
- /// Clients are responsible for ensuring that registration doesn't occur
- /// while another thread is attempting to access the registry. Typically
- /// this is done by initializing all targets at program startup.
- ///
- /// @param T - The target being registered.
- /// @param Fn - A function to construct a MCRegisterInfo for the target.
- static void RegisterMCRegInfo(Target &T, Target::MCRegInfoCtorFnTy Fn) {
- T.MCRegInfoCtorFn = Fn;
- }
-
- /// RegisterMCSubtargetInfo - Register a MCSubtargetInfo implementation for
- /// the given target.
- ///
- /// Clients are responsible for ensuring that registration doesn't occur
- /// while another thread is attempting to access the registry. Typically
- /// this is done by initializing all targets at program startup.
- ///
- /// @param T - The target being registered.
- /// @param Fn - A function to construct a MCSubtargetInfo for the target.
- static void RegisterMCSubtargetInfo(Target &T,
- Target::MCSubtargetInfoCtorFnTy Fn) {
- T.MCSubtargetInfoCtorFn = Fn;
- }
-
- /// RegisterTargetMachine - Register a TargetMachine implementation for the
- /// given target.
- ///
- /// Clients are responsible for ensuring that registration doesn't occur
- /// while another thread is attempting to access the registry. Typically
- /// this is done by initializing all targets at program startup.
- ///
- /// @param T - The target being registered.
- /// @param Fn - A function to construct a TargetMachine for the target.
- static void RegisterTargetMachine(Target &T,
- Target::TargetMachineCtorTy Fn) {
- T.TargetMachineCtorFn = Fn;
- }
-
- /// RegisterMCAsmBackend - Register a MCAsmBackend implementation for the
- /// given target.
- ///
- /// Clients are responsible for ensuring that registration doesn't occur
- /// while another thread is attempting to access the registry. Typically
- /// this is done by initializing all targets at program startup.
- ///
- /// @param T - The target being registered.
- /// @param Fn - A function to construct an AsmBackend for the target.
- static void RegisterMCAsmBackend(Target &T, Target::MCAsmBackendCtorTy Fn) {
- T.MCAsmBackendCtorFn = Fn;
- }
-
- /// RegisterMCAsmParser - Register a MCTargetAsmParser implementation for
- /// the given target.
- ///
- /// Clients are responsible for ensuring that registration doesn't occur
- /// while another thread is attempting to access the registry. Typically
- /// this is done by initializing all targets at program startup.
- ///
- /// @param T - The target being registered.
- /// @param Fn - A function to construct an MCTargetAsmParser for the target.
- static void RegisterMCAsmParser(Target &T, Target::MCAsmParserCtorTy Fn) {
- T.MCAsmParserCtorFn = Fn;
- }
-
- /// RegisterAsmPrinter - Register an AsmPrinter implementation for the given
- /// target.
- ///
- /// Clients are responsible for ensuring that registration doesn't occur
- /// while another thread is attempting to access the registry. Typically
- /// this is done by initializing all targets at program startup.
- ///
- /// @param T - The target being registered.
- /// @param Fn - A function to construct an AsmPrinter for the target.
- static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn) {
- T.AsmPrinterCtorFn = Fn;
- }
-
- /// RegisterMCDisassembler - Register a MCDisassembler implementation for
- /// the given target.
- ///
- /// Clients are responsible for ensuring that registration doesn't occur
- /// while another thread is attempting to access the registry. Typically
- /// this is done by initializing all targets at program startup.
- ///
- /// @param T - The target being registered.
- /// @param Fn - A function to construct an MCDisassembler for the target.
- static void RegisterMCDisassembler(Target &T,
- Target::MCDisassemblerCtorTy Fn) {
- T.MCDisassemblerCtorFn = Fn;
- }
+ /// printRegisteredTargetsForVersion - Print the registered targets
+ /// appropriately for inclusion in a tool's version output.
+ static void printRegisteredTargetsForVersion();
- /// RegisterMCInstPrinter - Register a MCInstPrinter implementation for the
- /// given target.
- ///
- /// Clients are responsible for ensuring that registration doesn't occur
- /// while another thread is attempting to access the registry. Typically
- /// this is done by initializing all targets at program startup.
- ///
- /// @param T - The target being registered.
- /// @param Fn - A function to construct an MCInstPrinter for the target.
- static void RegisterMCInstPrinter(Target &T,
- Target::MCInstPrinterCtorTy Fn) {
- T.MCInstPrinterCtorFn = Fn;
- }
+ /// @name Registry Access
+ /// @{
- /// RegisterMCCodeEmitter - Register a MCCodeEmitter implementation for the
- /// given target.
- ///
- /// Clients are responsible for ensuring that registration doesn't occur
- /// while another thread is attempting to access the registry. Typically
- /// this is done by initializing all targets at program startup.
- ///
- /// @param T - The target being registered.
- /// @param Fn - A function to construct an MCCodeEmitter for the target.
- static void RegisterMCCodeEmitter(Target &T,
- Target::MCCodeEmitterCtorTy Fn) {
- T.MCCodeEmitterCtorFn = Fn;
- }
+ static iterator_range<iterator> targets();
- /// RegisterMCObjectStreamer - Register a object code MCStreamer
- /// implementation for the given target.
- ///
- /// Clients are responsible for ensuring that registration doesn't occur
- /// while another thread is attempting to access the registry. Typically
- /// this is done by initializing all targets at program startup.
- ///
- /// @param T - The target being registered.
- /// @param Fn - A function to construct an MCStreamer for the target.
- static void RegisterMCObjectStreamer(Target &T,
- Target::MCObjectStreamerCtorTy Fn) {
- T.MCObjectStreamerCtorFn = Fn;
- }
-
- /// RegisterAsmStreamer - Register an assembly MCStreamer implementation
- /// for the given target.
- ///
- /// Clients are responsible for ensuring that registration doesn't occur
- /// while another thread is attempting to access the registry. Typically
- /// this is done by initializing all targets at program startup.
- ///
- /// @param T - The target being registered.
- /// @param Fn - A function to construct an MCStreamer for the target.
- static void RegisterAsmStreamer(Target &T, Target::AsmStreamerCtorTy Fn) {
- T.AsmStreamerCtorFn = Fn;
- }
-
- static void RegisterNullStreamer(Target &T, Target::NullStreamerCtorTy Fn) {
- T.NullStreamerCtorFn = Fn;
- }
-
- /// RegisterMCRelocationInfo - Register an MCRelocationInfo
- /// implementation for the given target.
- ///
- /// Clients are responsible for ensuring that registration doesn't occur
- /// while another thread is attempting to access the registry. Typically
- /// this is done by initializing all targets at program startup.
- ///
- /// @param T - The target being registered.
- /// @param Fn - A function to construct an MCRelocationInfo for the target.
- static void RegisterMCRelocationInfo(Target &T,
- Target::MCRelocationInfoCtorTy Fn) {
- T.MCRelocationInfoCtorFn = Fn;
- }
-
- /// RegisterMCSymbolizer - Register an MCSymbolizer
- /// implementation for the given target.
- ///
- /// Clients are responsible for ensuring that registration doesn't occur
- /// while another thread is attempting to access the registry. Typically
- /// this is done by initializing all targets at program startup.
- ///
- /// @param T - The target being registered.
- /// @param Fn - A function to construct an MCSymbolizer for the target.
- static void RegisterMCSymbolizer(Target &T,
- Target::MCSymbolizerCtorTy Fn) {
- T.MCSymbolizerCtorFn = Fn;
- }
-
- /// @}
- };
-
-
- //===--------------------------------------------------------------------===//
-
- /// RegisterTarget - Helper template for registering a target, for use in the
- /// target's initialization function. Usage:
+ /// lookupTarget - Lookup a target based on a target triple.
///
+ /// \param Triple - The triple to use for finding a target.
+ /// \param Error - On failure, an error string describing why no target was
+ /// found.
+ static const Target *lookupTarget(const std::string &Triple,
+ std::string &Error);
+
+ /// lookupTarget - Lookup a target based on an architecture name
+ /// and a target triple. If the architecture name is non-empty,
+ /// then the lookup is done by architecture. Otherwise, the target
+ /// triple is used.
///
- /// Target TheFooTarget; // The global target instance.
+ /// \param ArchName - The architecture to use for finding a target.
+ /// \param TheTriple - The triple to use for finding a target. The
+ /// triple is updated with canonical architecture name if a lookup
+ /// by architecture is done.
+ /// \param Error - On failure, an error string describing why no target was
+ /// found.
+ static const Target *lookupTarget(const std::string &ArchName,
+ Triple &TheTriple, std::string &Error);
+
+ /// @}
+ /// @name Target Registration
+ /// @{
+
+ /// RegisterTarget - Register the given target. Attempts to register a
+ /// target which has already been registered will be ignored.
///
- /// extern "C" void LLVMInitializeFooTargetInfo() {
- /// RegisterTarget<Triple::foo> X(TheFooTarget, "foo", "Foo description");
- /// }
- template<Triple::ArchType TargetArchType = Triple::UnknownArch,
- bool HasJIT = false>
- struct RegisterTarget {
- RegisterTarget(Target &T, const char *Name, const char *Desc) {
- TargetRegistry::RegisterTarget(T, Name, Desc, &getArchMatch, HasJIT);
- }
-
- static bool getArchMatch(Triple::ArchType Arch) {
- return Arch == TargetArchType;
- }
- };
-
- /// RegisterMCAsmInfo - Helper template for registering a target assembly info
- /// implementation. This invokes the static "Create" method on the class to
- /// actually do the construction. Usage:
+ /// Clients are responsible for ensuring that registration doesn't occur
+ /// while another thread is attempting to access the registry. Typically
+ /// this is done by initializing all targets at program startup.
///
- /// extern "C" void LLVMInitializeFooTarget() {
- /// extern Target TheFooTarget;
- /// RegisterMCAsmInfo<FooMCAsmInfo> X(TheFooTarget);
- /// }
- template<class MCAsmInfoImpl>
- struct RegisterMCAsmInfo {
- RegisterMCAsmInfo(Target &T) {
- TargetRegistry::RegisterMCAsmInfo(T, &Allocator);
- }
- private:
- static MCAsmInfo *Allocator(const MCRegisterInfo &/*MRI*/, StringRef TT) {
- return new MCAsmInfoImpl(TT);
- }
-
- };
-
- /// RegisterMCAsmInfoFn - Helper template for registering a target assembly info
- /// implementation. This invokes the specified function to do the
- /// construction. Usage:
+ /// @param T - The target being registered.
+ /// @param Name - The target name. This should be a static string.
+ /// @param ShortDesc - A short target description. This should be a static
+ /// string.
+ /// @param ArchMatchFn - The arch match checking function for this target.
+ /// @param HasJIT - Whether the target supports JIT code
+ /// generation.
+ static void RegisterTarget(Target &T, const char *Name, const char *ShortDesc,
+ Target::ArchMatchFnTy ArchMatchFn,
+ bool HasJIT = false);
+
+ /// RegisterMCAsmInfo - Register a MCAsmInfo implementation for the
+ /// given target.
///
- /// extern "C" void LLVMInitializeFooTarget() {
- /// extern Target TheFooTarget;
- /// RegisterMCAsmInfoFn X(TheFooTarget, TheFunction);
- /// }
- struct RegisterMCAsmInfoFn {
- RegisterMCAsmInfoFn(Target &T, Target::MCAsmInfoCtorFnTy Fn) {
- TargetRegistry::RegisterMCAsmInfo(T, Fn);
- }
- };
-
- /// RegisterMCCodeGenInfo - Helper template for registering a target codegen info
- /// implementation. This invokes the static "Create" method on the class
- /// to actually do the construction. Usage:
+ /// Clients are responsible for ensuring that registration doesn't occur
+ /// while another thread is attempting to access the registry. Typically
+ /// this is done by initializing all targets at program startup.
///
- /// extern "C" void LLVMInitializeFooTarget() {
- /// extern Target TheFooTarget;
- /// RegisterMCCodeGenInfo<FooMCCodeGenInfo> X(TheFooTarget);
- /// }
- template<class MCCodeGenInfoImpl>
- struct RegisterMCCodeGenInfo {
- RegisterMCCodeGenInfo(Target &T) {
- TargetRegistry::RegisterMCCodeGenInfo(T, &Allocator);
- }
- private:
- static MCCodeGenInfo *Allocator(StringRef /*TT*/, Reloc::Model /*RM*/,
- CodeModel::Model /*CM*/,
- CodeGenOpt::Level /*OL*/) {
- return new MCCodeGenInfoImpl();
- }
- };
-
- /// RegisterMCCodeGenInfoFn - Helper template for registering a target codegen
- /// info implementation. This invokes the specified function to do the
- /// construction. Usage:
+ /// @param T - The target being registered.
+ /// @param Fn - A function to construct a MCAsmInfo for the target.
+ static void RegisterMCAsmInfo(Target &T, Target::MCAsmInfoCtorFnTy Fn) {
+ T.MCAsmInfoCtorFn = Fn;
+ }
+
+ /// RegisterMCCodeGenInfo - Register a MCCodeGenInfo implementation for the
+ /// given target.
///
- /// extern "C" void LLVMInitializeFooTarget() {
- /// extern Target TheFooTarget;
- /// RegisterMCCodeGenInfoFn X(TheFooTarget, TheFunction);
- /// }
- struct RegisterMCCodeGenInfoFn {
- RegisterMCCodeGenInfoFn(Target &T, Target::MCCodeGenInfoCtorFnTy Fn) {
- TargetRegistry::RegisterMCCodeGenInfo(T, Fn);
- }
- };
-
- /// RegisterMCInstrInfo - Helper template for registering a target instruction
- /// info implementation. This invokes the static "Create" method on the class
- /// to actually do the construction. Usage:
+ /// Clients are responsible for ensuring that registration doesn't occur
+ /// while another thread is attempting to access the registry. Typically
+ /// this is done by initializing all targets at program startup.
///
- /// extern "C" void LLVMInitializeFooTarget() {
- /// extern Target TheFooTarget;
- /// RegisterMCInstrInfo<FooMCInstrInfo> X(TheFooTarget);
- /// }
- template<class MCInstrInfoImpl>
- struct RegisterMCInstrInfo {
- RegisterMCInstrInfo(Target &T) {
- TargetRegistry::RegisterMCInstrInfo(T, &Allocator);
- }
- private:
- static MCInstrInfo *Allocator() {
- return new MCInstrInfoImpl();
- }
- };
-
- /// RegisterMCInstrInfoFn - Helper template for registering a target
- /// instruction info implementation. This invokes the specified function to
- /// do the construction. Usage:
+ /// @param T - The target being registered.
+ /// @param Fn - A function to construct a MCCodeGenInfo for the target.
+ static void RegisterMCCodeGenInfo(Target &T,
+ Target::MCCodeGenInfoCtorFnTy Fn) {
+ T.MCCodeGenInfoCtorFn = Fn;
+ }
+
+ /// RegisterMCInstrInfo - Register a MCInstrInfo implementation for the
+ /// given target.
///
- /// extern "C" void LLVMInitializeFooTarget() {
- /// extern Target TheFooTarget;
- /// RegisterMCInstrInfoFn X(TheFooTarget, TheFunction);
- /// }
- struct RegisterMCInstrInfoFn {
- RegisterMCInstrInfoFn(Target &T, Target::MCInstrInfoCtorFnTy Fn) {
- TargetRegistry::RegisterMCInstrInfo(T, Fn);
- }
- };
-
- /// RegisterMCInstrAnalysis - Helper template for registering a target
- /// instruction analyzer implementation. This invokes the static "Create"
- /// method on the class to actually do the construction. Usage:
+ /// Clients are responsible for ensuring that registration doesn't occur
+ /// while another thread is attempting to access the registry. Typically
+ /// this is done by initializing all targets at program startup.
///
- /// extern "C" void LLVMInitializeFooTarget() {
- /// extern Target TheFooTarget;
- /// RegisterMCInstrAnalysis<FooMCInstrAnalysis> X(TheFooTarget);
- /// }
- template<class MCInstrAnalysisImpl>
- struct RegisterMCInstrAnalysis {
- RegisterMCInstrAnalysis(Target &T) {
- TargetRegistry::RegisterMCInstrAnalysis(T, &Allocator);
- }
- private:
- static MCInstrAnalysis *Allocator(const MCInstrInfo *Info) {
- return new MCInstrAnalysisImpl(Info);
- }
- };
-
- /// RegisterMCInstrAnalysisFn - Helper template for registering a target
- /// instruction analyzer implementation. This invokes the specified function
- /// to do the construction. Usage:
+ /// @param T - The target being registered.
+ /// @param Fn - A function to construct a MCInstrInfo for the target.
+ static void RegisterMCInstrInfo(Target &T, Target::MCInstrInfoCtorFnTy Fn) {
+ T.MCInstrInfoCtorFn = Fn;
+ }
+
+ /// RegisterMCInstrAnalysis - Register a MCInstrAnalysis implementation for
+ /// the given target.
+ static void RegisterMCInstrAnalysis(Target &T,
+ Target::MCInstrAnalysisCtorFnTy Fn) {
+ T.MCInstrAnalysisCtorFn = Fn;
+ }
+
+ /// RegisterMCRegInfo - Register a MCRegisterInfo implementation for the
+ /// given target.
///
- /// extern "C" void LLVMInitializeFooTarget() {
- /// extern Target TheFooTarget;
- /// RegisterMCInstrAnalysisFn X(TheFooTarget, TheFunction);
- /// }
- struct RegisterMCInstrAnalysisFn {
- RegisterMCInstrAnalysisFn(Target &T, Target::MCInstrAnalysisCtorFnTy Fn) {
- TargetRegistry::RegisterMCInstrAnalysis(T, Fn);
- }
- };
-
- /// RegisterMCRegInfo - Helper template for registering a target register info
- /// implementation. This invokes the static "Create" method on the class to
- /// actually do the construction. Usage:
+ /// Clients are responsible for ensuring that registration doesn't occur
+ /// while another thread is attempting to access the registry. Typically
+ /// this is done by initializing all targets at program startup.
///
- /// extern "C" void LLVMInitializeFooTarget() {
- /// extern Target TheFooTarget;
- /// RegisterMCRegInfo<FooMCRegInfo> X(TheFooTarget);
- /// }
- template<class MCRegisterInfoImpl>
- struct RegisterMCRegInfo {
- RegisterMCRegInfo(Target &T) {
- TargetRegistry::RegisterMCRegInfo(T, &Allocator);
- }
- private:
- static MCRegisterInfo *Allocator(StringRef /*TT*/) {
- return new MCRegisterInfoImpl();
- }
- };
-
- /// RegisterMCRegInfoFn - Helper template for registering a target register
- /// info implementation. This invokes the specified function to do the
- /// construction. Usage:
+ /// @param T - The target being registered.
+ /// @param Fn - A function to construct a MCRegisterInfo for the target.
+ static void RegisterMCRegInfo(Target &T, Target::MCRegInfoCtorFnTy Fn) {
+ T.MCRegInfoCtorFn = Fn;
+ }
+
+ /// RegisterMCSubtargetInfo - Register a MCSubtargetInfo implementation for
+ /// the given target.
///
- /// extern "C" void LLVMInitializeFooTarget() {
- /// extern Target TheFooTarget;
- /// RegisterMCRegInfoFn X(TheFooTarget, TheFunction);
- /// }
- struct RegisterMCRegInfoFn {
- RegisterMCRegInfoFn(Target &T, Target::MCRegInfoCtorFnTy Fn) {
- TargetRegistry::RegisterMCRegInfo(T, Fn);
- }
- };
-
- /// RegisterMCSubtargetInfo - Helper template for registering a target
- /// subtarget info implementation. This invokes the static "Create" method
- /// on the class to actually do the construction. Usage:
+ /// Clients are responsible for ensuring that registration doesn't occur
+ /// while another thread is attempting to access the registry. Typically
+ /// this is done by initializing all targets at program startup.
///
- /// extern "C" void LLVMInitializeFooTarget() {
- /// extern Target TheFooTarget;
- /// RegisterMCSubtargetInfo<FooMCSubtargetInfo> X(TheFooTarget);
- /// }
- template<class MCSubtargetInfoImpl>
- struct RegisterMCSubtargetInfo {
- RegisterMCSubtargetInfo(Target &T) {
- TargetRegistry::RegisterMCSubtargetInfo(T, &Allocator);
- }
- private:
- static MCSubtargetInfo *Allocator(StringRef /*TT*/, StringRef /*CPU*/,
- StringRef /*FS*/) {
- return new MCSubtargetInfoImpl();
- }
- };
-
- /// RegisterMCSubtargetInfoFn - Helper template for registering a target
- /// subtarget info implementation. This invokes the specified function to
- /// do the construction. Usage:
+ /// @param T - The target being registered.
+ /// @param Fn - A function to construct a MCSubtargetInfo for the target.
+ static void RegisterMCSubtargetInfo(Target &T,
+ Target::MCSubtargetInfoCtorFnTy Fn) {
+ T.MCSubtargetInfoCtorFn = Fn;
+ }
+
+ /// RegisterTargetMachine - Register a TargetMachine implementation for the
+ /// given target.
///
- /// extern "C" void LLVMInitializeFooTarget() {
- /// extern Target TheFooTarget;
- /// RegisterMCSubtargetInfoFn X(TheFooTarget, TheFunction);
- /// }
- struct RegisterMCSubtargetInfoFn {
- RegisterMCSubtargetInfoFn(Target &T, Target::MCSubtargetInfoCtorFnTy Fn) {
- TargetRegistry::RegisterMCSubtargetInfo(T, Fn);
- }
- };
-
- /// RegisterTargetMachine - Helper template for registering a target machine
- /// implementation, for use in the target machine initialization
- /// function. Usage:
+ /// Clients are responsible for ensuring that registration doesn't occur
+ /// while another thread is attempting to access the registry. Typically
+ /// this is done by initializing all targets at program startup.
///
- /// extern "C" void LLVMInitializeFooTarget() {
- /// extern Target TheFooTarget;
- /// RegisterTargetMachine<FooTargetMachine> X(TheFooTarget);
- /// }
- template<class TargetMachineImpl>
- struct RegisterTargetMachine {
- RegisterTargetMachine(Target &T) {
- TargetRegistry::RegisterTargetMachine(T, &Allocator);
- }
-
- private:
- static TargetMachine *Allocator(const Target &T, StringRef TT,
- StringRef CPU, StringRef FS,
- const TargetOptions &Options,
- Reloc::Model RM,
- CodeModel::Model CM,
- CodeGenOpt::Level OL) {
- return new TargetMachineImpl(T, TT, CPU, FS, Options, RM, CM, OL);
- }
- };
-
- /// RegisterMCAsmBackend - Helper template for registering a target specific
- /// assembler backend. Usage:
+ /// @param T - The target being registered.
+ /// @param Fn - A function to construct a TargetMachine for the target.
+ static void RegisterTargetMachine(Target &T, Target::TargetMachineCtorTy Fn) {
+ T.TargetMachineCtorFn = Fn;
+ }
+
+ /// RegisterMCAsmBackend - Register a MCAsmBackend implementation for the
+ /// given target.
///
- /// extern "C" void LLVMInitializeFooMCAsmBackend() {
- /// extern Target TheFooTarget;
- /// RegisterMCAsmBackend<FooAsmLexer> X(TheFooTarget);
- /// }
- template<class MCAsmBackendImpl>
- struct RegisterMCAsmBackend {
- RegisterMCAsmBackend(Target &T) {
- TargetRegistry::RegisterMCAsmBackend(T, &Allocator);
- }
-
- private:
- static MCAsmBackend *Allocator(const Target &T,
- const MCRegisterInfo &MRI,
- StringRef Triple, StringRef CPU) {
- return new MCAsmBackendImpl(T, MRI, Triple, CPU);
- }
- };
-
- /// RegisterMCAsmParser - Helper template for registering a target specific
- /// assembly parser, for use in the target machine initialization
- /// function. Usage:
+ /// Clients are responsible for ensuring that registration doesn't occur
+ /// while another thread is attempting to access the registry. Typically
+ /// this is done by initializing all targets at program startup.
///
- /// extern "C" void LLVMInitializeFooMCAsmParser() {
- /// extern Target TheFooTarget;
- /// RegisterMCAsmParser<FooAsmParser> X(TheFooTarget);
- /// }
- template<class MCAsmParserImpl>
- struct RegisterMCAsmParser {
- RegisterMCAsmParser(Target &T) {
- TargetRegistry::RegisterMCAsmParser(T, &Allocator);
- }
-
- private:
- static MCTargetAsmParser *Allocator(MCSubtargetInfo &STI, MCAsmParser &P,
- const MCInstrInfo &MII,
- const MCTargetOptions &Options) {
- return new MCAsmParserImpl(STI, P, MII, Options);
- }
- };
-
- /// RegisterAsmPrinter - Helper template for registering a target specific
- /// assembly printer, for use in the target machine initialization
- /// function. Usage:
+ /// @param T - The target being registered.
+ /// @param Fn - A function to construct an AsmBackend for the target.
+ static void RegisterMCAsmBackend(Target &T, Target::MCAsmBackendCtorTy Fn) {
+ T.MCAsmBackendCtorFn = Fn;
+ }
+
+ /// RegisterMCAsmParser - Register a MCTargetAsmParser implementation for
+ /// the given target.
///
- /// extern "C" void LLVMInitializeFooAsmPrinter() {
- /// extern Target TheFooTarget;
- /// RegisterAsmPrinter<FooAsmPrinter> X(TheFooTarget);
- /// }
- template<class AsmPrinterImpl>
- struct RegisterAsmPrinter {
- RegisterAsmPrinter(Target &T) {
- TargetRegistry::RegisterAsmPrinter(T, &Allocator);
- }
-
- private:
- static AsmPrinter *Allocator(TargetMachine &TM, MCStreamer &Streamer) {
- return new AsmPrinterImpl(TM, Streamer);
- }
- };
-
- /// RegisterMCCodeEmitter - Helper template for registering a target specific
- /// machine code emitter, for use in the target initialization
- /// function. Usage:
+ /// Clients are responsible for ensuring that registration doesn't occur
+ /// while another thread is attempting to access the registry. Typically
+ /// this is done by initializing all targets at program startup.
///
- /// extern "C" void LLVMInitializeFooMCCodeEmitter() {
- /// extern Target TheFooTarget;
- /// RegisterMCCodeEmitter<FooCodeEmitter> X(TheFooTarget);
- /// }
- template<class MCCodeEmitterImpl>
- struct RegisterMCCodeEmitter {
- RegisterMCCodeEmitter(Target &T) {
- TargetRegistry::RegisterMCCodeEmitter(T, &Allocator);
- }
-
- private:
- static MCCodeEmitter *Allocator(const MCInstrInfo &/*II*/,
- const MCRegisterInfo &/*MRI*/,
- const MCSubtargetInfo &/*STI*/,
- MCContext &/*Ctx*/) {
- return new MCCodeEmitterImpl();
- }
- };
-
+ /// @param T - The target being registered.
+ /// @param Fn - A function to construct an MCTargetAsmParser for the target.
+ static void RegisterMCAsmParser(Target &T, Target::MCAsmParserCtorTy Fn) {
+ T.MCAsmParserCtorFn = Fn;
+ }
+
+ /// RegisterAsmPrinter - Register an AsmPrinter implementation for the given
+ /// target.
+ ///
+ /// Clients are responsible for ensuring that registration doesn't occur
+ /// while another thread is attempting to access the registry. Typically
+ /// this is done by initializing all targets at program startup.
+ ///
+ /// @param T - The target being registered.
+ /// @param Fn - A function to construct an AsmPrinter for the target.
+ static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn) {
+ T.AsmPrinterCtorFn = Fn;
+ }
+
+ /// RegisterMCDisassembler - Register a MCDisassembler implementation for
+ /// the given target.
+ ///
+ /// Clients are responsible for ensuring that registration doesn't occur
+ /// while another thread is attempting to access the registry. Typically
+ /// this is done by initializing all targets at program startup.
+ ///
+ /// @param T - The target being registered.
+ /// @param Fn - A function to construct an MCDisassembler for the target.
+ static void RegisterMCDisassembler(Target &T,
+ Target::MCDisassemblerCtorTy Fn) {
+ T.MCDisassemblerCtorFn = Fn;
+ }
+
+ /// RegisterMCInstPrinter - Register a MCInstPrinter implementation for the
+ /// given target.
+ ///
+ /// Clients are responsible for ensuring that registration doesn't occur
+ /// while another thread is attempting to access the registry. Typically
+ /// this is done by initializing all targets at program startup.
+ ///
+ /// @param T - The target being registered.
+ /// @param Fn - A function to construct an MCInstPrinter for the target.
+ static void RegisterMCInstPrinter(Target &T, Target::MCInstPrinterCtorTy Fn) {
+ T.MCInstPrinterCtorFn = Fn;
+ }
+
+ /// RegisterMCCodeEmitter - Register a MCCodeEmitter implementation for the
+ /// given target.
+ ///
+ /// Clients are responsible for ensuring that registration doesn't occur
+ /// while another thread is attempting to access the registry. Typically
+ /// this is done by initializing all targets at program startup.
+ ///
+ /// @param T - The target being registered.
+ /// @param Fn - A function to construct an MCCodeEmitter for the target.
+ static void RegisterMCCodeEmitter(Target &T, Target::MCCodeEmitterCtorTy Fn) {
+ T.MCCodeEmitterCtorFn = Fn;
+ }
+
+ static void RegisterCOFFStreamer(Target &T, Target::COFFStreamerCtorTy Fn) {
+ T.COFFStreamerCtorFn = Fn;
+ }
+
+ static void RegisterMachOStreamer(Target &T, Target::MachOStreamerCtorTy Fn) {
+ T.MachOStreamerCtorFn = Fn;
+ }
+
+ static void RegisterELFStreamer(Target &T, Target::ELFStreamerCtorTy Fn) {
+ T.ELFStreamerCtorFn = Fn;
+ }
+
+ static void RegisterNullTargetStreamer(Target &T,
+ Target::NullTargetStreamerCtorTy Fn) {
+ T.NullTargetStreamerCtorFn = Fn;
+ }
+
+ static void RegisterAsmTargetStreamer(Target &T,
+ Target::AsmTargetStreamerCtorTy Fn) {
+ T.AsmTargetStreamerCtorFn = Fn;
+ }
+
+ static void
+ RegisterObjectTargetStreamer(Target &T,
+ Target::ObjectTargetStreamerCtorTy Fn) {
+ T.ObjectTargetStreamerCtorFn = Fn;
+ }
+
+ /// RegisterMCRelocationInfo - Register an MCRelocationInfo
+ /// implementation for the given target.
+ ///
+ /// Clients are responsible for ensuring that registration doesn't occur
+ /// while another thread is attempting to access the registry. Typically
+ /// this is done by initializing all targets at program startup.
+ ///
+ /// @param T - The target being registered.
+ /// @param Fn - A function to construct an MCRelocationInfo for the target.
+ static void RegisterMCRelocationInfo(Target &T,
+ Target::MCRelocationInfoCtorTy Fn) {
+ T.MCRelocationInfoCtorFn = Fn;
+ }
+
+ /// RegisterMCSymbolizer - Register an MCSymbolizer
+ /// implementation for the given target.
+ ///
+ /// Clients are responsible for ensuring that registration doesn't occur
+ /// while another thread is attempting to access the registry. Typically
+ /// this is done by initializing all targets at program startup.
+ ///
+ /// @param T - The target being registered.
+ /// @param Fn - A function to construct an MCSymbolizer for the target.
+ static void RegisterMCSymbolizer(Target &T, Target::MCSymbolizerCtorTy Fn) {
+ T.MCSymbolizerCtorFn = Fn;
+ }
+
+ /// @}
+};
+
+//===--------------------------------------------------------------------===//
+
+/// RegisterTarget - Helper template for registering a target, for use in the
+/// target's initialization function. Usage:
+///
+///
+/// Target TheFooTarget; // The global target instance.
+///
+/// extern "C" void LLVMInitializeFooTargetInfo() {
+/// RegisterTarget<Triple::foo> X(TheFooTarget, "foo", "Foo description");
+/// }
+template <Triple::ArchType TargetArchType = Triple::UnknownArch,
+ bool HasJIT = false>
+struct RegisterTarget {
+ RegisterTarget(Target &T, const char *Name, const char *Desc) {
+ TargetRegistry::RegisterTarget(T, Name, Desc, &getArchMatch, HasJIT);
+ }
+
+ static bool getArchMatch(Triple::ArchType Arch) {
+ return Arch == TargetArchType;
+ }
+};
+
+/// RegisterMCAsmInfo - Helper template for registering a target assembly info
+/// implementation. This invokes the static "Create" method on the class to
+/// actually do the construction. Usage:
+///
+/// extern "C" void LLVMInitializeFooTarget() {
+/// extern Target TheFooTarget;
+/// RegisterMCAsmInfo<FooMCAsmInfo> X(TheFooTarget);
+/// }
+template <class MCAsmInfoImpl> struct RegisterMCAsmInfo {
+ RegisterMCAsmInfo(Target &T) {
+ TargetRegistry::RegisterMCAsmInfo(T, &Allocator);
+ }
+
+private:
+ static MCAsmInfo *Allocator(const MCRegisterInfo & /*MRI*/, StringRef TT) {
+ return new MCAsmInfoImpl(TT);
+ }
+};
+
+/// RegisterMCAsmInfoFn - Helper template for registering a target assembly info
+/// implementation. This invokes the specified function to do the
+/// construction. Usage:
+///
+/// extern "C" void LLVMInitializeFooTarget() {
+/// extern Target TheFooTarget;
+/// RegisterMCAsmInfoFn X(TheFooTarget, TheFunction);
+/// }
+struct RegisterMCAsmInfoFn {
+ RegisterMCAsmInfoFn(Target &T, Target::MCAsmInfoCtorFnTy Fn) {
+ TargetRegistry::RegisterMCAsmInfo(T, Fn);
+ }
+};
+
+/// RegisterMCCodeGenInfo - Helper template for registering a target codegen
+/// info
+/// implementation. This invokes the static "Create" method on the class
+/// to actually do the construction. Usage:
+///
+/// extern "C" void LLVMInitializeFooTarget() {
+/// extern Target TheFooTarget;
+/// RegisterMCCodeGenInfo<FooMCCodeGenInfo> X(TheFooTarget);
+/// }
+template <class MCCodeGenInfoImpl> struct RegisterMCCodeGenInfo {
+ RegisterMCCodeGenInfo(Target &T) {
+ TargetRegistry::RegisterMCCodeGenInfo(T, &Allocator);
+ }
+
+private:
+ static MCCodeGenInfo *Allocator(StringRef /*TT*/, Reloc::Model /*RM*/,
+ CodeModel::Model /*CM*/,
+ CodeGenOpt::Level /*OL*/) {
+ return new MCCodeGenInfoImpl();
+ }
+};
+
+/// RegisterMCCodeGenInfoFn - Helper template for registering a target codegen
+/// info implementation. This invokes the specified function to do the
+/// construction. Usage:
+///
+/// extern "C" void LLVMInitializeFooTarget() {
+/// extern Target TheFooTarget;
+/// RegisterMCCodeGenInfoFn X(TheFooTarget, TheFunction);
+/// }
+struct RegisterMCCodeGenInfoFn {
+ RegisterMCCodeGenInfoFn(Target &T, Target::MCCodeGenInfoCtorFnTy Fn) {
+ TargetRegistry::RegisterMCCodeGenInfo(T, Fn);
+ }
+};
+
+/// RegisterMCInstrInfo - Helper template for registering a target instruction
+/// info implementation. This invokes the static "Create" method on the class
+/// to actually do the construction. Usage:
+///
+/// extern "C" void LLVMInitializeFooTarget() {
+/// extern Target TheFooTarget;
+/// RegisterMCInstrInfo<FooMCInstrInfo> X(TheFooTarget);
+/// }
+template <class MCInstrInfoImpl> struct RegisterMCInstrInfo {
+ RegisterMCInstrInfo(Target &T) {
+ TargetRegistry::RegisterMCInstrInfo(T, &Allocator);
+ }
+
+private:
+ static MCInstrInfo *Allocator() { return new MCInstrInfoImpl(); }
+};
+
+/// RegisterMCInstrInfoFn - Helper template for registering a target
+/// instruction info implementation. This invokes the specified function to
+/// do the construction. Usage:
+///
+/// extern "C" void LLVMInitializeFooTarget() {
+/// extern Target TheFooTarget;
+/// RegisterMCInstrInfoFn X(TheFooTarget, TheFunction);
+/// }
+struct RegisterMCInstrInfoFn {
+ RegisterMCInstrInfoFn(Target &T, Target::MCInstrInfoCtorFnTy Fn) {
+ TargetRegistry::RegisterMCInstrInfo(T, Fn);
+ }
+};
+
+/// RegisterMCInstrAnalysis - Helper template for registering a target
+/// instruction analyzer implementation. This invokes the static "Create"
+/// method on the class to actually do the construction. Usage:
+///
+/// extern "C" void LLVMInitializeFooTarget() {
+/// extern Target TheFooTarget;
+/// RegisterMCInstrAnalysis<FooMCInstrAnalysis> X(TheFooTarget);
+/// }
+template <class MCInstrAnalysisImpl> struct RegisterMCInstrAnalysis {
+ RegisterMCInstrAnalysis(Target &T) {
+ TargetRegistry::RegisterMCInstrAnalysis(T, &Allocator);
+ }
+
+private:
+ static MCInstrAnalysis *Allocator(const MCInstrInfo *Info) {
+ return new MCInstrAnalysisImpl(Info);
+ }
+};
+
+/// RegisterMCInstrAnalysisFn - Helper template for registering a target
+/// instruction analyzer implementation. This invokes the specified function
+/// to do the construction. Usage:
+///
+/// extern "C" void LLVMInitializeFooTarget() {
+/// extern Target TheFooTarget;
+/// RegisterMCInstrAnalysisFn X(TheFooTarget, TheFunction);
+/// }
+struct RegisterMCInstrAnalysisFn {
+ RegisterMCInstrAnalysisFn(Target &T, Target::MCInstrAnalysisCtorFnTy Fn) {
+ TargetRegistry::RegisterMCInstrAnalysis(T, Fn);
+ }
+};
+
+/// RegisterMCRegInfo - Helper template for registering a target register info
+/// implementation. This invokes the static "Create" method on the class to
+/// actually do the construction. Usage:
+///
+/// extern "C" void LLVMInitializeFooTarget() {
+/// extern Target TheFooTarget;
+/// RegisterMCRegInfo<FooMCRegInfo> X(TheFooTarget);
+/// }
+template <class MCRegisterInfoImpl> struct RegisterMCRegInfo {
+ RegisterMCRegInfo(Target &T) {
+ TargetRegistry::RegisterMCRegInfo(T, &Allocator);
+ }
+
+private:
+ static MCRegisterInfo *Allocator(StringRef /*TT*/) {
+ return new MCRegisterInfoImpl();
+ }
+};
+
+/// RegisterMCRegInfoFn - Helper template for registering a target register
+/// info implementation. This invokes the specified function to do the
+/// construction. Usage:
+///
+/// extern "C" void LLVMInitializeFooTarget() {
+/// extern Target TheFooTarget;
+/// RegisterMCRegInfoFn X(TheFooTarget, TheFunction);
+/// }
+struct RegisterMCRegInfoFn {
+ RegisterMCRegInfoFn(Target &T, Target::MCRegInfoCtorFnTy Fn) {
+ TargetRegistry::RegisterMCRegInfo(T, Fn);
+ }
+};
+
+/// RegisterMCSubtargetInfo - Helper template for registering a target
+/// subtarget info implementation. This invokes the static "Create" method
+/// on the class to actually do the construction. Usage:
+///
+/// extern "C" void LLVMInitializeFooTarget() {
+/// extern Target TheFooTarget;
+/// RegisterMCSubtargetInfo<FooMCSubtargetInfo> X(TheFooTarget);
+/// }
+template <class MCSubtargetInfoImpl> struct RegisterMCSubtargetInfo {
+ RegisterMCSubtargetInfo(Target &T) {
+ TargetRegistry::RegisterMCSubtargetInfo(T, &Allocator);
+ }
+
+private:
+ static MCSubtargetInfo *Allocator(StringRef /*TT*/, StringRef /*CPU*/,
+ StringRef /*FS*/) {
+ return new MCSubtargetInfoImpl();
+ }
+};
+
+/// RegisterMCSubtargetInfoFn - Helper template for registering a target
+/// subtarget info implementation. This invokes the specified function to
+/// do the construction. Usage:
+///
+/// extern "C" void LLVMInitializeFooTarget() {
+/// extern Target TheFooTarget;
+/// RegisterMCSubtargetInfoFn X(TheFooTarget, TheFunction);
+/// }
+struct RegisterMCSubtargetInfoFn {
+ RegisterMCSubtargetInfoFn(Target &T, Target::MCSubtargetInfoCtorFnTy Fn) {
+ TargetRegistry::RegisterMCSubtargetInfo(T, Fn);
+ }
+};
+
+/// RegisterTargetMachine - Helper template for registering a target machine
+/// implementation, for use in the target machine initialization
+/// function. Usage:
+///
+/// extern "C" void LLVMInitializeFooTarget() {
+/// extern Target TheFooTarget;
+/// RegisterTargetMachine<FooTargetMachine> X(TheFooTarget);
+/// }
+template <class TargetMachineImpl> struct RegisterTargetMachine {
+ RegisterTargetMachine(Target &T) {
+ TargetRegistry::RegisterTargetMachine(T, &Allocator);
+ }
+
+private:
+ static TargetMachine *Allocator(const Target &T, StringRef TT, StringRef CPU,
+ StringRef FS, const TargetOptions &Options,
+ Reloc::Model RM, CodeModel::Model CM,
+ CodeGenOpt::Level OL) {
+ return new TargetMachineImpl(T, TT, CPU, FS, Options, RM, CM, OL);
+ }
+};
+
+/// RegisterMCAsmBackend - Helper template for registering a target specific
+/// assembler backend. Usage:
+///
+/// extern "C" void LLVMInitializeFooMCAsmBackend() {
+/// extern Target TheFooTarget;
+/// RegisterMCAsmBackend<FooAsmLexer> X(TheFooTarget);
+/// }
+template <class MCAsmBackendImpl> struct RegisterMCAsmBackend {
+ RegisterMCAsmBackend(Target &T) {
+ TargetRegistry::RegisterMCAsmBackend(T, &Allocator);
+ }
+
+private:
+ static MCAsmBackend *Allocator(const Target &T, const MCRegisterInfo &MRI,
+ StringRef Triple, StringRef CPU) {
+ return new MCAsmBackendImpl(T, MRI, Triple, CPU);
+ }
+};
+
+/// RegisterMCAsmParser - Helper template for registering a target specific
+/// assembly parser, for use in the target machine initialization
+/// function. Usage:
+///
+/// extern "C" void LLVMInitializeFooMCAsmParser() {
+/// extern Target TheFooTarget;
+/// RegisterMCAsmParser<FooAsmParser> X(TheFooTarget);
+/// }
+template <class MCAsmParserImpl> struct RegisterMCAsmParser {
+ RegisterMCAsmParser(Target &T) {
+ TargetRegistry::RegisterMCAsmParser(T, &Allocator);
+ }
+
+private:
+ static MCTargetAsmParser *Allocator(MCSubtargetInfo &STI, MCAsmParser &P,
+ const MCInstrInfo &MII,
+ const MCTargetOptions &Options) {
+ return new MCAsmParserImpl(STI, P, MII, Options);
+ }
+};
+
+/// RegisterAsmPrinter - Helper template for registering a target specific
+/// assembly printer, for use in the target machine initialization
+/// function. Usage:
+///
+/// extern "C" void LLVMInitializeFooAsmPrinter() {
+/// extern Target TheFooTarget;
+/// RegisterAsmPrinter<FooAsmPrinter> X(TheFooTarget);
+/// }
+template <class AsmPrinterImpl> struct RegisterAsmPrinter {
+ RegisterAsmPrinter(Target &T) {
+ TargetRegistry::RegisterAsmPrinter(T, &Allocator);
+ }
+
+private:
+ static AsmPrinter *Allocator(TargetMachine &TM,
+ std::unique_ptr<MCStreamer> &&Streamer) {
+ return new AsmPrinterImpl(TM, std::move(Streamer));
+ }
+};
+
+/// RegisterMCCodeEmitter - Helper template for registering a target specific
+/// machine code emitter, for use in the target initialization
+/// function. Usage:
+///
+/// extern "C" void LLVMInitializeFooMCCodeEmitter() {
+/// extern Target TheFooTarget;
+/// RegisterMCCodeEmitter<FooCodeEmitter> X(TheFooTarget);
+/// }
+template <class MCCodeEmitterImpl> struct RegisterMCCodeEmitter {
+ RegisterMCCodeEmitter(Target &T) {
+ TargetRegistry::RegisterMCCodeEmitter(T, &Allocator);
+ }
+
+private:
+ static MCCodeEmitter *Allocator(const MCInstrInfo & /*II*/,
+ const MCRegisterInfo & /*MRI*/,
+ MCContext & /*Ctx*/) {
+ return new MCCodeEmitterImpl();
+ }
+};
}
#endif
diff --git a/include/llvm/Support/Timer.h b/include/llvm/Support/Timer.h
index 45c182831b2a..2cd30e2aaf32 100644
--- a/include/llvm/Support/Timer.h
+++ b/include/llvm/Support/Timer.h
@@ -11,7 +11,6 @@
#define LLVM_SUPPORT_TIMER_H
#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
#include <cassert>
#include <string>
@@ -126,7 +125,7 @@ private:
///
class TimeRegion {
Timer *T;
- TimeRegion(const TimeRegion &) LLVM_DELETED_FUNCTION;
+ TimeRegion(const TimeRegion &) = delete;
public:
explicit TimeRegion(Timer &t) : T(&t) {
T->startTimer();
@@ -164,8 +163,8 @@ class TimerGroup {
std::vector<std::pair<TimeRecord, std::string> > TimersToPrint;
TimerGroup **Prev, *Next; // Doubly linked list of TimerGroup's.
- TimerGroup(const TimerGroup &TG) LLVM_DELETED_FUNCTION;
- void operator=(const TimerGroup &TG) LLVM_DELETED_FUNCTION;
+ TimerGroup(const TimerGroup &TG) = delete;
+ void operator=(const TimerGroup &TG) = delete;
public:
explicit TimerGroup(StringRef name);
~TimerGroup();
diff --git a/include/llvm/Support/ToolOutputFile.h b/include/llvm/Support/ToolOutputFile.h
index d98e7bbd51d4..1be26c2cb58b 100644
--- a/include/llvm/Support/ToolOutputFile.h
+++ b/include/llvm/Support/ToolOutputFile.h
@@ -18,16 +18,16 @@
namespace llvm {
-/// tool_output_file - This class contains a raw_fd_ostream and adds a
-/// few extra features commonly needed for compiler-like tool output files:
+/// This class contains a raw_fd_ostream and adds a few extra features commonly
+/// needed for compiler-like tool output files:
/// - The file is automatically deleted if the process is killed.
/// - The file is automatically deleted when the tool_output_file
/// object is destroyed unless the client calls keep().
class tool_output_file {
- /// Installer - This class is declared before the raw_fd_ostream so that
- /// it is constructed before the raw_fd_ostream is constructed and
- /// destructed after the raw_fd_ostream is destructed. It installs
- /// cleanups in its constructor and uninstalls them in its destructor.
+ /// This class is declared before the raw_fd_ostream so that it is constructed
+ /// before the raw_fd_ostream is constructed and destructed after the
+ /// raw_fd_ostream is destructed. It installs cleanups in its constructor and
+ /// uninstalls them in its destructor.
class CleanupInstaller {
/// The name of the file.
std::string Filename;
@@ -39,8 +39,7 @@ class tool_output_file {
~CleanupInstaller();
} Installer;
- /// OS - The contained stream. This is intentionally declared after
- /// Installer.
+ /// The contained stream. This is intentionally declared after Installer.
raw_fd_ostream OS;
public:
@@ -51,11 +50,11 @@ public:
tool_output_file(StringRef Filename, int FD);
- /// os - Return the contained raw_fd_ostream.
+ /// Return the contained raw_fd_ostream.
raw_fd_ostream &os() { return OS; }
- /// keep - Indicate that the tool's job wrt this output file has been
- /// successful and the file should not be deleted.
+ /// Indicate that the tool's job wrt this output file has been successful and
+ /// the file should not be deleted.
void keep() { Installer.Keep = true; }
};
diff --git a/include/llvm/Support/UnicodeCharRanges.h b/include/llvm/Support/UnicodeCharRanges.h
index 79137bf35363..9f738dff1107 100644
--- a/include/llvm/Support/UnicodeCharRanges.h
+++ b/include/llvm/Support/UnicodeCharRanges.h
@@ -50,9 +50,13 @@ public:
/// the UnicodeCharSet instance, and should not change. Array is validated by
/// the constructor, so it makes sense to create as few UnicodeCharSet
/// instances per each array of ranges, as possible.
+#ifdef NDEBUG
+ LLVM_CONSTEXPR UnicodeCharSet(CharRanges Ranges) : Ranges(Ranges) {}
+#else
UnicodeCharSet(CharRanges Ranges) : Ranges(Ranges) {
assert(rangesAreValid());
}
+#endif
/// \brief Returns true if the character set contains the Unicode code point
/// \p C.
diff --git a/include/llvm/Support/UniqueLock.h b/include/llvm/Support/UniqueLock.h
index 5a4c273e83e2..529284d3868b 100644
--- a/include/llvm/Support/UniqueLock.h
+++ b/include/llvm/Support/UniqueLock.h
@@ -29,8 +29,8 @@ namespace llvm {
MutexT *M;
bool locked;
- unique_lock(const unique_lock &) LLVM_DELETED_FUNCTION;
- void operator=(const unique_lock &) LLVM_DELETED_FUNCTION;
+ unique_lock(const unique_lock &) = delete;
+ void operator=(const unique_lock &) = delete;
public:
unique_lock() : M(nullptr), locked(false) {}
explicit unique_lock(MutexT &m) : M(&m), locked(true) { M->lock(); }
diff --git a/include/llvm/Support/Watchdog.h b/include/llvm/Support/Watchdog.h
index b58496b2fb8e..01e1d926eb95 100644
--- a/include/llvm/Support/Watchdog.h
+++ b/include/llvm/Support/Watchdog.h
@@ -29,8 +29,8 @@ namespace llvm {
~Watchdog();
private:
// Noncopyable.
- Watchdog(const Watchdog &other) LLVM_DELETED_FUNCTION;
- Watchdog &operator=(const Watchdog &other) LLVM_DELETED_FUNCTION;
+ Watchdog(const Watchdog &other) = delete;
+ Watchdog &operator=(const Watchdog &other) = delete;
};
}
}
diff --git a/include/llvm/Support/YAMLParser.h b/include/llvm/Support/YAMLParser.h
index de6e6544e25b..0fbb7d2e6c7e 100644
--- a/include/llvm/Support/YAMLParser.h
+++ b/include/llvm/Support/YAMLParser.h
@@ -38,19 +38,18 @@
#ifndef LLVM_SUPPORT_YAMLPARSER_H
#define LLVM_SUPPORT_YAMLPARSER_H
-#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
-#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SMLoc.h"
#include <limits>
#include <map>
#include <utility>
namespace llvm {
+class MemoryBufferRef;
class SourceMgr;
-class raw_ostream;
class Twine;
+class raw_ostream;
namespace yaml {
@@ -77,9 +76,9 @@ std::string escape(StringRef Input);
class Stream {
public:
/// \brief This keeps a reference to the string referenced by \p Input.
- Stream(StringRef Input, SourceMgr &);
+ Stream(StringRef Input, SourceMgr &, bool ShowColors = true);
- Stream(MemoryBufferRef InputBuffer, SourceMgr &);
+ Stream(MemoryBufferRef InputBuffer, SourceMgr &, bool ShowColors = true);
~Stream();
document_iterator begin();
@@ -108,6 +107,7 @@ public:
enum NodeKind {
NK_Null,
NK_Scalar,
+ NK_BlockScalar,
NK_KeyValue,
NK_Mapping,
NK_Sequence,
@@ -159,7 +159,7 @@ protected:
void operator delete(void *) throw() {}
- virtual ~Node() {}
+ ~Node() = default;
private:
unsigned int TypeID;
@@ -172,7 +172,7 @@ private:
///
/// Example:
/// !!null null
-class NullNode : public Node {
+class NullNode final : public Node {
void anchor() override;
public:
@@ -187,7 +187,7 @@ public:
///
/// Example:
/// Adena
-class ScalarNode : public Node {
+class ScalarNode final : public Node {
void anchor() override;
public:
@@ -223,6 +223,36 @@ private:
SmallVectorImpl<char> &Storage) const;
};
+/// \brief A block scalar node is an opaque datum that can be presented as a
+/// series of zero or more Unicode scalar values.
+///
+/// Example:
+/// |
+/// Hello
+/// World
+class BlockScalarNode final : public Node {
+ void anchor() override;
+
+public:
+ BlockScalarNode(std::unique_ptr<Document> &D, StringRef Anchor, StringRef Tag,
+ StringRef Value, StringRef RawVal)
+ : Node(NK_BlockScalar, D, Anchor, Tag), Value(Value) {
+ SMLoc Start = SMLoc::getFromPointer(RawVal.begin());
+ SMLoc End = SMLoc::getFromPointer(RawVal.end());
+ SourceRange = SMRange(Start, End);
+ }
+
+ /// \brief Gets the value of this node as a StringRef.
+ StringRef getValue() const { return Value; }
+
+ static inline bool classof(const Node *N) {
+ return N->getType() == NK_BlockScalar;
+ }
+
+private:
+ StringRef Value;
+};
+
/// \brief A key and value pair. While not technically a Node under the YAML
/// representation graph, it is easier to treat them this way.
///
@@ -230,7 +260,7 @@ private:
///
/// Example:
/// Section: .text
-class KeyValueNode : public Node {
+class KeyValueNode final : public Node {
void anchor() override;
public:
@@ -254,7 +284,8 @@ public:
void skip() override {
getKey()->skip();
- getValue()->skip();
+ if (Node *Val = getValue())
+ Val->skip();
}
static inline bool classof(const Node *N) {
@@ -340,7 +371,7 @@ template <class CollectionType> void skip(CollectionType &C) {
/// Example:
/// Name: _main
/// Scope: Global
-class MappingNode : public Node {
+class MappingNode final : public Node {
void anchor() override;
public:
@@ -387,7 +418,7 @@ private:
/// Example:
/// - Hello
/// - World
-class SequenceNode : public Node {
+class SequenceNode final : public Node {
void anchor() override;
public:
@@ -440,7 +471,7 @@ private:
///
/// Example:
/// *AnchorName
-class AliasNode : public Node {
+class AliasNode final : public Node {
void anchor() override;
public:
diff --git a/include/llvm/Support/YAMLTraits.h b/include/llvm/Support/YAMLTraits.h
index 023dcee7d54c..3bdff2091809 100644
--- a/include/llvm/Support/YAMLTraits.h
+++ b/include/llvm/Support/YAMLTraits.h
@@ -46,6 +46,10 @@ struct MappingTraits {
// static void mapping(IO &io, T &fields);
// Optionally may provide:
// static StringRef validate(IO &io, T &fields);
+ //
+ // The optional flow flag will cause generated YAML to use a flow mapping
+ // (e.g. { a: 0, b: 1 }):
+ // static const bool flow = true;
};
@@ -117,6 +121,35 @@ struct ScalarTraits {
};
+/// This class should be specialized by type that requires custom conversion
+/// to/from a YAML literal block scalar. For example:
+///
+/// template <>
+/// struct BlockScalarTraits<MyType> {
+/// static void output(const MyType &Value, void*, llvm::raw_ostream &Out)
+/// {
+/// // stream out custom formatting
+/// Out << Val;
+/// }
+/// static StringRef input(StringRef Scalar, void*, MyType &Value) {
+/// // parse scalar and set `value`
+/// // return empty string on success, or error string
+/// return StringRef();
+/// }
+/// };
+template <typename T>
+struct BlockScalarTraits {
+ // Must provide:
+ //
+ // Function to write the value as a string:
+ // static void output(const T &Value, void *ctx, llvm::raw_ostream &Out);
+ //
+ // Function to convert a string to a value. Returns the empty
+ // StringRef on success or an error string if string is malformed:
+ // static StringRef input(StringRef Scalar, void *ctxt, T &Value);
+};
+
+
/// This class should be specialized by any type that needs to be converted
/// to/from a YAML sequence. For example:
///
@@ -220,6 +253,26 @@ public:
};
+// Test if BlockScalarTraits<T> is defined on type T.
+template <class T>
+struct has_BlockScalarTraits
+{
+ typedef StringRef (*Signature_input)(StringRef, void *, T &);
+ typedef void (*Signature_output)(const T &, void *, llvm::raw_ostream &);
+
+ template <typename U>
+ static char test(SameType<Signature_input, &U::input> *,
+ SameType<Signature_output, &U::output> *);
+
+ template <typename U>
+ static double test(...);
+
+public:
+ static bool const value =
+ (sizeof(test<BlockScalarTraits<T>>(nullptr, nullptr)) == 1);
+};
+
+
// Test if MappingTraits<T> is defined on type T.
template <class T>
struct has_MappingTraits
@@ -406,6 +459,7 @@ struct missingTraits : public std::integral_constant<bool,
!has_ScalarEnumerationTraits<T>::value
&& !has_ScalarBitSetTraits<T>::value
&& !has_ScalarTraits<T>::value
+ && !has_BlockScalarTraits<T>::value
&& !has_MappingTraits<T>::value
&& !has_SequenceTraits<T>::value
&& !has_DocumentListTraits<T>::value > {};
@@ -445,8 +499,12 @@ public:
virtual bool preflightKey(const char*, bool, bool, bool &, void *&) = 0;
virtual void postflightKey(void*) = 0;
+ virtual void beginFlowMapping() = 0;
+ virtual void endFlowMapping() = 0;
+
virtual void beginEnumScalar() = 0;
virtual bool matchEnumScalar(const char*, bool) = 0;
+ virtual bool matchEnumFallback() = 0;
virtual void endEnumScalar() = 0;
virtual bool beginBitSetScalar(bool &) = 0;
@@ -454,6 +512,7 @@ public:
virtual void endBitSetScalar() = 0;
virtual void scalarString(StringRef &, bool) = 0;
+ virtual void blockScalarString(StringRef &) = 0;
virtual void setError(const Twine &) = 0;
@@ -472,6 +531,16 @@ public:
}
}
+ template <typename FBT, typename T>
+ void enumFallback(T &Val) {
+ if ( matchEnumFallback() ) {
+ // FIXME: Force integral conversion to allow strong typedefs to convert.
+ FBT Res = (uint64_t)Val;
+ yamlize(*this, Res, true);
+ Val = (uint64_t)Res;
+ }
+ }
+
template <typename T>
void bitSetCase(T &Val, const char* Str, const T ConstVal) {
if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
@@ -532,7 +601,7 @@ public:
void mapOptional(const char* Key, T& Val, const T& Default) {
this->processKeyWithDefault(Key, Val, Default, false);
}
-
+
private:
template <typename T>
void processKeyWithDefault(const char *Key, Optional<T> &Val,
@@ -628,11 +697,32 @@ yamlize(IO &io, T &Val, bool) {
}
}
+template <typename T>
+typename std::enable_if<has_BlockScalarTraits<T>::value, void>::type
+yamlize(IO &YamlIO, T &Val, bool) {
+ if (YamlIO.outputting()) {
+ std::string Storage;
+ llvm::raw_string_ostream Buffer(Storage);
+ BlockScalarTraits<T>::output(Val, YamlIO.getContext(), Buffer);
+ StringRef Str = Buffer.str();
+ YamlIO.blockScalarString(Str);
+ } else {
+ StringRef Str;
+ YamlIO.blockScalarString(Str);
+ StringRef Result =
+ BlockScalarTraits<T>::input(Str, YamlIO.getContext(), Val);
+ if (!Result.empty())
+ YamlIO.setError(llvm::Twine(Result));
+ }
+}
template<typename T>
typename std::enable_if<validatedMappingTraits<T>::value, void>::type
yamlize(IO &io, T &Val, bool) {
- io.beginMapping();
+ if (has_FlowTraits<MappingTraits<T>>::value)
+ io.beginFlowMapping();
+ else
+ io.beginMapping();
if (io.outputting()) {
StringRef Err = MappingTraits<T>::validate(io, Val);
if (!Err.empty()) {
@@ -646,15 +736,24 @@ yamlize(IO &io, T &Val, bool) {
if (!Err.empty())
io.setError(Err);
}
- io.endMapping();
+ if (has_FlowTraits<MappingTraits<T>>::value)
+ io.endFlowMapping();
+ else
+ io.endMapping();
}
template<typename T>
typename std::enable_if<unvalidatedMappingTraits<T>::value, void>::type
yamlize(IO &io, T &Val, bool) {
- io.beginMapping();
- MappingTraits<T>::mapping(io, Val);
- io.endMapping();
+ if (has_FlowTraits<MappingTraits<T>>::value) {
+ io.beginFlowMapping();
+ MappingTraits<T>::mapping(io, Val);
+ io.endFlowMapping();
+ } else {
+ io.beginMapping();
+ MappingTraits<T>::mapping(io, Val);
+ io.endMapping();
+ }
}
template<typename T>
@@ -706,7 +805,7 @@ struct ScalarTraits<StringRef> {
static StringRef input(StringRef, void*, StringRef &);
static bool mustQuote(StringRef S) { return needsQuotes(S); }
};
-
+
template<>
struct ScalarTraits<std::string> {
static void output(const std::string &, void*, llvm::raw_ostream &);
@@ -877,7 +976,7 @@ public:
void *Ctxt = nullptr,
SourceMgr::DiagHandlerTy DiagHandler = nullptr,
void *DiagHandlerCtxt = nullptr);
- ~Input();
+ ~Input() override;
// Check if there was an syntax or semantic error during parsing.
std::error_code error();
@@ -889,6 +988,8 @@ private:
void endMapping() override;
bool preflightKey(const char *, bool, bool, bool &, void *&) override;
void postflightKey(void *) override;
+ void beginFlowMapping() override;
+ void endFlowMapping() override;
unsigned beginSequence() override;
void endSequence() override;
bool preflightElement(unsigned index, void *&) override;
@@ -899,11 +1000,13 @@ private:
void endFlowSequence() override;
void beginEnumScalar() override;
bool matchEnumScalar(const char*, bool) override;
+ bool matchEnumFallback() override;
void endEnumScalar() override;
bool beginBitSetScalar(bool &) override;
bool bitSetMatch(const char *, bool ) override;
void endBitSetScalar() override;
void scalarString(StringRef &, bool) override;
+ void blockScalarString(StringRef &) override;
void setError(const Twine &message) override;
bool canElideEmptySequence() override;
@@ -935,7 +1038,8 @@ private:
StringRef value() const { return _value; }
static inline bool classof(const HNode *n) {
- return ScalarNode::classof(n->_node);
+ return ScalarNode::classof(n->_node) ||
+ BlockScalarNode::classof(n->_node);
}
static inline bool classof(const ScalarHNode *) { return true; }
protected:
@@ -943,7 +1047,7 @@ private:
};
class MapHNode : public HNode {
- virtual void anchor();
+ void anchor() override;
public:
MapHNode(Node *n) : HNode(n) { }
@@ -962,7 +1066,7 @@ private:
};
class SequenceHNode : public HNode {
- virtual void anchor();
+ void anchor() override;
public:
SequenceHNode(Node *n) : HNode(n) { }
@@ -1008,7 +1112,7 @@ private:
class Output : public IO {
public:
Output(llvm::raw_ostream &, void *Ctxt=nullptr);
- virtual ~Output();
+ ~Output() override;
bool outputting() override;
bool mapTag(StringRef, bool) override;
@@ -1016,6 +1120,8 @@ public:
void endMapping() override;
bool preflightKey(const char *key, bool, bool, bool &, void *&) override;
void postflightKey(void *) override;
+ void beginFlowMapping() override;
+ void endFlowMapping() override;
unsigned beginSequence() override;
void endSequence() override;
bool preflightElement(unsigned, void *&) override;
@@ -1026,11 +1132,13 @@ public:
void endFlowSequence() override;
void beginEnumScalar() override;
bool matchEnumScalar(const char*, bool) override;
+ bool matchEnumFallback() override;
void endEnumScalar() override;
bool beginBitSetScalar(bool &) override;
bool bitSetMatch(const char *, bool ) override;
void endBitSetScalar() override;
void scalarString(StringRef &, bool) override;
+ void blockScalarString(StringRef &) override;
void setError(const Twine &message) override;
bool canElideEmptySequence() override;
public:
@@ -1047,13 +1155,22 @@ private:
void newLineCheck();
void outputNewLine();
void paddedKey(StringRef key);
-
- enum InState { inSeq, inFlowSeq, inMapFirstKey, inMapOtherKey };
+ void flowKey(StringRef Key);
+
+ enum InState {
+ inSeq,
+ inFlowSeq,
+ inMapFirstKey,
+ inMapOtherKey,
+ inFlowMapFirstKey,
+ inFlowMapOtherKey
+ };
llvm::raw_ostream &Out;
SmallVector<InState, 8> StateStack;
int Column;
int ColumnAtFlowStart;
+ int ColumnAtMapFlowStart;
bool NeedBitValueComma;
bool NeedFlowSequenceComma;
bool EnumerationMatchFound;
@@ -1163,6 +1280,16 @@ operator>>(Input &yin, T &docSeq) {
return yin;
}
+// Define non-member operator>> so that Input can stream in a block scalar.
+template <typename T>
+inline
+typename std::enable_if<has_BlockScalarTraits<T>::value, Input &>::type
+operator>>(Input &In, T &Val) {
+ if (In.setCurrentDocument())
+ yamlize(In, Val, true);
+ return In;
+}
+
// Provide better error message about types missing a trait specialization
template <typename T>
inline
@@ -1218,6 +1345,20 @@ operator<<(Output &yout, T &seq) {
return yout;
}
+// Define non-member operator<< so that Output can stream out a block scalar.
+template <typename T>
+inline
+typename std::enable_if<has_BlockScalarTraits<T>::value, Output &>::type
+operator<<(Output &Out, T &Val) {
+ Out.beginDocuments();
+ if (Out.preflightDocument(0)) {
+ yamlize(Out, Val, true);
+ Out.postflightDocument();
+ }
+ Out.endDocuments();
+ return Out;
+}
+
// Provide better error message about types missing a trait specialization
template <typename T>
inline
diff --git a/include/llvm/Support/circular_raw_ostream.h b/include/llvm/Support/circular_raw_ostream.h
index ee7b89fe8c8d..19f9c2c4b155 100644
--- a/include/llvm/Support/circular_raw_ostream.h
+++ b/include/llvm/Support/circular_raw_ostream.h
@@ -107,30 +107,17 @@ namespace llvm
/// management of it, etc.
///
circular_raw_ostream(raw_ostream &Stream, const char *Header,
- size_t BuffSize = 0, bool Owns = REFERENCE_ONLY)
- : raw_ostream(/*unbuffered*/true),
- TheStream(nullptr),
- OwnsStream(Owns),
- BufferSize(BuffSize),
- BufferArray(nullptr),
- Filled(false),
- Banner(Header) {
+ size_t BuffSize = 0, bool Owns = REFERENCE_ONLY)
+ : raw_ostream(/*unbuffered*/ true), TheStream(nullptr),
+ OwnsStream(Owns), BufferSize(BuffSize), BufferArray(nullptr),
+ Filled(false), Banner(Header) {
if (BufferSize != 0)
BufferArray = new char[BufferSize];
Cur = BufferArray;
setStream(Stream, Owns);
}
- explicit circular_raw_ostream()
- : raw_ostream(/*unbuffered*/true),
- TheStream(nullptr),
- OwnsStream(REFERENCE_ONLY),
- BufferArray(nullptr),
- Filled(false),
- Banner("") {
- Cur = BufferArray;
- }
- ~circular_raw_ostream() {
+ ~circular_raw_ostream() override {
flush();
flushBufferWithBanner();
releaseStream();
diff --git a/include/llvm/Support/raw_os_ostream.h b/include/llvm/Support/raw_os_ostream.h
index 04cf3b6202c4..a983aeb90879 100644
--- a/include/llvm/Support/raw_os_ostream.h
+++ b/include/llvm/Support/raw_os_ostream.h
@@ -34,7 +34,7 @@ class raw_os_ostream : public raw_ostream {
public:
raw_os_ostream(std::ostream &O) : OS(O) {}
- ~raw_os_ostream();
+ ~raw_os_ostream() override;
};
} // end llvm namespace
diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h
index c9ef637940db..b59317112c44 100644
--- a/include/llvm/Support/raw_ostream.h
+++ b/include/llvm/Support/raw_ostream.h
@@ -14,32 +14,31 @@
#ifndef LLVM_SUPPORT_RAW_OSTREAM_H
#define LLVM_SUPPORT_RAW_OSTREAM_H
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
#include <system_error>
namespace llvm {
- class format_object_base;
- class FormattedString;
- class FormattedNumber;
- template <typename T>
- class SmallVectorImpl;
-
- namespace sys {
- namespace fs {
- enum OpenFlags : unsigned;
- }
- }
-
-/// raw_ostream - This class implements an extremely fast bulk output stream
-/// that can *only* output to a stream. It does not support seeking, reopening,
-/// rewinding, line buffered disciplines etc. It is a simple buffer that outputs
+class format_object_base;
+class FormattedString;
+class FormattedNumber;
+template <typename T> class SmallVectorImpl;
+
+namespace sys {
+namespace fs {
+enum OpenFlags : unsigned;
+}
+}
+
+/// This class implements an extremely fast bulk output stream that can *only*
+/// output to a stream. It does not support seeking, reopening, rewinding, line
+/// buffered disciplines etc. It is a simple buffer that outputs
/// a chunk at a time.
class raw_ostream {
private:
- void operator=(const raw_ostream &) LLVM_DELETED_FUNCTION;
- raw_ostream(const raw_ostream &) LLVM_DELETED_FUNCTION;
+ void operator=(const raw_ostream &) = delete;
+ raw_ostream(const raw_ostream &) = delete;
/// The buffer is handled in such a way that the buffer is
/// uninitialized, unbuffered, or out of space when OutBufCur >=
@@ -81,8 +80,8 @@ public:
SAVEDCOLOR
};
- explicit raw_ostream(bool unbuffered=false)
- : BufferMode(unbuffered ? Unbuffered : InternalBuffer) {
+ explicit raw_ostream(bool unbuffered = false)
+ : BufferMode(unbuffered ? Unbuffered : InternalBuffer) {
// Start out ready to flush.
OutBufStart = OutBufEnd = OutBufCur = nullptr;
}
@@ -96,12 +95,11 @@ public:
// Configuration Interface
//===--------------------------------------------------------------------===//
- /// SetBuffered - Set the stream to be buffered, with an automatically
- /// determined buffer size.
+ /// Set the stream to be buffered, with an automatically determined buffer
+ /// size.
void SetBuffered();
- /// SetBufferSize - Set the stream to be buffered, using the
- /// specified buffer size.
+ /// Set the stream to be buffered, using the specified buffer size.
void SetBufferSize(size_t Size) {
flush();
SetBufferAndMode(new char[Size], Size, InternalBuffer);
@@ -117,10 +115,9 @@ public:
return OutBufEnd - OutBufStart;
}
- /// SetUnbuffered - Set the stream to be unbuffered. When
- /// unbuffered, the stream will flush after every write. This routine
- /// will also flush the buffer immediately when the stream is being
- /// set to unbuffered.
+ /// Set the stream to be unbuffered. When unbuffered, the stream will flush
+ /// after every write. This routine will also flush the buffer immediately
+ /// when the stream is being set to unbuffered.
void SetUnbuffered() {
flush();
SetBufferAndMode(nullptr, 0, Unbuffered);
@@ -185,6 +182,10 @@ public:
return write(Str.data(), Str.length());
}
+ raw_ostream &operator<<(const llvm::SmallVectorImpl<char> &Str) {
+ return write(Str.data(), Str.size());
+ }
+
raw_ostream &operator<<(unsigned long N);
raw_ostream &operator<<(long N);
raw_ostream &operator<<(unsigned long long N);
@@ -200,11 +201,11 @@ public:
raw_ostream &operator<<(double N);
- /// write_hex - Output \p N in hexadecimal, without any prefix or padding.
+ /// Output \p N in hexadecimal, without any prefix or padding.
raw_ostream &write_hex(unsigned long long N);
- /// write_escaped - Output \p Str, turning '\\', '\t', '\n', '"', and
- /// anything that doesn't satisfy std::isprint into an escape sequence.
+ /// Output \p Str, turning '\\', '\t', '\n', '"', and anything that doesn't
+ /// satisfy std::isprint into an escape sequence.
raw_ostream &write_escaped(StringRef Str, bool UseHexEscapes = false);
raw_ostream &write(unsigned char C);
@@ -259,8 +260,8 @@ public:
//===--------------------------------------------------------------------===//
private:
- /// write_impl - The is the piece of the class that is implemented
- /// by subclasses. This writes the \p Size bytes starting at
+ /// The is the piece of the class that is implemented by subclasses. This
+ /// writes the \p Size bytes starting at
/// \p Ptr to the underlying stream.
///
/// This function is guaranteed to only be called at a point at which it is
@@ -277,51 +278,69 @@ private:
// An out of line virtual method to provide a home for the class vtable.
virtual void handle();
- /// current_pos - Return the current position within the stream, not
- /// counting the bytes currently in the buffer.
+ /// Return the current position within the stream, not counting the bytes
+ /// currently in the buffer.
virtual uint64_t current_pos() const = 0;
protected:
- /// SetBuffer - Use the provided buffer as the raw_ostream buffer. This is
- /// intended for use only by subclasses which can arrange for the output to go
- /// directly into the desired output buffer, instead of being copied on each
- /// flush.
+ /// Use the provided buffer as the raw_ostream buffer. This is intended for
+ /// use only by subclasses which can arrange for the output to go directly
+ /// into the desired output buffer, instead of being copied on each flush.
void SetBuffer(char *BufferStart, size_t Size) {
SetBufferAndMode(BufferStart, Size, ExternalBuffer);
}
- /// preferred_buffer_size - Return an efficient buffer size for the
- /// underlying output mechanism.
+ /// Return an efficient buffer size for the underlying output mechanism.
virtual size_t preferred_buffer_size() const;
- /// getBufferStart - Return the beginning of the current stream buffer, or 0
- /// if the stream is unbuffered.
+ /// Return the beginning of the current stream buffer, or 0 if the stream is
+ /// unbuffered.
const char *getBufferStart() const { return OutBufStart; }
//===--------------------------------------------------------------------===//
// Private Interface
//===--------------------------------------------------------------------===//
private:
- /// SetBufferAndMode - Install the given buffer and mode.
+ /// Install the given buffer and mode.
void SetBufferAndMode(char *BufferStart, size_t Size, BufferKind Mode);
- /// flush_nonempty - Flush the current buffer, which is known to be
- /// non-empty. This outputs the currently buffered data and resets
- /// the buffer to empty.
+ /// Flush the current buffer, which is known to be non-empty. This outputs the
+ /// currently buffered data and resets the buffer to empty.
void flush_nonempty();
- /// copy_to_buffer - Copy data into the buffer. Size must not be
- /// greater than the number of unused bytes in the buffer.
+ /// Copy data into the buffer. Size must not be greater than the number of
+ /// unused bytes in the buffer.
void copy_to_buffer(const char *Ptr, size_t Size);
};
+/// An abstract base class for streams implementations that also support a
+/// pwrite operation. This is usefull for code that can mostly stream out data,
+/// but needs to patch in a header that needs to know the output size.
+class raw_pwrite_stream : public raw_ostream {
+ virtual void pwrite_impl(const char *Ptr, size_t Size, uint64_t Offset) = 0;
+
+public:
+ explicit raw_pwrite_stream(bool Unbuffered = false)
+ : raw_ostream(Unbuffered) {}
+ void pwrite(const char *Ptr, size_t Size, uint64_t Offset) {
+#ifndef NDBEBUG
+ uint64_t Pos = tell();
+ // /dev/null always reports a pos of 0, so we cannot perform this check
+ // in that case.
+ if (Pos)
+ assert(Size + Offset <= Pos && "We don't support extending the stream");
+#endif
+ pwrite_impl(Ptr, Size, Offset);
+ }
+};
+
//===----------------------------------------------------------------------===//
// File Output Streams
//===----------------------------------------------------------------------===//
-/// raw_fd_ostream - A raw_ostream that writes to a file descriptor.
+/// A raw_ostream that writes to a file descriptor.
///
-class raw_fd_ostream : public raw_ostream {
+class raw_fd_ostream : public raw_pwrite_stream {
int FD;
bool ShouldClose;
@@ -335,18 +354,21 @@ class raw_fd_ostream : public raw_ostream {
uint64_t pos;
- /// write_impl - See raw_ostream::write_impl.
+ bool SupportsSeeking;
+
+ /// See raw_ostream::write_impl.
void write_impl(const char *Ptr, size_t Size) override;
- /// current_pos - Return the current position within the stream, not
- /// counting the bytes currently in the buffer.
+ void pwrite_impl(const char *Ptr, size_t Size, uint64_t Offset) override;
+
+ /// Return the current position within the stream, not counting the bytes
+ /// currently in the buffer.
uint64_t current_pos() const override { return pos; }
- /// preferred_buffer_size - Determine an efficient buffer size.
+ /// Determine an efficient buffer size.
size_t preferred_buffer_size() const override;
- /// error_detected - Set the flag indicating that an output error has
- /// been encountered.
+ /// Set the flag indicating that an output error has been encountered.
void error_detected() { Error = true; }
public:
@@ -363,22 +385,24 @@ public:
raw_fd_ostream(StringRef Filename, std::error_code &EC,
sys::fs::OpenFlags Flags);
- /// raw_fd_ostream ctor - FD is the file descriptor that this writes to. If
- /// ShouldClose is true, this closes the file when the stream is destroyed.
+ /// FD is the file descriptor that this writes to. If ShouldClose is true,
+ /// this closes the file when the stream is destroyed.
raw_fd_ostream(int fd, bool shouldClose, bool unbuffered=false);
- ~raw_fd_ostream();
+ ~raw_fd_ostream() override;
- /// close - Manually flush the stream and close the file.
- /// Note that this does not call fsync.
+ /// Manually flush the stream and close the file. Note that this does not call
+ /// fsync.
void close();
- /// seek - Flushes the stream and repositions the underlying file descriptor
- /// position to the offset specified from the beginning of the file.
+ bool supportsSeeking() { return SupportsSeeking; }
+
+ /// Flushes the stream and repositions the underlying file descriptor position
+ /// to the offset specified from the beginning of the file.
uint64_t seek(uint64_t off);
- /// SetUseAtomicWrite - Set the stream to attempt to use atomic writes for
- /// individual output routines where possible.
+ /// Set the stream to attempt to use atomic writes for individual output
+ /// routines where possible.
///
/// Note that because raw_ostream's are typically buffered, this flag is only
/// sensible when used on unbuffered streams which will flush their output
@@ -397,18 +421,18 @@ public:
bool has_colors() const override;
- /// has_error - Return the value of the flag in this raw_fd_ostream indicating
- /// whether an output error has been encountered.
+ /// Return the value of the flag in this raw_fd_ostream indicating whether an
+ /// output error has been encountered.
/// This doesn't implicitly flush any pending output. Also, it doesn't
/// guarantee to detect all errors unless the stream has been closed.
bool has_error() const {
return Error;
}
- /// clear_error - Set the flag read by has_error() to false. If the error
- /// flag is set at the time when this raw_ostream's destructor is called,
- /// report_fatal_error is called to report the error. Use clear_error()
- /// after handling the error to avoid this behavior.
+ /// Set the flag read by has_error() to false. If the error flag is set at the
+ /// time when this raw_ostream's destructor is called, report_fatal_error is
+ /// called to report the error. Use clear_error() after handling the error to
+ /// avoid this behavior.
///
/// "Errors should never pass silently.
/// Unless explicitly silenced."
@@ -419,87 +443,106 @@ public:
}
};
-/// outs() - This returns a reference to a raw_ostream for standard output.
-/// Use it like: outs() << "foo" << "bar";
+/// This returns a reference to a raw_ostream for standard output. Use it like:
+/// outs() << "foo" << "bar";
raw_ostream &outs();
-/// errs() - This returns a reference to a raw_ostream for standard error.
-/// Use it like: errs() << "foo" << "bar";
+/// This returns a reference to a raw_ostream for standard error. Use it like:
+/// errs() << "foo" << "bar";
raw_ostream &errs();
-/// nulls() - This returns a reference to a raw_ostream which simply discards
-/// output.
+/// This returns a reference to a raw_ostream which simply discards output.
raw_ostream &nulls();
//===----------------------------------------------------------------------===//
// Output Stream Adaptors
//===----------------------------------------------------------------------===//
-/// raw_string_ostream - A raw_ostream that writes to an std::string. This is a
-/// simple adaptor class. This class does not encounter output errors.
+/// A raw_ostream that writes to an std::string. This is a simple adaptor
+/// class. This class does not encounter output errors.
class raw_string_ostream : public raw_ostream {
std::string &OS;
- /// write_impl - See raw_ostream::write_impl.
+ /// See raw_ostream::write_impl.
void write_impl(const char *Ptr, size_t Size) override;
- /// current_pos - Return the current position within the stream, not
- /// counting the bytes currently in the buffer.
+ /// Return the current position within the stream, not counting the bytes
+ /// currently in the buffer.
uint64_t current_pos() const override { return OS.size(); }
public:
explicit raw_string_ostream(std::string &O) : OS(O) {}
- ~raw_string_ostream();
+ ~raw_string_ostream() override;
- /// str - Flushes the stream contents to the target string and returns
- /// the string's reference.
+ /// Flushes the stream contents to the target string and returns the string's
+ /// reference.
std::string& str() {
flush();
return OS;
}
};
-/// raw_svector_ostream - A raw_ostream that writes to an SmallVector or
-/// SmallString. This is a simple adaptor class. This class does not
-/// encounter output errors.
-class raw_svector_ostream : public raw_ostream {
+/// A raw_ostream that writes to an SmallVector or SmallString. This is a
+/// simple adaptor class. This class does not encounter output errors.
+class raw_svector_ostream : public raw_pwrite_stream {
SmallVectorImpl<char> &OS;
- /// write_impl - See raw_ostream::write_impl.
+ /// See raw_ostream::write_impl.
void write_impl(const char *Ptr, size_t Size) override;
- /// current_pos - Return the current position within the stream, not
- /// counting the bytes currently in the buffer.
+ void pwrite_impl(const char *Ptr, size_t Size, uint64_t Offset) override;
+
+ /// Return the current position within the stream, not counting the bytes
+ /// currently in the buffer.
uint64_t current_pos() const override;
+
+protected:
+ // Like the regular constructor, but doesn't call init.
+ explicit raw_svector_ostream(SmallVectorImpl<char> &O, unsigned);
+ void init();
+
public:
/// Construct a new raw_svector_ostream.
///
/// \param O The vector to write to; this should generally have at least 128
/// bytes free to avoid any extraneous memory overhead.
explicit raw_svector_ostream(SmallVectorImpl<char> &O);
- ~raw_svector_ostream();
+ ~raw_svector_ostream() override;
- /// resync - This is called when the SmallVector we're appending to is changed
- /// outside of the raw_svector_ostream's control. It is only safe to do this
- /// if the raw_svector_ostream has previously been flushed.
+
+ /// This is called when the SmallVector we're appending to is changed outside
+ /// of the raw_svector_ostream's control. It is only safe to do this if the
+ /// raw_svector_ostream has previously been flushed.
void resync();
- /// str - Flushes the stream contents to the target vector and return a
- /// StringRef for the vector contents.
+ /// Flushes the stream contents to the target vector and return a StringRef
+ /// for the vector contents.
StringRef str();
};
-/// raw_null_ostream - A raw_ostream that discards all output.
-class raw_null_ostream : public raw_ostream {
- /// write_impl - See raw_ostream::write_impl.
+/// A raw_ostream that discards all output.
+class raw_null_ostream : public raw_pwrite_stream {
+ /// See raw_ostream::write_impl.
void write_impl(const char *Ptr, size_t size) override;
+ void pwrite_impl(const char *Ptr, size_t Size, uint64_t Offset) override;
- /// current_pos - Return the current position within the stream, not
- /// counting the bytes currently in the buffer.
+ /// Return the current position within the stream, not counting the bytes
+ /// currently in the buffer.
uint64_t current_pos() const override;
public:
explicit raw_null_ostream() {}
- ~raw_null_ostream();
+ ~raw_null_ostream() override;
+};
+
+class buffer_ostream : public raw_svector_ostream {
+ raw_ostream &OS;
+ SmallVector<char, 0> Buffer;
+
+public:
+ buffer_ostream(raw_ostream &OS) : raw_svector_ostream(Buffer, 0), OS(OS) {
+ init();
+ }
+ ~buffer_ostream() { OS << str(); }
};
} // end llvm namespace
diff --git a/include/llvm/Support/type_traits.h b/include/llvm/Support/type_traits.h
index 70953a9cb70e..45465aea004b 100644
--- a/include/llvm/Support/type_traits.h
+++ b/include/llvm/Support/type_traits.h
@@ -28,9 +28,17 @@ namespace llvm {
/// type can be copied around with memcpy instead of running ctors etc.
template <typename T>
struct isPodLike {
-#if __has_feature(is_trivially_copyable)
+ // std::is_trivially_copyable is available in libc++ with clang, libstdc++
+ // that comes with GCC 5.
+#if (__has_feature(is_trivially_copyable) && defined(_LIBCPP_VERSION)) || \
+ (defined(__GNUC__) && __GNUC__ >= 5)
// If the compiler supports the is_trivially_copyable trait use it, as it
// matches the definition of isPodLike closely.
+ static const bool value = std::is_trivially_copyable<T>::value;
+#elif __has_feature(is_trivially_copyable)
+ // Use the internal name if the compiler supports is_trivially_copyable but we
+ // don't know if the standard library does. This is the case for clang in
+ // conjunction with libstdc++ from GCC 4.x.
static const bool value = __is_trivially_copyable(T);
#else
// If we don't know anything else, we can (at least) assume that all non-class