aboutsummaryrefslogtreecommitdiff
path: root/include/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm')
-rw-r--r--include/llvm/ADT/IntrusiveRefCntPtr.h7
-rw-r--r--include/llvm/ADT/PriorityWorklist.h39
-rw-r--r--include/llvm/Analysis/Loads.h18
-rw-r--r--include/llvm/CodeGen/AsmPrinter.h5
-rw-r--r--include/llvm/CodeGen/MachineDominators.h4
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFDebugLine.h6
-rw-r--r--include/llvm/IR/IntrinsicsAMDGPU.td7
-rw-r--r--include/llvm/IR/IntrinsicsX86.td124
-rw-r--r--include/llvm/Support/FileSystem.h18
-rw-r--r--include/llvm/Support/YAMLTraits.h98
10 files changed, 169 insertions, 157 deletions
diff --git a/include/llvm/ADT/IntrusiveRefCntPtr.h b/include/llvm/ADT/IntrusiveRefCntPtr.h
index 559fb40773aa..a77cf04ea4d1 100644
--- a/include/llvm/ADT/IntrusiveRefCntPtr.h
+++ b/include/llvm/ADT/IntrusiveRefCntPtr.h
@@ -21,8 +21,8 @@
// class MyClass : public RefCountedBase<MyClass> {};
//
// void foo() {
-// // Objects that inherit from RefCountedBase should always be instantiated
-// // on the heap, never on the stack.
+// // Constructing an IntrusiveRefCntPtr increases the pointee's refcount by
+// // 1 (from 0 in this case).
// IntrusiveRefCntPtr<MyClass> Ptr1(new MyClass());
//
// // Copying an IntrusiveRefCntPtr increases the pointee's refcount by 1.
@@ -68,9 +68,6 @@ namespace llvm {
/// calls to Release() and Retain(), which increment and decrement the object's
/// refcount, respectively. When a Release() call decrements the refcount to 0,
/// the object deletes itself.
-///
-/// Objects that inherit from RefCountedBase should always be allocated with
-/// operator new.
template <class Derived> class RefCountedBase {
mutable unsigned RefCount = 0;
diff --git a/include/llvm/ADT/PriorityWorklist.h b/include/llvm/ADT/PriorityWorklist.h
index c0b4709e98f8..3198dd438700 100644
--- a/include/llvm/ADT/PriorityWorklist.h
+++ b/include/llvm/ADT/PriorityWorklist.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/Sequence.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Compiler.h"
#include <algorithm>
@@ -107,6 +108,39 @@ public:
return false;
}
+ /// Insert a sequence of new elements into the PriorityWorklist.
+ template <typename SequenceT>
+ typename std::enable_if<!std::is_convertible<SequenceT, T>::value>::type
+ insert(SequenceT &&Input) {
+ if (std::begin(Input) == std::end(Input))
+ // Nothing to do for an empty input sequence.
+ return;
+
+ // First pull the input sequence into the vector as a bulk append
+ // operation.
+ ptrdiff_t StartIndex = V.size();
+ V.insert(V.end(), std::begin(Input), std::end(Input));
+ // Now walk backwards fixing up the index map and deleting any duplicates.
+ for (ptrdiff_t i = V.size() - 1; i >= StartIndex; --i) {
+ auto InsertResult = M.insert({V[i], i});
+ if (InsertResult.second)
+ continue;
+
+ // If the existing index is before this insert's start, nuke that one and
+ // move it up.
+ ptrdiff_t &Index = InsertResult.first->second;
+ if (Index < StartIndex) {
+ V[Index] = T();
+ Index = i;
+ continue;
+ }
+
+ // Otherwise the existing one comes first so just clear out the value in
+ // this slot.
+ V[i] = T();
+ }
+ }
+
/// Remove the last element of the PriorityWorklist.
void pop_back() {
assert(!empty() && "Cannot remove an element when empty!");
@@ -169,6 +203,11 @@ public:
return true;
}
+ /// Reverse the items in the PriorityWorklist.
+ ///
+ /// This does an in-place reversal. Other kinds of reverse aren't easy to
+ /// support in the face of the worklist semantics.
+
/// Completely clear the PriorityWorklist
void clear() {
M.clear();
diff --git a/include/llvm/Analysis/Loads.h b/include/llvm/Analysis/Loads.h
index 139bf3c2116f..e167f36219d2 100644
--- a/include/llvm/Analysis/Loads.h
+++ b/include/llvm/Analysis/Loads.h
@@ -23,10 +23,9 @@ namespace llvm {
class DataLayout;
class MDNode;
-/// isDereferenceablePointer - Return true if this is always a dereferenceable
-/// pointer. If the context instruction is specified perform context-sensitive
-/// analysis and return true if the pointer is dereferenceable at the
-/// specified instruction.
+/// Return true if this is always a dereferenceable pointer. If the context
+/// instruction is specified perform context-sensitive analysis and return true
+/// if the pointer is dereferenceable at the specified instruction.
bool isDereferenceablePointer(const Value *V, const DataLayout &DL,
const Instruction *CtxI = nullptr,
const DominatorTree *DT = nullptr);
@@ -40,8 +39,7 @@ bool isDereferenceableAndAlignedPointer(const Value *V, unsigned Align,
const Instruction *CtxI = nullptr,
const DominatorTree *DT = nullptr);
-/// isSafeToLoadUnconditionally - Return true if we know that executing a load
-/// from this value cannot trap.
+/// Return true if we know that executing a load from this value cannot trap.
///
/// If DT and ScanFrom are specified this method performs context-sensitive
/// analysis and returns true if it is safe to load immediately before ScanFrom.
@@ -54,12 +52,12 @@ bool isSafeToLoadUnconditionally(Value *V, unsigned Align,
Instruction *ScanFrom = nullptr,
const DominatorTree *DT = nullptr);
-/// DefMaxInstsToScan - the default number of maximum instructions
-/// to scan in the block, used by FindAvailableLoadedValue().
+/// The default number of maximum instructions to scan in the block, used by
+/// FindAvailableLoadedValue().
extern cl::opt<unsigned> DefMaxInstsToScan;
-/// \brief Scan backwards to see if we have the value of the given load
-/// available locally within a small number of instructions.
+/// Scan backwards to see if we have the value of the given load available
+/// locally within a small number of instructions.
///
/// You can use this function to scan across multiple blocks: after you call
/// this function, if ScanFrom points at the beginning of the block, it's safe
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h
index c1be46ddd7b5..be8822df3dba 100644
--- a/include/llvm/CodeGen/AsmPrinter.h
+++ b/include/llvm/CodeGen/AsmPrinter.h
@@ -208,6 +208,8 @@ public:
SledKind Kind;
bool AlwaysInstrument;
const class Function *Fn;
+
+ void emit(int, MCStreamer *, const MCSymbol *) const;
};
// All the sleds to be emitted.
@@ -216,6 +218,9 @@ public:
// Helper function to record a given XRay sled.
void recordSled(MCSymbol *Sled, const MachineInstr &MI, SledKind Kind);
+ /// Emit a table with all XRay instrumentation points.
+ void emitXRayTable();
+
//===------------------------------------------------------------------===//
// MachineFunctionPass Implementation.
//===------------------------------------------------------------------===//
diff --git a/include/llvm/CodeGen/MachineDominators.h b/include/llvm/CodeGen/MachineDominators.h
index 76e1df89169e..21ecef587aa5 100644
--- a/include/llvm/CodeGen/MachineDominators.h
+++ b/include/llvm/CodeGen/MachineDominators.h
@@ -59,6 +59,9 @@ class MachineDominatorTree : public MachineFunctionPass {
/// such as BB == elt.NewBB.
mutable SmallSet<MachineBasicBlock *, 32> NewBBs;
+ /// The DominatorTreeBase that is used to compute a normal dominator tree
+ DominatorTreeBase<MachineBasicBlock>* DT;
+
/// \brief Apply all the recorded critical edges to the DT.
/// This updates the underlying DT information in a way that uses
/// the fast query path of DT as much as possible.
@@ -68,7 +71,6 @@ class MachineDominatorTree : public MachineFunctionPass {
public:
static char ID; // Pass ID, replacement for typeid
- DominatorTreeBase<MachineBasicBlock>* DT;
MachineDominatorTree();
diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h b/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
index ca9a6c822876..878f1c76ebf6 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
@@ -116,12 +116,12 @@ public:
// An unsigned integer indicating the identity of the source file
// corresponding to a machine instruction.
uint16_t File;
- // An unsigned integer whose value encodes the applicable instruction set
- // architecture for the current instruction.
- uint8_t Isa;
// An unsigned integer representing the DWARF path discriminator value
// for this location.
uint32_t Discriminator;
+ // An unsigned integer whose value encodes the applicable instruction set
+ // architecture for the current instruction.
+ uint8_t Isa;
// A boolean indicating that the current instruction is the beginning of a
// statement.
uint8_t IsStmt:1,
diff --git a/include/llvm/IR/IntrinsicsAMDGPU.td b/include/llvm/IR/IntrinsicsAMDGPU.td
index 078959ce15d0..07d5b5ea40dc 100644
--- a/include/llvm/IR/IntrinsicsAMDGPU.td
+++ b/include/llvm/IR/IntrinsicsAMDGPU.td
@@ -104,6 +104,13 @@ def int_amdgcn_dispatch_id :
// Instruction Intrinsics
//===----------------------------------------------------------------------===//
+// The first parameter is s_sendmsg immediate (i16),
+// the second one is copied to m0
+def int_amdgcn_s_sendmsg : GCCBuiltin<"__builtin_amdgcn_s_sendmsg">,
+ Intrinsic <[], [llvm_i32_ty, llvm_i32_ty], []>;
+def int_amdgcn_s_sendmsghalt : GCCBuiltin<"__builtin_amdgcn_s_sendmsghalt">,
+ Intrinsic <[], [llvm_i32_ty, llvm_i32_ty], []>;
+
def int_amdgcn_s_barrier : GCCBuiltin<"__builtin_amdgcn_s_barrier">,
Intrinsic<[], [], [IntrConvergent]>;
diff --git a/include/llvm/IR/IntrinsicsX86.td b/include/llvm/IR/IntrinsicsX86.td
index 3a496cb6645c..85966af9c820 100644
--- a/include/llvm/IR/IntrinsicsX86.td
+++ b/include/llvm/IR/IntrinsicsX86.td
@@ -2063,130 +2063,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
llvm_v4i64_ty, llvm_i8_ty], [IntrNoMem]>;
}
-// Vector extract and insert
-let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
- def int_x86_avx512_mask_vextractf32x4_512 :
- GCCBuiltin<"__builtin_ia32_extractf32x4_mask">,
- Intrinsic<[llvm_v4f32_ty], [llvm_v16f32_ty, llvm_i32_ty,
- llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_vextracti32x4_512 :
- GCCBuiltin<"__builtin_ia32_extracti32x4_mask">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v16i32_ty, llvm_i32_ty,
- llvm_v4i32_ty, llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_vextractf32x4_256 :
- GCCBuiltin<"__builtin_ia32_extractf32x4_256_mask">,
- Intrinsic<[llvm_v4f32_ty], [llvm_v8f32_ty, llvm_i32_ty,
- llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_vextracti32x4_256 :
- GCCBuiltin<"__builtin_ia32_extracti32x4_256_mask">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v8i32_ty, llvm_i32_ty,
- llvm_v4i32_ty, llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_vextractf64x2_256 :
- GCCBuiltin<"__builtin_ia32_extractf64x2_256_mask">,
- Intrinsic<[llvm_v2f64_ty], [llvm_v4f64_ty, llvm_i32_ty,
- llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_vextracti64x2_256 :
- GCCBuiltin<"__builtin_ia32_extracti64x2_256_mask">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v4i64_ty, llvm_i32_ty,
- llvm_v2i64_ty, llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_vextractf64x2_512 :
- GCCBuiltin<"__builtin_ia32_extractf64x2_512_mask">,
- Intrinsic<[llvm_v2f64_ty], [llvm_v8f64_ty, llvm_i32_ty,
- llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_vextracti64x2_512 :
- GCCBuiltin<"__builtin_ia32_extracti64x2_512_mask">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v8i64_ty, llvm_i32_ty,
- llvm_v2i64_ty, llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_vextractf32x8_512 :
- GCCBuiltin<"__builtin_ia32_extractf32x8_mask">,
- Intrinsic<[llvm_v8f32_ty], [llvm_v16f32_ty, llvm_i32_ty,
- llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_vextracti32x8_512 :
- GCCBuiltin<"__builtin_ia32_extracti32x8_mask">,
- Intrinsic<[llvm_v8i32_ty],[llvm_v16i32_ty, llvm_i32_ty,
- llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_vextractf64x4_512 :
- GCCBuiltin<"__builtin_ia32_extractf64x4_mask">,
- Intrinsic<[llvm_v4f64_ty], [llvm_v8f64_ty, llvm_i32_ty,
- llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_vextracti64x4_512 :
- GCCBuiltin<"__builtin_ia32_extracti64x4_mask">,
- Intrinsic<[llvm_v4i64_ty], [llvm_v8i64_ty, llvm_i32_ty,
- llvm_v4i64_ty, llvm_i8_ty], [IntrNoMem]>;
-
- def int_x86_avx512_mask_insertf32x4_256 :
- GCCBuiltin<"__builtin_ia32_insertf32x4_256_mask">,
- Intrinsic<[llvm_v8f32_ty],
- [llvm_v8f32_ty, llvm_v4f32_ty, llvm_i32_ty, llvm_v8f32_ty, llvm_i8_ty],
- [IntrNoMem]>;
-
- def int_x86_avx512_mask_insertf32x4_512 :
- GCCBuiltin<"__builtin_ia32_insertf32x4_mask">,
- Intrinsic<[llvm_v16f32_ty],
- [llvm_v16f32_ty, llvm_v4f32_ty, llvm_i32_ty, llvm_v16f32_ty, llvm_i16_ty],
- [IntrNoMem]>;
-
- def int_x86_avx512_mask_insertf32x8_512 :
- GCCBuiltin<"__builtin_ia32_insertf32x8_mask">,
- Intrinsic<[llvm_v16f32_ty],
- [llvm_v16f32_ty, llvm_v8f32_ty, llvm_i32_ty, llvm_v16f32_ty, llvm_i16_ty],
- [IntrNoMem]>;
-
- def int_x86_avx512_mask_insertf64x2_256 :
- GCCBuiltin<"__builtin_ia32_insertf64x2_256_mask">,
- Intrinsic<[llvm_v4f64_ty],
- [llvm_v4f64_ty, llvm_v2f64_ty, llvm_i32_ty, llvm_v4f64_ty, llvm_i8_ty],
- [IntrNoMem]>;
-
- def int_x86_avx512_mask_insertf64x2_512 :
- GCCBuiltin<"__builtin_ia32_insertf64x2_512_mask">,
- Intrinsic<[llvm_v8f64_ty],
- [llvm_v8f64_ty, llvm_v2f64_ty, llvm_i32_ty, llvm_v8f64_ty, llvm_i8_ty],
- [IntrNoMem]>;
-
- def int_x86_avx512_mask_insertf64x4_512 :
- GCCBuiltin<"__builtin_ia32_insertf64x4_mask">,
- Intrinsic<[llvm_v8f64_ty],
- [llvm_v8f64_ty, llvm_v4f64_ty, llvm_i32_ty, llvm_v8f64_ty, llvm_i8_ty],
- [IntrNoMem]>;
-
- def int_x86_avx512_mask_inserti32x4_256 :
- GCCBuiltin<"__builtin_ia32_inserti32x4_256_mask">,
- Intrinsic<[llvm_v8i32_ty],
- [llvm_v8i32_ty, llvm_v4i32_ty, llvm_i32_ty, llvm_v8i32_ty, llvm_i8_ty],
- [IntrNoMem]>;
-
- def int_x86_avx512_mask_inserti32x4_512 :
- GCCBuiltin<"__builtin_ia32_inserti32x4_mask">,
- Intrinsic<[llvm_v16i32_ty],
- [llvm_v16i32_ty, llvm_v4i32_ty, llvm_i32_ty, llvm_v16i32_ty, llvm_i16_ty],
- [IntrNoMem]>;
-
- def int_x86_avx512_mask_inserti32x8_512 :
- GCCBuiltin<"__builtin_ia32_inserti32x8_mask">,
- Intrinsic<[llvm_v16i32_ty],
- [llvm_v16i32_ty, llvm_v8i32_ty, llvm_i32_ty, llvm_v16i32_ty, llvm_i16_ty],
- [IntrNoMem]>;
-
- def int_x86_avx512_mask_inserti64x2_256 :
- GCCBuiltin<"__builtin_ia32_inserti64x2_256_mask">,
- Intrinsic<[llvm_v4i64_ty],
- [llvm_v4i64_ty, llvm_v2i64_ty, llvm_i32_ty, llvm_v4i64_ty, llvm_i8_ty],
- [IntrNoMem]>;
-
- def int_x86_avx512_mask_inserti64x2_512 :
- GCCBuiltin<"__builtin_ia32_inserti64x2_512_mask">,
- Intrinsic<[llvm_v8i64_ty],
- [llvm_v8i64_ty, llvm_v2i64_ty, llvm_i32_ty, llvm_v8i64_ty, llvm_i8_ty],
- [IntrNoMem]>;
-
- def int_x86_avx512_mask_inserti64x4_512 :
- GCCBuiltin<"__builtin_ia32_inserti64x4_mask">,
- Intrinsic<[llvm_v8i64_ty],
- [llvm_v8i64_ty, llvm_v4i64_ty, llvm_i32_ty, llvm_v8i64_ty, llvm_i8_ty],
- [IntrNoMem]>;
-}
-
// Conditional load ops
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx2_maskload_d : GCCBuiltin<"__builtin_ia32_maskloadd">,
diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h
index 9d8d8c3ffb5c..347f21108913 100644
--- a/include/llvm/Support/FileSystem.h
+++ b/include/llvm/Support/FileSystem.h
@@ -769,17 +769,13 @@ namespace detail {
std::error_code directory_iterator_increment(DirIterState &);
std::error_code directory_iterator_destruct(DirIterState &);
- /// DirIterState - Keeps state for the directory_iterator. It is reference
- /// counted in order to preserve InputIterator semantics on copy.
- struct DirIterState : public RefCountedBase<DirIterState> {
- DirIterState()
- : IterationHandle(0) {}
-
+ /// Keeps state for the directory_iterator.
+ struct DirIterState {
~DirIterState() {
directory_iterator_destruct(*this);
}
- intptr_t IterationHandle;
+ intptr_t IterationHandle = 0;
directory_entry CurrentEntry;
};
} // end namespace detail
@@ -788,23 +784,23 @@ namespace detail {
/// operator++ because we need an error_code. If it's really needed we can make
/// it call report_fatal_error on error.
class directory_iterator {
- IntrusiveRefCntPtr<detail::DirIterState> State;
+ std::shared_ptr<detail::DirIterState> State;
public:
explicit directory_iterator(const Twine &path, std::error_code &ec) {
- State = new detail::DirIterState;
+ State = std::make_shared<detail::DirIterState>();
SmallString<128> path_storage;
ec = detail::directory_iterator_construct(*State,
path.toStringRef(path_storage));
}
explicit directory_iterator(const directory_entry &de, std::error_code &ec) {
- State = new detail::DirIterState;
+ State = std::make_shared<detail::DirIterState>();
ec = detail::directory_iterator_construct(*State, de.path());
}
/// Construct end iterator.
- directory_iterator() : State(nullptr) {}
+ directory_iterator() = default;
// No operator++ because we need error_code.
directory_iterator &increment(std::error_code &ec) {
diff --git a/include/llvm/Support/YAMLTraits.h b/include/llvm/Support/YAMLTraits.h
index 38acb36942bc..cbba9c08275a 100644
--- a/include/llvm/Support/YAMLTraits.h
+++ b/include/llvm/Support/YAMLTraits.h
@@ -209,6 +209,15 @@ struct DocumentListTraits {
// static T::value_type& element(IO &io, T &seq, size_t index);
};
+/// This class should be specialized by any type that needs to be converted
+/// to/from a YAML mapping in the case where the names of the keys are not known
+/// in advance, e.g. a string map.
+template <typename T>
+struct CustomMappingTraits {
+ // static void inputOne(IO &io, StringRef key, T &elem);
+ // static void output(IO &io, T &elem);
+};
+
// Only used for better diagnostics of missing traits
template <typename T>
struct MissingTrait;
@@ -358,6 +367,23 @@ public:
static bool const value = (sizeof(test<SequenceTraits<T>>(nullptr)) == 1);
};
+// Test if CustomMappingTraits<T> is defined on type T.
+template <class T>
+struct has_CustomMappingTraits
+{
+ typedef void (*Signature_input)(IO &io, StringRef key, T &v);
+
+ template <typename U>
+ static char test(SameType<Signature_input, &U::inputOne>*);
+
+ template <typename U>
+ static double test(...);
+
+public:
+ static bool const value =
+ (sizeof(test<CustomMappingTraits<T>>(nullptr)) == 1);
+};
+
// has_FlowTraits<int> will cause an error with some compilers because
// it subclasses int. Using this wrapper only instantiates the
// real has_FlowTraits only if the template type is a class.
@@ -493,6 +519,7 @@ struct missingTraits
!has_BlockScalarTraits<T>::value &&
!has_MappingTraits<T, Context>::value &&
!has_SequenceTraits<T>::value &&
+ !has_CustomMappingTraits<T>::value &&
!has_DocumentListTraits<T>::value> {};
template <typename T, typename Context>
@@ -531,6 +558,7 @@ public:
virtual void endMapping() = 0;
virtual bool preflightKey(const char*, bool, bool, bool &, void *&) = 0;
virtual void postflightKey(void*) = 0;
+ virtual std::vector<StringRef> keys() = 0;
virtual void beginFlowMapping() = 0;
virtual void endFlowMapping() = 0;
@@ -819,6 +847,21 @@ yamlize(IO &io, T &Val, bool, Context &Ctx) {
}
template <typename T>
+typename std::enable_if<has_CustomMappingTraits<T>::value, void>::type
+yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
+ if ( io.outputting() ) {
+ io.beginMapping();
+ CustomMappingTraits<T>::output(io, Val);
+ io.endMapping();
+ } else {
+ io.beginMapping();
+ for (StringRef key : io.keys())
+ CustomMappingTraits<T>::inputOne(io, key, Val);
+ io.endMapping();
+ }
+}
+
+template <typename T>
typename std::enable_if<missingTraits<T, EmptyContext>::value, void>::type
yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
@@ -1074,6 +1117,7 @@ private:
void endMapping() override;
bool preflightKey(const char *, bool, bool, bool &, void *&) override;
void postflightKey(void *) override;
+ std::vector<StringRef> keys() override;
void beginFlowMapping() override;
void endFlowMapping() override;
unsigned beginSequence() override;
@@ -1154,10 +1198,8 @@ private:
typedef llvm::StringMap<std::unique_ptr<HNode>> NameToNode;
- bool isValidKey(StringRef key);
-
NameToNode Mapping;
- llvm::SmallVector<const char*, 6> ValidKeys;
+ llvm::SmallVector<std::string, 6> ValidKeys;
};
class SequenceHNode : public HNode {
@@ -1215,6 +1257,7 @@ public:
void endMapping() override;
bool preflightKey(const char *key, bool, bool, bool &, void *&) override;
void postflightKey(void *) override;
+ std::vector<StringRef> keys() override;
void beginFlowMapping() override;
void endFlowMapping() override;
unsigned beginSequence() override;
@@ -1384,6 +1427,17 @@ operator>>(Input &In, T &Val) {
return In;
}
+// Define non-member operator>> so that Input can stream in a string map.
+template <typename T>
+inline
+typename std::enable_if<has_CustomMappingTraits<T>::value, Input &>::type
+operator>>(Input &In, T &Val) {
+ EmptyContext Ctx;
+ if (In.setCurrentDocument())
+ yamlize(In, Val, true, Ctx);
+ return In;
+}
+
// Provide better error message about types missing a trait specialization
template <typename T>
inline typename std::enable_if<missingTraits<T, EmptyContext>::value,
@@ -1457,6 +1511,21 @@ operator<<(Output &Out, T &Val) {
return Out;
}
+// Define non-member operator<< so that Output can stream out a string map.
+template <typename T>
+inline
+typename std::enable_if<has_CustomMappingTraits<T>::value, Output &>::type
+operator<<(Output &Out, T &Val) {
+ EmptyContext Ctx;
+ Out.beginDocuments();
+ if (Out.preflightDocument(0)) {
+ yamlize(Out, Val, true, Ctx);
+ Out.postflightDocument();
+ }
+ Out.endDocuments();
+ return Out;
+}
+
// Provide better error message about types missing a trait specialization
template <typename T>
inline typename std::enable_if<missingTraits<T, EmptyContext>::value,
@@ -1476,6 +1545,18 @@ template <typename T> struct SequenceTraitsImpl {
}
};
+/// Implementation of CustomMappingTraits for std::map<std::string, T>.
+template <typename T> struct StdMapStringCustomMappingTraitsImpl {
+ typedef std::map<std::string, T> map_type;
+ static void inputOne(IO &io, StringRef key, map_type &v) {
+ io.mapRequired(key.str().c_str(), v[key]);
+ }
+ static void output(IO &io, map_type &v) {
+ for (auto &p : v)
+ io.mapRequired(p.first.c_str(), p.second);
+ }
+};
+
} // end namespace yaml
} // end namespace llvm
@@ -1530,4 +1611,15 @@ template <typename T> struct SequenceTraitsImpl {
} \
}
+/// Utility for declaring that std::map<std::string, _type> should be considered
+/// a YAML map.
+#define LLVM_YAML_IS_STRING_MAP(_type) \
+ namespace llvm { \
+ namespace yaml { \
+ template <> \
+ struct CustomMappingTraits<std::map<std::string, _type>> \
+ : public StdMapStringCustomMappingTraitsImpl<_type> {}; \
+ } \
+ }
+
#endif // LLVM_SUPPORT_YAMLTRAITS_H