Update clang to r339409b.

Change-Id: Ied8a188bb072c40035320acedc86164b66d920af
diff --git a/linux-x64/clang/include/llvm/XRay/BlockIndexer.h b/linux-x64/clang/include/llvm/XRay/BlockIndexer.h
new file mode 100644
index 0000000..46a7243
--- /dev/null
+++ b/linux-x64/clang/include/llvm/XRay/BlockIndexer.h
@@ -0,0 +1,67 @@
+//===- BlockIndexer.h - FDR Block Indexing Visitor ------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// An implementation of the RecordVisitor which generates a mapping between a
+// thread and a range of records representing a block.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIB_XRAY_BLOCKINDEXER_H_
+#define LLVM_LIB_XRAY_BLOCKINDEXER_H_
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/XRay/FDRRecords.h"
+#include <cstdint>
+#include <vector>
+
+namespace llvm {
+namespace xray {
+
+// The BlockIndexer will gather all related records associated with a
+// process+thread and group them by 'Block'.
+class BlockIndexer : public RecordVisitor {
+public:
+  struct Block {
+    uint64_t ProcessID;
+    int32_t ThreadID;
+    WallclockRecord *WallclockTime;
+    std::vector<Record *> Records;
+  };
+
+  // This maps the process + thread combination to a sequence of blocks.
+  using Index = DenseMap<std::pair<uint64_t, int32_t>, std::vector<Block>>;
+
+private:
+  Index &Indices;
+
+  Block CurrentBlock{0, 0, nullptr, {}};
+
+public:
+  explicit BlockIndexer(Index &I) : RecordVisitor(), Indices(I) {}
+
+  Error visit(BufferExtents &) override;
+  Error visit(WallclockRecord &) override;
+  Error visit(NewCPUIDRecord &) override;
+  Error visit(TSCWrapRecord &) override;
+  Error visit(CustomEventRecord &) override;
+  Error visit(CallArgRecord &) override;
+  Error visit(PIDRecord &) override;
+  Error visit(NewBufferRecord &) override;
+  Error visit(EndBufferRecord &) override;
+  Error visit(FunctionRecord &) override;
+
+  /// The flush() function will clear out the current state of the visitor, to
+  /// allow for explicitly flushing a block's records to the currently
+  /// recognized thread and process combination.
+  Error flush();
+};
+
+} // namespace xray
+} // namespace llvm
+
+#endif // LLVM_LIB_XRAY_BLOCKINDEXER_H_
diff --git a/linux-x64/clang/include/llvm/XRay/BlockPrinter.h b/linux-x64/clang/include/llvm/XRay/BlockPrinter.h
new file mode 100644
index 0000000..3a8f6e0
--- /dev/null
+++ b/linux-x64/clang/include/llvm/XRay/BlockPrinter.h
@@ -0,0 +1,60 @@
+//===- BlockPrinter.h - FDR Block Pretty Printer -------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// An implementation of the RecordVisitor which formats a block of records for
+// easier human consumption.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_INCLUDE_LLVM_XRAY_BLOCKPRINTER_H_
+#define LLVM_INCLUDE_LLVM_XRAY_BLOCKPRINTER_H_
+
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/XRay/FDRRecords.h"
+#include "llvm/XRay/RecordPrinter.h"
+
+namespace llvm {
+namespace xray {
+
+class BlockPrinter : public RecordVisitor {
+  enum class State {
+    Start,
+    Preamble,
+    Metadata,
+    Function,
+    Arg,
+    CustomEvent,
+    End,
+  };
+
+  raw_ostream &OS;
+  RecordPrinter &RP;
+  State CurrentState = State::Start;
+
+public:
+  explicit BlockPrinter(raw_ostream &O, RecordPrinter &P)
+      : RecordVisitor(), OS(O), RP(P) {}
+
+  Error visit(BufferExtents &) override;
+  Error visit(WallclockRecord &) override;
+  Error visit(NewCPUIDRecord &) override;
+  Error visit(TSCWrapRecord &) override;
+  Error visit(CustomEventRecord &) override;
+  Error visit(CallArgRecord &) override;
+  Error visit(PIDRecord &) override;
+  Error visit(NewBufferRecord &) override;
+  Error visit(EndBufferRecord &) override;
+  Error visit(FunctionRecord &) override;
+
+  void reset() { CurrentState = State::Start; }
+};
+
+} // namespace xray
+} // namespace llvm
+
+#endif // LLVM_INCLUDE_LLVM_XRAY_BLOCKPRINTER_H_
diff --git a/linux-x64/clang/include/llvm/XRay/BlockVerifier.h b/linux-x64/clang/include/llvm/XRay/BlockVerifier.h
new file mode 100644
index 0000000..b43a435
--- /dev/null
+++ b/linux-x64/clang/include/llvm/XRay/BlockVerifier.h
@@ -0,0 +1,69 @@
+//===- BlockVerifier.h - FDR Block Verifier -------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// An implementation of the RecordVisitor which verifies a sequence of records
+// associated with a block, following the FDR mode log format's specifications.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_INCLUDE_LLVM_XRAY_BLOCKVERIFIER_H_
+#define LLVM_INCLUDE_LLVM_XRAY_BLOCKVERIFIER_H_
+
+#include "llvm/XRay/FDRRecords.h"
+#include <array>
+#include <bitset>
+
+namespace llvm {
+namespace xray {
+
+class BlockVerifier : public RecordVisitor {
+public:
+  // We force State elements to be size_t, to be used as indices for containers.
+  enum class State : std::size_t {
+    Unknown,
+    BufferExtents,
+    NewBuffer,
+    WallClockTime,
+    PIDEntry,
+    NewCPUId,
+    TSCWrap,
+    CustomEvent,
+    Function,
+    CallArg,
+    EndOfBuffer,
+    StateMax,
+  };
+
+private:
+  // We keep track of the current record seen by the verifier.
+  State CurrentRecord = State::Unknown;
+
+  // Transitions the current record to the new record, records an error on
+  // invalid transitions.
+  Error transition(State To);
+
+public:
+  Error visit(BufferExtents &) override;
+  Error visit(WallclockRecord &) override;
+  Error visit(NewCPUIDRecord &) override;
+  Error visit(TSCWrapRecord &) override;
+  Error visit(CustomEventRecord &) override;
+  Error visit(CallArgRecord &) override;
+  Error visit(PIDRecord &) override;
+  Error visit(NewBufferRecord &) override;
+  Error visit(EndBufferRecord &) override;
+  Error visit(FunctionRecord &) override;
+
+  Error verify();
+  void reset();
+};
+
+} // namespace xray
+} // namespace llvm
+
+#endif // LLVM_INCLUDE_LLVM_XRAY_BLOCKVERIFIER_H_
diff --git a/linux-x64/clang/include/llvm/XRay/FDRLogBuilder.h b/linux-x64/clang/include/llvm/XRay/FDRLogBuilder.h
new file mode 100644
index 0000000..b5e9ed5
--- /dev/null
+++ b/linux-x64/clang/include/llvm/XRay/FDRLogBuilder.h
@@ -0,0 +1,41 @@
+//===- FDRLogBuilder.h - XRay FDR Log Building Utility --------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_INCLUDE_LLVM_XRAY_FDRLOGBUILDER_H_
+#define LLVM_INCLUDE_LLVM_XRAY_FDRLOGBUILDER_H_
+
+#include "llvm/XRay/FDRRecords.h"
+
+namespace llvm {
+namespace xray {
+
+/// The LogBuilder class allows for creating ad-hoc collections of records
+/// through the `add<...>(...)` function. An example use of this API is in
+/// crafting arbitrary sequences of records:
+///
+///   auto Records = LogBuilder()
+///       .add<BufferExtents>(256)
+///       .add<NewBufferRecord>(1)
+///       .consume();
+///
+class LogBuilder {
+  std::vector<std::unique_ptr<Record>> Records;
+
+public:
+  template <class R, class... T> LogBuilder &add(T &&... A) {
+    Records.emplace_back(new R(std::forward<T>(A)...));
+    return *this;
+  }
+
+  std::vector<std::unique_ptr<Record>> consume() { return std::move(Records); }
+};
+
+} // namespace xray
+} // namespace llvm
+
+#endif // LLVM_INCLUDE_LLVM_XRAY_FDRLOGBUILDER_H_
diff --git a/linux-x64/clang/include/llvm/XRay/FDRRecordConsumer.h b/linux-x64/clang/include/llvm/XRay/FDRRecordConsumer.h
new file mode 100644
index 0000000..e856e15
--- /dev/null
+++ b/linux-x64/clang/include/llvm/XRay/FDRRecordConsumer.h
@@ -0,0 +1,55 @@
+//===- FDRRecordConsumer.h - XRay Flight Data Recorder Mode Records -------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_INCLUDE_LLVM_XRAY_FDRRECORDCONSUMER_H_
+#define LLVM_INCLUDE_LLVM_XRAY_FDRRECORDCONSUMER_H_
+
+#include "llvm/Support/Error.h"
+#include "llvm/XRay/FDRRecords.h"
+#include <algorithm>
+#include <memory>
+#include <vector>
+
+namespace llvm {
+namespace xray {
+
+class RecordConsumer {
+public:
+  virtual Error consume(std::unique_ptr<Record> R) = 0;
+  virtual ~RecordConsumer() = default;
+};
+
+// This consumer will collect all the records into a vector of records, in
+// arrival order.
+class LogBuilderConsumer : public RecordConsumer {
+  std::vector<std::unique_ptr<Record>> &Records;
+
+public:
+  explicit LogBuilderConsumer(std::vector<std::unique_ptr<Record>> &R)
+      : RecordConsumer(), Records(R) {}
+
+  Error consume(std::unique_ptr<Record> R) override;
+};
+
+// A PipelineConsumer applies a set of visitors to every consumed Record, in the
+// order by which the visitors are added to the pipeline in the order of
+// appearance.
+class PipelineConsumer : public RecordConsumer {
+  std::vector<RecordVisitor *> Visitors;
+
+public:
+  PipelineConsumer(std::initializer_list<RecordVisitor *> V)
+      : RecordConsumer(), Visitors(V) {}
+
+  Error consume(std::unique_ptr<Record> R) override;
+};
+
+} // namespace xray
+} // namespace llvm
+
+#endif // LLVM_INCLUDE_LLVM_XRAY_FDRRECORDCONSUMER_H_
diff --git a/linux-x64/clang/include/llvm/XRay/FDRRecordProducer.h b/linux-x64/clang/include/llvm/XRay/FDRRecordProducer.h
new file mode 100644
index 0000000..e67e228
--- /dev/null
+++ b/linux-x64/clang/include/llvm/XRay/FDRRecordProducer.h
@@ -0,0 +1,46 @@
+//===- FDRRecordProducer.h - XRay FDR Mode Record Producer ----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_INCLUDE_LLVM_XRAY_FDRRECORDPRODUCER_H_
+#define LLVM_INCLUDE_LLVM_XRAY_FDRRECORDPRODUCER_H_
+
+#include "llvm/Support/Error.h"
+#include "llvm/XRay/FDRRecords.h"
+#include "llvm/XRay/XRayRecord.h"
+#include <memory>
+
+namespace llvm {
+namespace xray {
+
+class RecordProducer {
+public:
+  /// All producer implementations must yield either an Error or a non-nullptr
+  /// unique_ptr<Record>.
+  virtual Expected<std::unique_ptr<Record>> produce() = 0;
+  virtual ~RecordProducer() = default;
+};
+
+class FileBasedRecordProducer : public RecordProducer {
+  const XRayFileHeader &Header;
+  DataExtractor &E;
+  uint32_t &OffsetPtr;
+
+public:
+  FileBasedRecordProducer(const XRayFileHeader &FH, DataExtractor &DE,
+                          uint32_t &OP)
+      : Header(FH), E(DE), OffsetPtr(OP) {}
+
+  /// This producer encapsulates the logic for loading a File-backed
+  /// RecordProducer hidden behind a DataExtractor.
+  Expected<std::unique_ptr<Record>> produce() override;
+};
+
+} // namespace xray
+} // namespace llvm
+
+#endif // LLVM_INCLUDE_LLVM_XRAY_FDRRECORDPRODUCER_H_
diff --git a/linux-x64/clang/include/llvm/XRay/FDRRecords.h b/linux-x64/clang/include/llvm/XRay/FDRRecords.h
new file mode 100644
index 0000000..c524dab
--- /dev/null
+++ b/linux-x64/clang/include/llvm/XRay/FDRRecords.h
@@ -0,0 +1,295 @@
+//===- FDRRecords.h - XRay Flight Data Recorder Mode Records --------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Define types and operations on these types that represent the different kinds
+// of records we encounter in XRay flight data recorder mode traces.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIB_XRAY_FDRRECORDS_H_
+#define LLVM_LIB_XRAY_FDRRECORDS_H_
+
+#include "llvm/Support/DataExtractor.h"
+#include "llvm/Support/Error.h"
+#include "llvm/XRay/XRayRecord.h"
+#include <cstdint>
+
+namespace llvm {
+namespace xray {
+
+class RecordVisitor;
+class RecordInitializer;
+
+class Record {
+protected:
+  enum class Type {
+    Unknown,
+    Function,
+    Metadata,
+  };
+
+public:
+  Record(const Record &) = delete;
+  Record(Record &&) = delete;
+  Record &operator=(const Record &) = delete;
+  Record &operator=(Record &&) = delete;
+  Record() = default;
+
+  virtual Type type() const = 0;
+
+  // Each Record should be able to apply an abstract visitor, and choose the
+  // appropriate function in the visitor to invoke, given its own type.
+  virtual Error apply(RecordVisitor &V) = 0;
+
+  virtual ~Record() = default;
+};
+
+class MetadataRecord : public Record {
+protected:
+  static constexpr int kMetadataBodySize = 15;
+  friend class RecordInitializer;
+
+public:
+  enum class MetadataType : unsigned {
+    Unknown,
+    BufferExtents,
+    WallClockTime,
+    NewCPUId,
+    TSCWrap,
+    CustomEvent,
+    CallArg,
+    PIDEntry,
+    NewBuffer,
+    EndOfBuffer,
+  };
+
+  Type type() const override { return Type::Metadata; }
+
+  // All metadata records must know to provide the type of their open
+  // metadata record.
+  virtual MetadataType metadataType() const = 0;
+
+  virtual ~MetadataRecord() = default;
+};
+
+// What follows are specific Metadata record types which encapsulate the
+// information associated with specific metadata record types in an FDR mode
+// log.
+class BufferExtents : public MetadataRecord {
+  uint64_t Size = 0;
+  friend class RecordInitializer;
+
+public:
+  BufferExtents() = default;
+  explicit BufferExtents(uint64_t S) : MetadataRecord(), Size(S) {}
+
+  MetadataType metadataType() const override {
+    return MetadataType::BufferExtents;
+  }
+
+  uint64_t size() const { return Size; }
+
+  Error apply(RecordVisitor &V) override;
+};
+
+class WallclockRecord : public MetadataRecord {
+  uint64_t Seconds = 0;
+  uint32_t Nanos = 0;
+  friend class RecordInitializer;
+
+public:
+  WallclockRecord() = default;
+  explicit WallclockRecord(uint64_t S, uint32_t N)
+      : MetadataRecord(), Seconds(S), Nanos(N) {}
+
+  MetadataType metadataType() const override {
+    return MetadataType::WallClockTime;
+  }
+
+  uint64_t seconds() const { return Seconds; }
+  uint32_t nanos() const { return Nanos; }
+
+  Error apply(RecordVisitor &V) override;
+};
+
+class NewCPUIDRecord : public MetadataRecord {
+  uint16_t CPUId = 0;
+  uint64_t TSC = 0;
+  friend class RecordInitializer;
+
+public:
+  NewCPUIDRecord() = default;
+  NewCPUIDRecord(uint16_t C, uint64_t T) : MetadataRecord(), CPUId(C), TSC(T) {}
+
+  MetadataType metadataType() const override { return MetadataType::NewCPUId; }
+
+  uint16_t cpuid() const { return CPUId; }
+
+  uint64_t tsc() const { return TSC; }
+
+  Error apply(RecordVisitor &V) override;
+};
+
+class TSCWrapRecord : public MetadataRecord {
+  uint64_t BaseTSC = 0;
+  friend class RecordInitializer;
+
+public:
+  TSCWrapRecord() = default;
+  explicit TSCWrapRecord(uint64_t B) : MetadataRecord(), BaseTSC(B) {}
+
+  MetadataType metadataType() const override { return MetadataType::TSCWrap; }
+
+  uint64_t tsc() const { return BaseTSC; }
+
+  Error apply(RecordVisitor &V) override;
+};
+
+class CustomEventRecord : public MetadataRecord {
+  int32_t Size = 0;
+  uint64_t TSC = 0;
+  std::string Data{};
+  friend class RecordInitializer;
+
+public:
+  CustomEventRecord() = default;
+  explicit CustomEventRecord(uint64_t S, uint64_t T, std::string D)
+      : MetadataRecord(), Size(S), TSC(T), Data(std::move(D)) {}
+
+  MetadataType metadataType() const override {
+    return MetadataType::CustomEvent;
+  }
+
+  int32_t size() const { return Size; }
+  uint64_t tsc() const { return TSC; }
+  StringRef data() const { return Data; }
+
+  Error apply(RecordVisitor &V) override;
+};
+
+class CallArgRecord : public MetadataRecord {
+  uint64_t Arg;
+  friend class RecordInitializer;
+
+public:
+  CallArgRecord() = default;
+  explicit CallArgRecord(uint64_t A) : MetadataRecord(), Arg(A) {}
+
+  MetadataType metadataType() const override { return MetadataType::CallArg; }
+
+  uint64_t arg() const { return Arg; }
+
+  Error apply(RecordVisitor &V) override;
+};
+
+class PIDRecord : public MetadataRecord {
+  int32_t PID = 0;
+  friend class RecordInitializer;
+
+public:
+  PIDRecord() = default;
+  explicit PIDRecord(int32_t P) : MetadataRecord(), PID(P) {}
+
+  MetadataType metadataType() const override { return MetadataType::PIDEntry; }
+
+  int32_t pid() const { return PID; }
+
+  Error apply(RecordVisitor &V) override;
+};
+
+class NewBufferRecord : public MetadataRecord {
+  int32_t TID = 0;
+  friend class RecordInitializer;
+
+public:
+  NewBufferRecord() = default;
+  explicit NewBufferRecord(int32_t T) : MetadataRecord(), TID(T) {}
+
+  MetadataType metadataType() const override { return MetadataType::NewBuffer; }
+
+  int32_t tid() const { return TID; }
+
+  Error apply(RecordVisitor &V) override;
+};
+
+class EndBufferRecord : public MetadataRecord {
+public:
+  EndBufferRecord() = default;
+
+  MetadataType metadataType() const override {
+    return MetadataType::EndOfBuffer;
+  }
+
+  Error apply(RecordVisitor &V) override;
+};
+
+class FunctionRecord : public Record {
+  RecordTypes Kind;
+  int32_t FuncId;
+  uint32_t Delta;
+  friend class RecordInitializer;
+
+  static constexpr unsigned kFunctionRecordSize = 8;
+
+public:
+  FunctionRecord() = default;
+  explicit FunctionRecord(RecordTypes K, int32_t F, uint32_t D)
+      : Record(), Kind(K), FuncId(F), Delta(D) {}
+
+  Type type() const override { return Type::Function; }
+
+  // A function record is a concrete record type which has a number of common
+  // properties.
+  RecordTypes recordType() const { return Kind; }
+  int32_t functionId() const { return FuncId; }
+  uint32_t delta() const { return Delta; }
+
+  Error apply(RecordVisitor &V) override;
+};
+
+class RecordVisitor {
+public:
+  virtual ~RecordVisitor() = default;
+
+  // Support all specific kinds of records:
+  virtual Error visit(BufferExtents &) = 0;
+  virtual Error visit(WallclockRecord &) = 0;
+  virtual Error visit(NewCPUIDRecord &) = 0;
+  virtual Error visit(TSCWrapRecord &) = 0;
+  virtual Error visit(CustomEventRecord &) = 0;
+  virtual Error visit(CallArgRecord &) = 0;
+  virtual Error visit(PIDRecord &) = 0;
+  virtual Error visit(NewBufferRecord &) = 0;
+  virtual Error visit(EndBufferRecord &) = 0;
+  virtual Error visit(FunctionRecord &) = 0;
+};
+
+class RecordInitializer : public RecordVisitor {
+  DataExtractor &E;
+  uint32_t &OffsetPtr;
+
+public:
+  explicit RecordInitializer(DataExtractor &DE, uint32_t &OP)
+      : RecordVisitor(), E(DE), OffsetPtr(OP) {}
+
+  Error visit(BufferExtents &) override;
+  Error visit(WallclockRecord &) override;
+  Error visit(NewCPUIDRecord &) override;
+  Error visit(TSCWrapRecord &) override;
+  Error visit(CustomEventRecord &) override;
+  Error visit(CallArgRecord &) override;
+  Error visit(PIDRecord &) override;
+  Error visit(NewBufferRecord &) override;
+  Error visit(EndBufferRecord &) override;
+  Error visit(FunctionRecord &) override;
+};
+
+} // namespace xray
+} // namespace llvm
+
+#endif // LLVM_LIB_XRAY_FDRRECORDS_H_
diff --git a/linux-x64/clang/include/llvm/XRay/FDRTraceExpander.h b/linux-x64/clang/include/llvm/XRay/FDRTraceExpander.h
new file mode 100644
index 0000000..7f8236b
--- /dev/null
+++ b/linux-x64/clang/include/llvm/XRay/FDRTraceExpander.h
@@ -0,0 +1,61 @@
+//===- FDRTraceExpander.h - XRay FDR Mode Log Expander --------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// We define an FDR record visitor which can re-constitute XRayRecord instances
+// from a sequence of FDR mode records in arrival order into a collection.
+//
+//===----------------------------------------------------------------------===//
+#ifndef INCLUDE_LLVM_XRAY_FDRTRACEEXPANDER_H_
+#define INCLUDE_LLVM_XRAY_FDRTRACEEXPANDER_H_
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/XRay/FDRRecords.h"
+#include "llvm/XRay/XRayRecord.h"
+
+namespace llvm {
+namespace xray {
+
+class TraceExpander : public RecordVisitor {
+  // Type-erased callback for handling individual XRayRecord instances.
+  function_ref<void(const XRayRecord &)> C;
+  int32_t PID = 0;
+  int32_t TID = 0;
+  uint64_t BaseTSC = 0;
+  XRayRecord CurrentRecord{0, 0, RecordTypes::ENTER, 0, 0, 0, 0, {}};
+  uint16_t CPUId = 0;
+  uint16_t LogVersion = 0;
+  bool BuildingFunction = false;
+  bool IgnoringRecords = false;
+
+  void resetCurrentRecord();
+
+public:
+  explicit TraceExpander(function_ref<void(const XRayRecord &)> F, uint16_t L)
+      : RecordVisitor(), C(std::move(F)), LogVersion(L) {}
+
+  Error visit(BufferExtents &) override;
+  Error visit(WallclockRecord &) override;
+  Error visit(NewCPUIDRecord &) override;
+  Error visit(TSCWrapRecord &) override;
+  Error visit(CustomEventRecord &) override;
+  Error visit(CallArgRecord &) override;
+  Error visit(PIDRecord &) override;
+  Error visit(NewBufferRecord &) override;
+  Error visit(EndBufferRecord &) override;
+  Error visit(FunctionRecord &) override;
+
+  // Must be called after all the records have been processed, to handle the
+  // most recent record generated.
+  Error flush();
+};
+
+} // namespace xray
+} // namespace llvm
+
+#endif // INCLUDE_LLVM_XRAY_FDRTRACEEXPANDER_H_
diff --git a/linux-x64/clang/include/llvm/XRay/FDRTraceWriter.h b/linux-x64/clang/include/llvm/XRay/FDRTraceWriter.h
new file mode 100644
index 0000000..91488f8
--- /dev/null
+++ b/linux-x64/clang/include/llvm/XRay/FDRTraceWriter.h
@@ -0,0 +1,54 @@
+//===- FDRTraceWriter.h - XRay FDR Trace Writer -----------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Test a utility that can write out XRay FDR Mode formatted trace files.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_INCLUDE_LLVM_XRAY_FDRTRACEWRITER_H_
+#define LLVM_INCLUDE_LLVM_XRAY_FDRTRACEWRITER_H_
+
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/EndianStream.h"
+#include "llvm/XRay/FDRRecords.h"
+#include "llvm/XRay/XRayRecord.h"
+
+namespace llvm {
+namespace xray {
+
+/// The FDRTraceWriter allows us to hand-craft an XRay Flight Data Recorder
+/// (FDR) mode log file. This is used primarily for testing, generating
+/// sequences of FDR records that can be read/processed. It can also be used to
+/// generate various kinds of execution traces without using the XRay runtime.
+/// Note that this writer does not do any validation, but uses the types of
+/// records defined in the FDRRecords.h file.
+class FDRTraceWriter : public RecordVisitor {
+public:
+  // Construct an FDRTraceWriter associated with an output stream.
+  explicit FDRTraceWriter(raw_ostream &O, const XRayFileHeader &H);
+  ~FDRTraceWriter();
+
+  Error visit(BufferExtents &) override;
+  Error visit(WallclockRecord &) override;
+  Error visit(NewCPUIDRecord &) override;
+  Error visit(TSCWrapRecord &) override;
+  Error visit(CustomEventRecord &) override;
+  Error visit(CallArgRecord &) override;
+  Error visit(PIDRecord &) override;
+  Error visit(NewBufferRecord &) override;
+  Error visit(EndBufferRecord &) override;
+  Error visit(FunctionRecord &) override;
+
+private:
+  support::endian::Writer OS;
+};
+
+} // namespace xray
+} // namespace llvm
+
+#endif // LLVM_INCLUDE_LLVM_XRAY_FDRTRACEWRITER_H_
diff --git a/linux-x64/clang/include/llvm/XRay/FileHeaderReader.h b/linux-x64/clang/include/llvm/XRay/FileHeaderReader.h
new file mode 100644
index 0000000..3b8809b
--- /dev/null
+++ b/linux-x64/clang/include/llvm/XRay/FileHeaderReader.h
@@ -0,0 +1,33 @@
+//===- FileHeaderReader.h - XRay Trace File Header Reading Function -------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares functions that can load an XRay log header from various
+// sources.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIB_XRAY_FILEHEADERREADER_H_
+#define LLVM_LIB_XRAY_FILEHEADERREADER_H_
+
+#include "llvm/Support/DataExtractor.h"
+#include "llvm/Support/Error.h"
+#include "llvm/XRay/XRayRecord.h"
+#include <cstdint>
+
+namespace llvm {
+namespace xray {
+
+/// Convenience function for loading the file header given a data extractor at a
+/// specified offset.
+Expected<XRayFileHeader> readBinaryFormatHeader(DataExtractor &HeaderExtractor,
+                                                uint32_t &OffsetPtr);
+
+} // namespace xray
+} // namespace llvm
+
+#endif // LLVM_LIB_XRAY_FILEHEADERREADER_H_
diff --git a/linux-x64/clang/include/llvm/XRay/Profile.h b/linux-x64/clang/include/llvm/XRay/Profile.h
new file mode 100644
index 0000000..9365630
--- /dev/null
+++ b/linux-x64/clang/include/llvm/XRay/Profile.h
@@ -0,0 +1,150 @@
+//===- Profile.h - XRay Profile Abstraction -------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines the XRay Profile class representing the latency profile generated by
+// XRay's profiling mode.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_XRAY_PROFILE_H
+#define LLVM_XRAY_PROFILE_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
+#include <list>
+#include <utility>
+#include <vector>
+
+namespace llvm {
+namespace xray {
+
+class Profile;
+
+// We forward declare the Trace type for turning a Trace into a Profile.
+class Trace;
+
+/// This function will attempt to load an XRay Profiling Mode profile from the
+/// provided |Filename|.
+///
+/// For any errors encountered in the loading of the profile data from
+/// |Filename|, this function will return an Error condition appropriately.
+Expected<Profile> loadProfile(StringRef Filename);
+
+/// This algorithm will merge two Profile instances into a single Profile
+/// instance, aggregating blocks by Thread ID.
+Profile mergeProfilesByThread(const Profile &L, const Profile &R);
+
+/// This algorithm will merge two Profile instances into a single Profile
+/// instance, aggregating blocks by function call stack.
+Profile mergeProfilesByStack(const Profile &L, const Profile &R);
+
+/// This function takes a Trace and creates a Profile instance from it.
+Expected<Profile> profileFromTrace(const Trace &T);
+
+/// Profile instances are thread-compatible.
+class Profile {
+public:
+  using ThreadID = uint64_t;
+  using PathID = unsigned;
+  using FuncID = int32_t;
+
+  struct Data {
+    uint64_t CallCount;
+    uint64_t CumulativeLocalTime;
+  };
+
+  struct Block {
+    ThreadID Thread;
+    std::vector<std::pair<PathID, Data>> PathData;
+  };
+
+  /// Provides a sequence of function IDs from a previously interned PathID.
+  ///
+  /// Returns an error if |P| had not been interned before into the Profile.
+  ///
+  Expected<std::vector<FuncID>> expandPath(PathID P) const;
+
+  /// The stack represented in |P| must be in stack order (leaf to root). This
+  /// will always return the same PathID for |P| that has the same sequence.
+  PathID internPath(ArrayRef<FuncID> P);
+
+  /// Appends a fully-formed Block instance into the Profile.
+  ///
+  /// Returns an error condition in the following cases:
+  ///
+  ///    - The PathData component of the Block is empty
+  ///
+  Error addBlock(Block &&B);
+
+  Profile() = default;
+  ~Profile() = default;
+
+  Profile(Profile &&O) noexcept
+      : Blocks(std::move(O.Blocks)), NodeStorage(std::move(O.NodeStorage)),
+        Roots(std::move(O.Roots)), PathIDMap(std::move(O.PathIDMap)),
+        NextID(O.NextID) {}
+
+  Profile &operator=(Profile &&O) noexcept {
+    Blocks = std::move(O.Blocks);
+    NodeStorage = std::move(O.NodeStorage);
+    Roots = std::move(O.Roots);
+    PathIDMap = std::move(O.PathIDMap);
+    NextID = O.NextID;
+    return *this;
+  }
+
+  Profile(const Profile &);
+  Profile &operator=(const Profile &);
+
+  friend void swap(Profile &L, Profile &R) {
+    using std::swap;
+    swap(L.Blocks, R.Blocks);
+    swap(L.NodeStorage, R.NodeStorage);
+    swap(L.Roots, R.Roots);
+    swap(L.PathIDMap, R.PathIDMap);
+    swap(L.NextID, R.NextID);
+  }
+
+private:
+  using BlockList = std::list<Block>;
+
+  struct TrieNode {
+    FuncID Func = 0;
+    std::vector<TrieNode *> Callees{};
+    TrieNode *Caller = nullptr;
+    PathID ID = 0;
+  };
+
+  // List of blocks associated with a Profile.
+  BlockList Blocks;
+
+  // List of TrieNode elements we've seen.
+  std::list<TrieNode> NodeStorage;
+
+  // List of call stack roots.
+  SmallVector<TrieNode *, 4> Roots;
+
+  // Reverse mapping between a PathID to a TrieNode*.
+  DenseMap<PathID, TrieNode *> PathIDMap;
+
+  // Used to identify paths.
+  PathID NextID = 1;
+
+public:
+  using const_iterator = BlockList::const_iterator;
+  const_iterator begin() const { return Blocks.begin(); }
+  const_iterator end() const { return Blocks.end(); }
+  bool empty() const { return Blocks.empty(); }
+};
+
+} // namespace xray
+} // namespace llvm
+
+#endif
diff --git a/linux-x64/clang/include/llvm/XRay/RecordPrinter.h b/linux-x64/clang/include/llvm/XRay/RecordPrinter.h
new file mode 100644
index 0000000..bad1a57
--- /dev/null
+++ b/linux-x64/clang/include/llvm/XRay/RecordPrinter.h
@@ -0,0 +1,48 @@
+//===- RecordPrinter.h - FDR Record Printer -------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// An implementation of the RecordVisitor which prints an individual record's
+// data in an adhoc format, suitable for human inspection.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_INCLUDE_LLVM_XRAY_RECORDPRINTER_H_
+#define LLVM_INCLUDE_LLVM_XRAY_RECORDPRINTER_H_
+
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/XRay/FDRRecords.h"
+
+namespace llvm {
+namespace xray {
+
+class RecordPrinter : public RecordVisitor {
+  raw_ostream &OS;
+  std::string Delim;
+
+public:
+  explicit RecordPrinter(raw_ostream &O, std::string D)
+      : RecordVisitor(), OS(O), Delim(std::move(D)) {}
+
+  explicit RecordPrinter(raw_ostream &O) : RecordPrinter(O, ""){};
+
+  Error visit(BufferExtents &) override;
+  Error visit(WallclockRecord &) override;
+  Error visit(NewCPUIDRecord &) override;
+  Error visit(TSCWrapRecord &) override;
+  Error visit(CustomEventRecord &) override;
+  Error visit(CallArgRecord &) override;
+  Error visit(PIDRecord &) override;
+  Error visit(NewBufferRecord &) override;
+  Error visit(EndBufferRecord &) override;
+  Error visit(FunctionRecord &) override;
+};
+
+} // namespace xray
+} // namespace llvm
+
+#endif // LLVM_INCLUDE_LLVM_XRAY_RECORDPRINTER_H
diff --git a/linux-x64/clang/include/llvm/XRay/Trace.h b/linux-x64/clang/include/llvm/XRay/Trace.h
index 6b033d6..924addd 100644
--- a/linux-x64/clang/include/llvm/XRay/Trace.h
+++ b/linux-x64/clang/include/llvm/XRay/Trace.h
@@ -17,8 +17,8 @@
 #include <vector>
 
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DataExtractor.h"
 #include "llvm/Support/Error.h"
-#include "llvm/Support/FileSystem.h"
 #include "llvm/XRay/XRayRecord.h"
 
 namespace llvm {
@@ -46,25 +46,35 @@
 ///
 class Trace {
   XRayFileHeader FileHeader;
-  std::vector<XRayRecord> Records;
+  using RecordVector = std::vector<XRayRecord>;
+  RecordVector Records;
 
   typedef std::vector<XRayRecord>::const_iterator citerator;
 
-  friend Expected<Trace> loadTraceFile(StringRef, bool);
+  friend Expected<Trace> loadTrace(const DataExtractor &, bool);
 
 public:
+  using size_type = RecordVector::size_type;
+  using value_type = RecordVector::value_type;
+  using const_iterator = RecordVector::const_iterator;
+
   /// Provides access to the loaded XRay trace file header.
   const XRayFileHeader &getFileHeader() const { return FileHeader; }
 
-  citerator begin() const { return Records.begin(); }
-  citerator end() const { return Records.end(); }
-  size_t size() const { return Records.size(); }
+  const_iterator begin() const { return Records.begin(); }
+  const_iterator end() const { return Records.end(); }
+  bool empty() const { return Records.empty(); }
+  size_type size() const { return Records.size(); }
 };
 
 /// This function will attempt to load XRay trace records from the provided
 /// |Filename|.
 Expected<Trace> loadTraceFile(StringRef Filename, bool Sort = false);
 
+/// This function will attempt to load XRay trace records from the provided
+/// DataExtractor.
+Expected<Trace> loadTrace(const DataExtractor &Extractor, bool Sort = false);
+
 } // namespace xray
 } // namespace llvm