Importing rustc-1.70.0

Test: ./build.py --lto=thin
Change-Id: I34045ec5a79462afe9900f38a66f9783d4055a18
diff --git a/src/llvm-project/llvm/tools/llvm-dwarfutil/CMakeLists.txt b/src/llvm-project/llvm/tools/llvm-dwarfutil/CMakeLists.txt
index d932ff1..4210250 100644
--- a/src/llvm-project/llvm/tools/llvm-dwarfutil/CMakeLists.txt
+++ b/src/llvm-project/llvm/tools/llvm-dwarfutil/CMakeLists.txt
@@ -3,15 +3,16 @@
 add_public_tablegen_target(DwarfutilTableGen)
 
 set(LLVM_LINK_COMPONENTS
-  ${LLVM_TARGETS_TO_BUILD}
   DebugInfoDWARF
   DWARFLinker
+  DWARFLinkerParallel
   MC
   ObjCopy
   Object
   Option
   Support
   Target
+  TargetParser
   AllTargetsCodeGens
   AllTargetsDescs
   AllTargetsInfos
diff --git a/src/llvm-project/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp b/src/llvm-project/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp
index 3e70f46..ef222f8c 100644
--- a/src/llvm-project/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp
+++ b/src/llvm-project/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp
@@ -14,6 +14,7 @@
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
 #include "llvm/DebugInfo/DWARF/DWARFExpression.h"
 #include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/Endian.h"
 #include <memory>
 #include <vector>
 
@@ -40,7 +41,7 @@
 public:
   ObjFileAddressMap(DWARFContext &Context, const Options &Options,
                     object::ObjectFile &ObjFile)
-      : Opts(Options) {
+      : Opts(Options), Context(Context) {
     // Remember addresses of existing text sections.
     for (const object::SectionRef &Sect : ObjFile.sections()) {
       if (!Sect.isText())
@@ -75,7 +76,7 @@
             DIE.getTag() == dwarf::DW_TAG_label) &&
            "Wrong type of input die");
 
-    if (Optional<uint64_t> LowPC =
+    if (std::optional<uint64_t> LowPC =
             dwarf::toAddress(DIE.find(dwarf::DW_AT_low_pc))) {
       if (!isDeadAddress(*LowPC, DIE.getDwarfUnit()->getVersion(),
                          Opts.Tombstone,
@@ -137,17 +138,36 @@
 
   void clear() override { DWARFAddressRanges.clear(); }
 
-  llvm::Expected<uint64_t> relocateIndexedAddr(uint64_t, uint64_t) override {
-    // should not be called.
-    return object::createError("no relocations in linked binary");
+  llvm::Expected<uint64_t> relocateIndexedAddr(uint64_t StartOffset,
+                                               uint64_t EndOffset) override {
+    // No relocations in linked binary. Return just address value.
+
+    const char *AddrPtr =
+        Context.getDWARFObj().getAddrSection().Data.data() + StartOffset;
+    support::endianness Endianess =
+        Context.getDWARFObj().isLittleEndian() ? support::little : support::big;
+
+    assert(EndOffset > StartOffset);
+    switch (EndOffset - StartOffset) {
+    case 1:
+      return *AddrPtr;
+    case 2:
+      return support::endian::read16(AddrPtr, Endianess);
+    case 4:
+      return support::endian::read32(AddrPtr, Endianess);
+    case 8:
+      return support::endian::read64(AddrPtr, Endianess);
+    }
+
+    llvm_unreachable("relocateIndexedAddr unhandled case!");
   }
 
 protected:
   // returns true if specified address range is inside address ranges
   // of executable sections.
   bool isInsideExecutableSectionsAddressRange(uint64_t LowPC,
-                                              Optional<uint64_t> HighPC) {
-    Optional<AddressRange> Range =
+                                              std::optional<uint64_t> HighPC) {
+    std::optional<AddressRange> Range =
         TextAddressRanges.getRangeThatContains(LowPC);
 
     if (HighPC)
@@ -156,7 +176,7 @@
     return Range.has_value();
   }
 
-  uint64_t isBFDDeadAddressRange(uint64_t LowPC, Optional<uint64_t> HighPC,
+  uint64_t isBFDDeadAddressRange(uint64_t LowPC, std::optional<uint64_t> HighPC,
                                  uint16_t Version) {
     if (LowPC == 0)
       return true;
@@ -167,7 +187,8 @@
     return !isInsideExecutableSectionsAddressRange(LowPC, HighPC);
   }
 
-  uint64_t isMAXPCDeadAddressRange(uint64_t LowPC, Optional<uint64_t> HighPC,
+  uint64_t isMAXPCDeadAddressRange(uint64_t LowPC,
+                                   std::optional<uint64_t> HighPC,
                                    uint16_t Version, uint8_t AddressByteSize) {
     if (Version <= 4 && HighPC) {
       if (LowPC == (dwarf::computeTombstoneAddress(AddressByteSize) - 1))
@@ -182,7 +203,7 @@
     return false;
   }
 
-  bool isDeadAddressRange(uint64_t LowPC, Optional<uint64_t> HighPC,
+  bool isDeadAddressRange(uint64_t LowPC, std::optional<uint64_t> HighPC,
                           uint16_t Version, TombstoneKind Tombstone,
                           uint8_t AddressByteSize) {
     switch (Tombstone) {
@@ -202,13 +223,15 @@
 
   bool isDeadAddress(uint64_t LowPC, uint16_t Version, TombstoneKind Tombstone,
                      uint8_t AddressByteSize) {
-    return isDeadAddressRange(LowPC, None, Version, Tombstone, AddressByteSize);
+    return isDeadAddressRange(LowPC, std::nullopt, Version, Tombstone,
+                              AddressByteSize);
   }
 
 private:
   RangesTy DWARFAddressRanges;
   AddressRanges TextAddressRanges;
   const Options &Opts;
+  DWARFContext &Context;
 };
 
 static bool knownByDWARFUtil(StringRef SecName) {
@@ -229,9 +252,63 @@
       .Case(".debug_macinfo", true)
       .Case(".debug_str", true)
       .Case(".debug_str_offsets", true)
+      .Case(".debug_pubnames", true)
+      .Case(".debug_pubtypes", true)
+      .Case(".debug_names", true)
       .Default(false);
 }
 
+static std::optional<DwarfLinkerAccelTableKind>
+getAcceleratorTableKind(StringRef SecName) {
+  return llvm::StringSwitch<std::optional<DwarfLinkerAccelTableKind>>(SecName)
+      .Case(".debug_pubnames", DwarfLinkerAccelTableKind::Pub)
+      .Case(".debug_pubtypes", DwarfLinkerAccelTableKind::Pub)
+      .Case(".debug_names", DwarfLinkerAccelTableKind::DebugNames)
+      .Default(std::nullopt);
+}
+
+static std::string getMessageForReplacedAcceleratorTables(
+    SmallVector<StringRef> &AccelTableNamesToReplace,
+    DwarfUtilAccelKind TargetTable) {
+  std::string Message;
+
+  Message += "'";
+  for (StringRef Name : AccelTableNamesToReplace) {
+    if (Message.size() > 1)
+      Message += ", ";
+    Message += Name;
+  }
+
+  Message += "' will be replaced with requested ";
+
+  switch (TargetTable) {
+  case DwarfUtilAccelKind::DWARF:
+    Message += ".debug_names table";
+    break;
+
+  default:
+    assert(false);
+  }
+
+  return Message;
+}
+
+static std::string getMessageForDeletedAcceleratorTables(
+    SmallVector<StringRef> &AccelTableNamesToReplace) {
+  std::string Message;
+
+  Message += "'";
+  for (StringRef Name : AccelTableNamesToReplace) {
+    if (Message.size() > 1)
+      Message += ", ";
+    Message += Name;
+  }
+
+  Message += "' will be deleted as no accelerator tables are requested";
+
+  return Message;
+}
+
 Error linkDebugInfo(object::ObjectFile &File, const Options &Options,
                     raw_pwrite_stream &OutStream) {
 
@@ -263,11 +340,12 @@
                                           .str()))
     return createStringError(std::errc::invalid_argument, "");
 
+  std::unique_ptr<DWARFContext> Context = DWARFContext::create(File);
+
   // Create DWARF linker.
   DWARFLinker DebugInfoLinker(&OutStreamer, DwarfLinkerClient::LLD);
 
   DebugInfoLinker.setEstimatedObjfilesAmount(1);
-  DebugInfoLinker.setAccelTableKind(DwarfLinkerAccelTableKind::None);
   DebugInfoLinker.setErrorHandler(ReportErr);
   DebugInfoLinker.setWarningHandler(ReportWarn);
   DebugInfoLinker.setNumThreads(Options.NumThreads);
@@ -279,18 +357,6 @@
   std::vector<std::unique_ptr<AddressesMap>> AddresssMapForLinking(1);
   std::vector<std::string> EmptyWarnings;
 
-  std::unique_ptr<DWARFContext> Context = DWARFContext::create(File);
-
-  // Unknown debug sections would be removed. Display warning
-  // for such sections.
-  for (SectionName Sec : Context->getDWARFObj().getSectionNames()) {
-    if (isDebugSection(Sec.Name) && !knownByDWARFUtil(Sec.Name))
-      warning(
-          formatv("'{0}' is not currently supported: section will be skipped",
-                  Sec.Name),
-          Options.InputFileName);
-  }
-
   // Add object files to the DWARFLinker.
   AddresssMapForLinking[0] =
       std::make_unique<ObjFileAddressMap>(*Context, Options, File);
@@ -299,8 +365,77 @@
       File.getFileName(), &*Context, AddresssMapForLinking[0].get(),
       EmptyWarnings);
 
+  uint16_t MaxDWARFVersion = 0;
+  std::function<void(const DWARFUnit &Unit)> OnCUDieLoaded =
+      [&MaxDWARFVersion](const DWARFUnit &Unit) {
+        MaxDWARFVersion = std::max(Unit.getVersion(), MaxDWARFVersion);
+      };
+
   for (size_t I = 0; I < ObjectsForLinking.size(); I++)
-    DebugInfoLinker.addObjectFile(*ObjectsForLinking[I]);
+    DebugInfoLinker.addObjectFile(*ObjectsForLinking[I], nullptr,
+                                  OnCUDieLoaded);
+
+  // If we haven't seen any CUs, pick an arbitrary valid Dwarf version anyway.
+  if (MaxDWARFVersion == 0)
+    MaxDWARFVersion = 3;
+
+  if (Error Err = DebugInfoLinker.setTargetDWARFVersion(MaxDWARFVersion))
+    return Err;
+
+  SmallVector<DwarfLinkerAccelTableKind> AccelTables;
+
+  switch (Options.AccelTableKind) {
+  case DwarfUtilAccelKind::None:
+    // Nothing to do.
+    break;
+  case DwarfUtilAccelKind::DWARF:
+    // use .debug_names for all DWARF versions.
+    AccelTables.push_back(DwarfLinkerAccelTableKind::DebugNames);
+    break;
+  }
+
+  // Add accelerator tables to DWARFLinker.
+  for (DwarfLinkerAccelTableKind Table : AccelTables)
+    DebugInfoLinker.addAccelTableKind(Table);
+
+  SmallVector<StringRef> AccelTableNamesToReplace;
+  SmallVector<StringRef> AccelTableNamesToDelete;
+
+  // Unknown debug sections or non-requested accelerator sections would be
+  // removed. Display warning for such sections.
+  for (SectionName Sec : Context->getDWARFObj().getSectionNames()) {
+    if (isDebugSection(Sec.Name)) {
+      std::optional<DwarfLinkerAccelTableKind> SrcAccelTableKind =
+          getAcceleratorTableKind(Sec.Name);
+
+      if (SrcAccelTableKind) {
+        assert(knownByDWARFUtil(Sec.Name));
+
+        if (Options.AccelTableKind == DwarfUtilAccelKind::None)
+          AccelTableNamesToDelete.push_back(Sec.Name);
+        else if (std::find(AccelTables.begin(), AccelTables.end(),
+                           *SrcAccelTableKind) == AccelTables.end())
+          AccelTableNamesToReplace.push_back(Sec.Name);
+      } else if (!knownByDWARFUtil(Sec.Name)) {
+        assert(!SrcAccelTableKind);
+        warning(
+            formatv("'{0}' is not currently supported: section will be skipped",
+                    Sec.Name),
+            Options.InputFileName);
+      }
+    }
+  }
+
+  // Display message for the replaced accelerator tables.
+  if (!AccelTableNamesToReplace.empty())
+    warning(getMessageForReplacedAcceleratorTables(AccelTableNamesToReplace,
+                                                   Options.AccelTableKind),
+            Options.InputFileName);
+
+  // Display message for the removed accelerator tables.
+  if (!AccelTableNamesToDelete.empty())
+    warning(getMessageForDeletedAcceleratorTables(AccelTableNamesToDelete),
+            Options.InputFileName);
 
   // Link debug info.
   if (Error Err = DebugInfoLinker.link())
diff --git a/src/llvm-project/llvm/tools/llvm-dwarfutil/Options.h b/src/llvm-project/llvm/tools/llvm-dwarfutil/Options.h
index c993200..38fa2b9 100644
--- a/src/llvm-project/llvm/tools/llvm-dwarfutil/Options.h
+++ b/src/llvm-project/llvm/tools/llvm-dwarfutil/Options.h
@@ -24,6 +24,12 @@
   Exec,      /// match with address range of executable sections.
 };
 
+/// The kind of accelerator table.
+enum class DwarfUtilAccelKind : uint8_t {
+  None,
+  DWARF // DWARFv5: .debug_names
+};
+
 struct Options {
   std::string InputFileName;
   std::string OutputFileName;
@@ -34,6 +40,7 @@
   bool Verbose = false;
   int NumThreads = 0;
   bool Verify = false;
+  DwarfUtilAccelKind AccelTableKind = DwarfUtilAccelKind::None;
 
   std::string getSeparateDebugFileName() const {
     return OutputFileName + ".debug";
diff --git a/src/llvm-project/llvm/tools/llvm-dwarfutil/Options.td b/src/llvm-project/llvm/tools/llvm-dwarfutil/Options.td
index 4ab1b51..d454118 100644
--- a/src/llvm-project/llvm/tools/llvm-dwarfutil/Options.td
+++ b/src/llvm-project/llvm/tools/llvm-dwarfutil/Options.td
@@ -5,6 +5,14 @@
   def no_ # NAME: Flag<["--"], "no-" # name>, HelpText<help2>;
 }
 
+def build_accelerator: Separate<["--", "-"], "build-accelerator">,
+  MetaVarName<"[none,DWARF]">,
+  HelpText<"Build accelerator tables(default: none)\n"
+  "    =none - Do not build accelerators\n"
+  "    =DWARF - .debug_names are generated for all DWARF versions\n"
+  >;
+def: Joined<["--", "-"], "build-accelerator=">, Alias<build_accelerator>;
+
 def help : Flag<["--"], "help">,
   HelpText<"Prints this help output">;
 
diff --git a/src/llvm-project/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp b/src/llvm-project/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp
index a6466be..74b6104 100644
--- a/src/llvm-project/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp
+++ b/src/llvm-project/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp
@@ -40,11 +40,14 @@
 #undef OPTION
 };
 
-#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
+#define PREFIX(NAME, VALUE)                                                    \
+  static constexpr StringLiteral NAME##_init[] = VALUE;                        \
+  static constexpr ArrayRef<StringLiteral> NAME(NAME##_init,                   \
+                                                std::size(NAME##_init) - 1);
 #include "Options.inc"
 #undef PREFIX
 
-const opt::OptTable::Info InfoTable[] = {
+static constexpr opt::OptTable::Info InfoTable[] = {
 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \
                HELPTEXT, METAVAR, VALUES)                                      \
   {                                                                            \
@@ -56,9 +59,9 @@
 #undef OPTION
 };
 
-class DwarfutilOptTable : public opt::OptTable {
+class DwarfutilOptTable : public opt::GenericOptTable {
 public:
-  DwarfutilOptTable() : OptTable(InfoTable) {}
+  DwarfutilOptTable() : opt::GenericOptTable(InfoTable) {}
 };
 } // namespace
 
@@ -120,6 +123,19 @@
           formatv("unknown tombstone value: '{0}'", S).str().c_str());
   }
 
+  if (opt::Arg *BuildAccelerator = Args.getLastArg(OPT_build_accelerator)) {
+    StringRef S = BuildAccelerator->getValue();
+
+    if (S == "none")
+      Options.AccelTableKind = DwarfUtilAccelKind::None;
+    else if (S == "DWARF")
+      Options.AccelTableKind = DwarfUtilAccelKind::DWARF;
+    else
+      return createStringError(
+          std::errc::invalid_argument,
+          formatv("unknown build-accelerator value: '{0}'", S).str().c_str());
+  }
+
   if (Options.Verbose) {
     if (Options.NumThreads != 1 && Args.hasArg(OPT_threads))
       warning("--num-threads set to 1 because verbose mode is specified");
@@ -420,8 +436,9 @@
 }
 
 static Error applyCLOptions(const struct Options &Opts, ObjectFile &InputFile) {
-  if (Opts.DoGarbageCollection) {
-    verbose("Do garbage collection for debug info ...", Opts.Verbose);
+  if (Opts.DoGarbageCollection ||
+      Opts.AccelTableKind != DwarfUtilAccelKind::None) {
+    verbose("Do debug info linking...", Opts.Verbose);
 
     DebugInfoBits LinkedDebugInfo;
     raw_svector_ostream OutStream(LinkedDebugInfo);
@@ -458,7 +475,7 @@
   DwarfutilOptTable T;
   unsigned MAI;
   unsigned MAC;
-  ArrayRef<const char *> ArgsArr = makeArrayRef(Argv + 1, Argc - 1);
+  ArrayRef<const char *> ArgsArr = ArrayRef(Argv + 1, Argc - 1);
   opt::InputArgList Args = T.ParseArgs(ArgsArr, MAI, MAC);
 
   if (Args.hasArg(OPT_help) || Args.size() == 0) {
@@ -481,7 +498,6 @@
   InitializeAllTargetMCs();
   InitializeAllTargetInfos();
   InitializeAllAsmPrinters();
-  InitializeAllAsmParsers();
 
   ErrorOr<std::unique_ptr<MemoryBuffer>> BuffOrErr =
       MemoryBuffer::getFileOrSTDIN(Opts.InputFileName);