Commit de72860de6

Andrew Kelley <andrew@ziglang.org>
2024-04-25 23:42:58
update ar and clang C++ files to LLVM 18
1 parent 3ac8d37
src/zig_clang_cc1_main.cpp
@@ -28,6 +28,7 @@
 #include "llvm/ADT/Statistic.h"
 #include "llvm/Config/llvm-config.h"
 #include "llvm/LinkAllPasses.h"
+#include "llvm/MC/MCSubtargetInfo.h"
 #include "llvm/MC/TargetRegistry.h"
 #include "llvm/Option/Arg.h"
 #include "llvm/Option/ArgList.h"
@@ -38,12 +39,15 @@
 #include "llvm/Support/ManagedStatic.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Process.h"
+#include "llvm/Support/RISCVISAInfo.h"
 #include "llvm/Support/Signals.h"
 #include "llvm/Support/TargetSelect.h"
 #include "llvm/Support/TimeProfiler.h"
 #include "llvm/Support/Timer.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Target/TargetMachine.h"
+#include "llvm/TargetParser/AArch64TargetParser.h"
+#include "llvm/TargetParser/ARMTargetParser.h"
 #include <cstdio>
 
 #ifdef CLANG_HAVE_RLIMITS
@@ -182,6 +186,43 @@ static int PrintSupportedCPUs(std::string TargetStr) {
   return 0;
 }
 
+static int PrintSupportedExtensions(std::string TargetStr) {
+  std::string Error;
+  const llvm::Target *TheTarget =
+      llvm::TargetRegistry::lookupTarget(TargetStr, Error);
+  if (!TheTarget) {
+    llvm::errs() << Error;
+    return 1;
+  }
+
+  llvm::TargetOptions Options;
+  std::unique_ptr<llvm::TargetMachine> TheTargetMachine(
+      TheTarget->createTargetMachine(TargetStr, "", "", Options, std::nullopt));
+  const llvm::Triple &MachineTriple = TheTargetMachine->getTargetTriple();
+  const llvm::MCSubtargetInfo *MCInfo = TheTargetMachine->getMCSubtargetInfo();
+  const llvm::ArrayRef<llvm::SubtargetFeatureKV> Features =
+    MCInfo->getAllProcessorFeatures();
+
+  llvm::StringMap<llvm::StringRef> DescMap;
+  for (const llvm::SubtargetFeatureKV &feature : Features)
+    DescMap.insert({feature.Key, feature.Desc});
+
+  if (MachineTriple.isRISCV())
+    llvm::riscvExtensionsHelp(DescMap);
+  else if (MachineTriple.isAArch64())
+    llvm::AArch64::PrintSupportedExtensions(DescMap);
+  else if (MachineTriple.isARM())
+    llvm::ARM::PrintSupportedExtensions(DescMap);
+  else {
+    // The option was already checked in Driver::HandleImmediateArgs,
+    // so we do not expect to get here if we are not a supported architecture.
+    assert(0 && "Unhandled triple for --print-supported-extensions option.");
+    return 1;
+  }
+
+  return 0;
+}
+
 int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
   ensureSufficientStack();
 
@@ -221,6 +262,10 @@ int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
   if (Clang->getFrontendOpts().PrintSupportedCPUs)
     return PrintSupportedCPUs(Clang->getTargetOpts().Triple);
 
+  // --print-supported-extensions takes priority over the actual compilation.
+  if (Clang->getFrontendOpts().PrintSupportedExtensions)
+    return PrintSupportedExtensions(Clang->getTargetOpts().Triple);
+
   // Infer the builtin include path if unspecified.
   if (Clang->getHeaderSearchOpts().UseBuiltinIncludes &&
       Clang->getHeaderSearchOpts().ResourceDir.empty())
src/zig_clang_cc1as_main.cpp
@@ -204,10 +204,10 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
   // Parse the arguments.
   const OptTable &OptTbl = getDriverOptTable();
 
-  const unsigned IncludedFlagsBitmask = options::CC1AsOption;
+  llvm::opt::Visibility VisibilityMask(options::CC1AsOption);
   unsigned MissingArgIndex, MissingArgCount;
-  InputArgList Args = OptTbl.ParseArgs(Argv, MissingArgIndex, MissingArgCount,
-                                       IncludedFlagsBitmask);
+  InputArgList Args =
+      OptTbl.ParseArgs(Argv, MissingArgIndex, MissingArgCount, VisibilityMask);
 
   // Check for missing argument error.
   if (MissingArgCount) {
@@ -220,7 +220,7 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
   for (const Arg *A : Args.filtered(OPT_UNKNOWN)) {
     auto ArgString = A->getAsString(Args);
     std::string Nearest;
-    if (OptTbl.findNearest(ArgString, Nearest, IncludedFlagsBitmask) > 1)
+    if (OptTbl.findNearest(ArgString, Nearest, VisibilityMask) > 1)
       Diags.Report(diag::err_drv_unknown_argument) << ArgString;
     else
       Diags.Report(diag::err_drv_unknown_argument_with_suggestion)
@@ -643,9 +643,10 @@ int cc1as_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
   if (Asm.ShowHelp) {
     getDriverOptTable().printHelp(
         llvm::outs(), "clang -cc1as [options] file...",
-        "Clang Integrated Assembler",
-        /*Include=*/driver::options::CC1AsOption, /*Exclude=*/0,
-        /*ShowAllAliases=*/false);
+        "Clang Integrated Assembler", /*ShowHidden=*/false,
+        /*ShowAllAliases=*/false,
+        llvm::opt::Visibility(driver::options::CC1AsOption));
+
     return 0;
   }
 
src/zig_clang_driver.cpp
@@ -36,7 +36,6 @@
 #include "llvm/Support/CrashRecoveryContext.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/FileSystem.h"
-#include "llvm/Support/InitLLVM.h"
 #include "llvm/Support/LLVMDriver.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/PrettyStackTrace.h"
@@ -65,7 +64,7 @@ std::string GetExecutablePath(const char *Argv0, bool CanonicalPrefixes) {
       if (llvm::ErrorOr<std::string> P =
               llvm::sys::findProgramByName(ExecutablePath))
         ExecutablePath = *P;
-    return std::string(ExecutablePath.str());
+    return std::string(ExecutablePath);
   }
 
   // This just needs to be some symbol in the binary; C++ doesn't
@@ -79,9 +78,9 @@ static const char *GetStableCStr(std::set<std::string> &SavedStrings,
   return SavedStrings.insert(std::string(S)).first->c_str();
 }
 
-/// ApplyQAOverride - Apply a list of edits to the input argument lists.
+/// ApplyOneQAOverride - Apply a list of edits to the input argument lists.
 ///
-/// The input string is a space separate list of edits to perform,
+/// The input string is a space separated list of edits to perform,
 /// they are applied in order to the input argument lists. Edits
 /// should be one of the following forms:
 ///
@@ -122,7 +121,7 @@ static void ApplyOneQAOverride(raw_ostream &OS,
       GetStableCStr(SavedStrings, Edit.substr(1));
     OS << "### Adding argument " << Str << " at end\n";
     Args.push_back(Str);
-  } else if (Edit[0] == 's' && Edit[1] == '/' && Edit.endswith("/") &&
+  } else if (Edit[0] == 's' && Edit[1] == '/' && Edit.ends_with("/") &&
              Edit.slice(2, Edit.size() - 1).contains('/')) {
     StringRef MatchPattern = Edit.substr(2).split('/').first;
     StringRef ReplPattern = Edit.substr(2).split('/').second;
@@ -177,7 +176,7 @@ static void ApplyOneQAOverride(raw_ostream &OS,
   }
 }
 
-/// ApplyQAOverride - Apply a comma separate list of edits to the
+/// ApplyQAOverride - Apply a space separated list of edits to the
 /// input argument lists. See ApplyOneQAOverride.
 static void ApplyQAOverride(SmallVectorImpl<const char*> &Args,
                             const char *OverrideStr,
@@ -210,6 +209,9 @@ extern int cc1_main(ArrayRef<const char *> Argv, const char *Argv0,
                     void *MainAddr);
 extern int cc1as_main(ArrayRef<const char *> Argv, const char *Argv0,
                       void *MainAddr);
+extern int cc1gen_reproducer_main(ArrayRef<const char *> Argv,
+                                  const char *Argv0, void *MainAddr,
+                                  const llvm::ToolContext &);
 
 static void insertTargetAndModeArgs(const ParsedClangName &NameParts,
                                     SmallVectorImpl<const char *> &ArgVector,
@@ -363,27 +365,21 @@ static int ExecuteCC1Tool(SmallVectorImpl<const char *> &ArgV,
     return cc1_main(ArrayRef(ArgV).slice(1), ArgV[0], GetExecutablePathVP);
   if (Tool == "-cc1as")
     return cc1as_main(ArrayRef(ArgV).slice(2), ArgV[0], GetExecutablePathVP);
+  if (Tool == "-cc1gen-reproducer")
+    return cc1gen_reproducer_main(ArrayRef(ArgV).slice(2), ArgV[0],
+                                  GetExecutablePathVP, ToolContext);
   // Reject unknown tools.
   llvm::errs() << "error: unknown integrated tool '" << Tool << "'. "
                << "Valid tools include '-cc1' and '-cc1as'.\n";
   return 1;
 }
 
-static int clang_main(int Argc, char **Argv, const llvm::ToolContext &ToolContext) {
+int clang_main(int Argc, char **Argv, const llvm::ToolContext &ToolContext) {
   noteBottomOfStack();
-  // ZIG PATCH: On Windows, InitLLVM calls GetCommandLineW(),
-  // and overwrites the args.  We don't want it to do that,
-  // and we also don't need the signal handlers it installs
-  // (we have our own already), so we just use llvm_shutdown_obj
-  // instead.
-  // llvm::InitLLVM X(Argc, Argv);
-  llvm::llvm_shutdown_obj X;
-
   llvm::setBugReportMsg("PLEASE submit a bug report to " BUG_REPORT_URL
                         " and include the crash backtrace, preprocessed "
                         "source, and associated run script.\n");
-  size_t argv_offset = (strcmp(Argv[1], "-cc1") == 0 || strcmp(Argv[1], "-cc1as") == 0) ? 0 : 1;
-  SmallVector<const char *, 256> Args(Argv + argv_offset, Argv + Argc);
+  SmallVector<const char *, 256> Args(Argv, Argv + Argc);
 
   if (llvm::sys::Process::FixupStandardFileDescriptors())
     return 1;
@@ -405,7 +401,7 @@ static int clang_main(int Argc, char **Argv, const llvm::ToolContext &ToolContex
   }
 
   // Handle -cc1 integrated tools.
-  if (Args.size() >= 2 && StringRef(Args[1]).startswith("-cc1"))
+  if (Args.size() >= 2 && StringRef(Args[1]).starts_with("-cc1"))
     return ExecuteCC1Tool(Args, ToolContext);
 
   // Handle options that need handling before the real command line parsing in
@@ -605,8 +601,3 @@ static int clang_main(int Argc, char **Argv, const llvm::ToolContext &ToolContex
   // failing command.
   return Res;
 }
-
-extern "C" int ZigClang_main(int, char **);
-int ZigClang_main(int argc, char **argv) {
-  return clang_main(argc, argv, {argv[0], nullptr, false});
-}
src/zig_llvm-ar.cpp
@@ -25,7 +25,6 @@
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Format.h"
 #include "llvm/Support/FormatVariadic.h"
-#include "llvm/Support/InitLLVM.h"
 #include "llvm/Support/LLVMDriver.h"
 #include "llvm/Support/LineIterator.h"
 #include "llvm/Support/MemoryBuffer.h"
@@ -69,7 +68,9 @@ static void printRanLibHelp(StringRef ToolName) {
          << "  -v --version          - Display the version of this program\n"
          << "  -D                    - Use zero for timestamps and uids/gids "
             "(default)\n"
-         << "  -U                    - Use actual timestamps and uids/gids\n";
+         << "  -U                    - Use actual timestamps and uids/gids\n"
+         << "  -X{32|64|32_64|any}   - Specify which archive symbol tables "
+            "should be generated if they do not already exist (AIX OS only)\n";
 }
 
 static void printArHelp(StringRef ToolName) {
@@ -225,7 +226,8 @@ static bool DisplayMemberOffsets = false; ///< 'O' modifier
 static bool CompareFullPath = false;      ///< 'P' modifier
 static bool OnlyUpdate = false;           ///< 'u' modifier
 static bool Verbose = false;              ///< 'v' modifier
-static bool Symtab = true;                ///< 's' modifier
+static SymtabWritingMode Symtab =
+    SymtabWritingMode::NormalSymtab;      ///< 's' modifier
 static bool Deterministic = true;         ///< 'D' and 'U' modifiers
 static bool Thin = false;                 ///< 'T' modifier
 static bool AddLibrary = false;           ///< 'L' modifier
@@ -371,11 +373,11 @@ static ArchiveOperation parseCommandLine() {
       CompareFullPath = true;
       break;
     case 's':
-      Symtab = true;
+      Symtab = SymtabWritingMode::NormalSymtab;
       MaybeJustCreateSymTab = true;
       break;
     case 'S':
-      Symtab = false;
+      Symtab = SymtabWritingMode::NoSymtab;
       break;
     case 'u':
       OnlyUpdate = true;
@@ -1074,9 +1076,31 @@ static void createSymbolTable(object::Archive *OldArchive) {
   // In summary, we only need to update the symbol table if we have none.
   // This is actually very common because of broken build systems that think
   // they have to run ranlib.
-  if (OldArchive->hasSymbolTable())
-    return;
+  if (OldArchive->hasSymbolTable()) {
+    if (OldArchive->kind() != object::Archive::K_AIXBIG)
+      return;
 
+    // For archives in the Big Archive format, the bit mode option specifies
+    // which symbol table to generate. The presence of a symbol table that does
+    // not match the specified bit mode does not prevent creation of the symbol
+    // table that has been requested.
+    if (OldArchive->kind() == object::Archive::K_AIXBIG) {
+      BigArchive *BigArc = dyn_cast<BigArchive>(OldArchive);
+      if (BigArc->has32BitGlobalSymtab() &&
+          Symtab == SymtabWritingMode::BigArchive32)
+        return;
+
+      if (BigArc->has64BitGlobalSymtab() &&
+          Symtab == SymtabWritingMode::BigArchive64)
+        return;
+
+      if (BigArc->has32BitGlobalSymtab() && BigArc->has64BitGlobalSymtab() &&
+          Symtab == SymtabWritingMode::NormalSymtab)
+        return;
+
+      Symtab = SymtabWritingMode::NormalSymtab;
+    }
+  }
   if (OldArchive->isThin())
     Thin = true;
   performWriteOperation(CreateSymTab, OldArchive, nullptr, nullptr);
@@ -1262,8 +1286,7 @@ static const char *matchFlagWithArg(StringRef Expected,
                                     ArrayRef<const char *> Args) {
   StringRef Arg = *ArgIt;
 
-  if (Arg.startswith("--"))
-    Arg = Arg.substr(2);
+  Arg.consume_front("--");
 
   size_t len = Expected.size();
   if (Arg == Expected) {
@@ -1272,7 +1295,7 @@ static const char *matchFlagWithArg(StringRef Expected,
 
     return *ArgIt;
   }
-  if (Arg.startswith(Expected) && Arg.size() > len && Arg[len] == '=')
+  if (Arg.starts_with(Expected) && Arg.size() > len && Arg[len] == '=')
     return Arg.data() + len + 1;
 
   return nullptr;
@@ -1389,6 +1412,8 @@ static int ar_main(int argc, char **argv) {
 
 static int ranlib_main(int argc, char **argv) {
   std::vector<StringRef> Archives;
+  bool HasAIXXOption = false;
+
   for (int i = 1; i < argc; ++i) {
     StringRef arg(argv[i]);
     if (handleGenericOption(arg)) {
@@ -1406,6 +1431,28 @@ static int ranlib_main(int argc, char **argv) {
         } else if (arg.front() == 'v') {
           cl::PrintVersionMessage();
           return 0;
+        } else if (arg.front() == 'X') {
+          if (object::Archive::getDefaultKindForHost() ==
+              object::Archive::K_AIXBIG) {
+            HasAIXXOption = true;
+            arg.consume_front("X");
+            const char *Xarg = arg.data();
+            if (Xarg[0] == '\0') {
+              if (argv[i + 1][0] != '-')
+                BitMode = getBitMode(argv[++i]);
+              else
+                BitMode = BitModeTy::Unknown;
+            } else
+              BitMode = getBitMode(arg.data());
+
+            if (BitMode == BitModeTy::Unknown)
+              fail("the specified object mode is not valid. Specify -X32, "
+                   "-X64, -X32_64, or -Xany");
+          } else {
+            fail(Twine("-") + Twine(arg) +
+                 " option not supported on non AIX OS");
+          }
+          break;
         } else {
           // TODO: GNU ranlib also supports a -t flag
           fail("Invalid option: '-" + arg + "'");
@@ -1417,6 +1464,31 @@ static int ranlib_main(int argc, char **argv) {
     }
   }
 
+  if (object::Archive::getDefaultKindForHost() == object::Archive::K_AIXBIG) {
+    // If not specify -X option, get BitMode from enviorment variable
+    // "OBJECT_MODE" for AIX OS if specify.
+    if (!HasAIXXOption) {
+      if (char *EnvObjectMode = getenv("OBJECT_MODE")) {
+        BitMode = getBitMode(EnvObjectMode);
+        if (BitMode == BitModeTy::Unknown)
+          fail("the OBJECT_MODE environment variable has an invalid value. "
+               "OBJECT_MODE must be 32, 64, 32_64, or any");
+      }
+    }
+
+    switch (BitMode) {
+    case BitModeTy::Bit32:
+      Symtab = SymtabWritingMode::BigArchive32;
+      break;
+    case BitModeTy::Bit64:
+      Symtab = SymtabWritingMode::BigArchive64;
+      break;
+    default:
+      Symtab = SymtabWritingMode::NormalSymtab;
+      break;
+    }
+  }
+
   for (StringRef Archive : Archives) {
     ArchiveName = Archive.str();
     performOperation(CreateSymTab);
@@ -1426,15 +1498,7 @@ static int ranlib_main(int argc, char **argv) {
   return 0;
 }
 
-static int llvm_ar_main(int argc, char **argv, const llvm::ToolContext &) {
-  // ZIG PATCH: On Windows, InitLLVM calls GetCommandLineW(),
-  // and overwrites the args.  We don't want it to do that,
-  // and we also don't need the signal handlers it installs
-  // (we have our own already), so we just use llvm_shutdown_obj
-  // instead.
-  // InitLLVM X(argc, argv);
-  llvm::llvm_shutdown_obj X;
-
+int llvm_ar_main(int argc, char **argv, const llvm::ToolContext &) {
   ToolName = argv[0];
 
   llvm::InitializeAllTargetInfos();
@@ -1464,8 +1528,3 @@ static int llvm_ar_main(int argc, char **argv, const llvm::ToolContext &) {
 
   fail("not ranlib, ar, lib or dlltool");
 }
-
-extern "C" int ZigLlvmAr_main(int, char **);
-int ZigLlvmAr_main(int argc, char **argv) {
-  return llvm_ar_main(argc, argv, {argv[0], nullptr, false});
-}