https://github.com/dzbarsky updated 
https://github.com/llvm/llvm-project/pull/201743

>From 06b1358960b03044e84b2f3133124846d1b67d03 Mon Sep 17 00:00:00 2001
From: David Zbarsky <[email protected]>
Date: Thu, 4 Jun 2026 23:38:43 -0400
Subject: [PATCH] Port clang-tidy to Opts.td and multicall

---
 .../clang-tidy/tool/CMakeLists.txt            |   8 +
 .../clang-tidy/tool/ClangTidyMain.cpp         | 622 +++++++++---------
 .../clang-tidy/tool/ClangTidyMain.h           |   2 +-
 .../clang-tidy/tool/ClangTidyToolMain.cpp     |   3 +-
 clang-tools-extra/clang-tidy/tool/Opts.td     | 245 +++++++
 clang-tools-extra/docs/clang-tidy/index.rst   | 331 +++++-----
 .../infrastructure/invalid-command-line.cpp   |   3 +-
 .../clang-tools-extra/clang-tidy/BUILD.bazel  |  22 +-
 .../llvm-project-overlay/llvm/driver.bzl      |   1 +
 9 files changed, 738 insertions(+), 499 deletions(-)
 create mode 100644 clang-tools-extra/clang-tidy/tool/Opts.td

diff --git a/clang-tools-extra/clang-tidy/tool/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/tool/CMakeLists.txt
index 0d4501d1eac06..da007f49c934a 100644
--- a/clang-tools-extra/clang-tidy/tool/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/tool/CMakeLists.txt
@@ -3,10 +3,15 @@ set(LLVM_LINK_COMPONENTS
   AllTargetsDescs
   AllTargetsInfos
   FrontendOpenMP
+  Option
   TargetParser
   support
   )
 
+set(LLVM_TARGET_DEFINITIONS Opts.td)
+tablegen(LLVM Opts.inc -gen-opt-parser-defs)
+add_public_tablegen_target(ClangTidyOptsTableGen)
+
 # Needed by LLVM's CMake checks because this file defines multiple targets.
 set(LLVM_OPTIONAL_SOURCES ClangTidyMain.cpp ClangTidyToolMain.cpp)
 
@@ -20,6 +25,7 @@ add_clang_library(clangTidyMain STATIC
   DEPENDS
   omp_gen
   ClangDriverOptions
+  ClangTidyOptsTableGen
   )
 
 clang_target_link_libraries(clangTidyMain
@@ -42,6 +48,8 @@ add_clang_tool(clang-tidy
   DEPENDS
   clang-resource-headers
   ${support_plugins}
+
+  GENERATE_DRIVER
   )
 clang_target_link_libraries(clang-tidy
   PRIVATE
diff --git a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp 
b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
index 949a88f0fd50d..89ae0f497abeb 100644
--- a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
+++ b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
@@ -18,13 +18,22 @@
 #include "../ClangTidy.h"
 #include "../ClangTidyForceLinker.h" // IWYU pragma: keep
 #include "../GlobList.h"
+#include "clang/Basic/Version.h"
 #include "clang/Tooling/CommonOptionsParser.h"
+#include "clang/Tooling/CompilationDatabase.h"
+#include "clang/Tooling/Tooling.h"
 #include "llvm/ADT/StringSet.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Option/Arg.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Option/Option.h"
+#include "llvm/Support/Allocator.h"
 #include "llvm/Support/CommandLine.h"
-#include "llvm/Support/InitLLVM.h"
+#define DONT_GET_PLUGIN_LOADER_OPTION
 #include "llvm/Support/PluginLoader.h" // IWYU pragma: keep
 #include "llvm/Support/Process.h"
 #include "llvm/Support/Signals.h"
+#include "llvm/Support/StringSaver.h"
 #include "llvm/Support/TargetSelect.h"
 #include "llvm/Support/WithColor.h"
 #include "llvm/TargetParser/Host.h"
@@ -33,17 +42,62 @@
 using namespace clang::tooling;
 using namespace llvm;
 
-static cl::desc desc(StringRef Description) { return {Description.ltrim()}; }
-
-static cl::OptionCategory ClangTidyCategory("clang-tidy options");
-
-static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
-static cl::extrahelp ClangTidyParameterFileHelp(R"(
+namespace {
+using namespace llvm::opt;
+
+enum ID {
+  OPT_INVALID = 0,
+#define OPTION(...) LLVM_MAKE_OPT_ID(__VA_ARGS__),
+#include "Opts.inc"
+#undef OPTION
+};
+
+#define OPTTABLE_STR_TABLE_CODE
+#include "Opts.inc"
+#undef OPTTABLE_STR_TABLE_CODE
+
+#define OPTTABLE_PREFIXES_TABLE_CODE
+#include "Opts.inc"
+#undef OPTTABLE_PREFIXES_TABLE_CODE
+
+static constexpr opt::OptTable::Info InfoTable[] = {
+#define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__),
+#include "Opts.inc"
+#undef OPTION
+};
+
+class ClangTidyOptTable : public opt::GenericOptTable {
+public:
+  ClangTidyOptTable()
+      : opt::GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) {}
+};
+
+static constexpr llvm::StringLiteral CommonHelp = R"(
+-p <build-path> is used to read a compile command database.
+
+  For example, it can be a CMake build directory in which a file named
+  compile_commands.json exists (use -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
+  CMake option to get this output). When no build path is specified,
+  a search for compile_commands.json will be attempted through all
+  parent paths of the first input file. See:
+  https://clang.llvm.org/docs/HowToSetupToolingForLLVM.html for an
+  example of setting up Clang Tooling on a source tree.
+
+<source0> ... specify the paths of source files. These paths are
+  looked up in the compile command database. If the path of a file is
+  absolute, it needs to point into CMake's source tree. If the path is
+  relative, the current working directory needs to be in the CMake
+  source tree and the file must be in a subdirectory of the current
+  working directory. "./" prefixes in the relative files will be
+  automatically removed, but the rest of a relative path must be a
+  suffix of a path in the compile command database.
+)";
+static constexpr llvm::StringLiteral ClangTidyParameterFileHelp = R"(
 Parameters files:
   A large number of options or source files can be passed as parameter files
   by use '@parameter-file' in the command line.
-)");
-static cl::extrahelp ClangTidyHelp(R"(
+)";
+static constexpr llvm::StringLiteral ClangTidyHelp = R"(
 Configuration files:
   clang-tidy attempts to read configuration for each source file from a
   .clang-tidy file located in the closest parent directory of the source
@@ -102,270 +156,221 @@ Configuration files:
       some-check.SomeOption: 'some value'
     ...
 
-)");
+)";
 
 const char DefaultChecks[] = // Enable these checks by default:
     "clang-diagnostic-*";    //   * compiler diagnostics
 
-static cl::opt<std::string> Checks("checks", desc(R"(
-Comma-separated list of globs with optional '-'
-prefix. Globs are processed in order of
-appearance in the list. Globs without '-'
-prefix add checks with matching names to the
-set, globs with the '-' prefix remove checks
-with matching names from the set of enabled
-checks. This option's value is appended to the
-value of the 'Checks' option in .clang-tidy
-file, if any.
-)"),
-                                   cl::init(""), cl::cat(ClangTidyCategory));
-
-static cl::opt<std::string> WarningsAsErrors("warnings-as-errors", desc(R"(
-Upgrades warnings to errors. Same format as
-'-checks'.
-This option's value is appended to the value of
-the 'WarningsAsErrors' option in .clang-tidy
-file, if any.
-)"),
-                                             cl::init(""),
-                                             cl::cat(ClangTidyCategory));
-
-static cl::opt<std::string> HeaderFilter("header-filter", desc(R"(
-Regular expression matching the names of the
-headers to output diagnostics from. The default
-value is '.*', i.e. diagnostics from all non-system
-headers are displayed by default. Diagnostics
-from the main file of each translation unit are
-always displayed.
-Can be used together with -line-filter.
-This option overrides the 'HeaderFilterRegex'
-option in .clang-tidy file, if any.
-)"),
-                                         cl::init(".*"),
-                                         cl::cat(ClangTidyCategory));
-
-static cl::opt<std::string> ExcludeHeaderFilter("exclude-header-filter",
-                                                desc(R"(
-Regular expression matching the names of the
-headers to exclude diagnostics from. Diagnostics
-from the main file of each translation unit are
-always displayed.
-Must be used together with --header-filter.
-Can be used together with -line-filter.
-This option overrides the 'ExcludeHeaderFilterRegex'
-option in .clang-tidy file, if any.
-)"),
-                                                cl::init(""),
-                                                cl::cat(ClangTidyCategory));
-
-static cl::opt<bool> SystemHeaders("system-headers", desc(R"(
-Display the errors from system headers.
-This option overrides the 'SystemHeaders' option
-in .clang-tidy file, if any.
-)"),
-                                   cl::init(false), 
cl::cat(ClangTidyCategory));
-
-static cl::opt<std::string> LineFilter("line-filter", desc(R"(
-List of files and line ranges to output diagnostics from.
-The range is inclusive on both ends. Can be used together
-with -header-filter. The format of the list is a JSON
-array of objects. For example:
-
-  [
-    {"name":"file1.cpp","lines":[[1,3],[5,7]]},
-    {"name":"file2.h"}
-  ]
-
-This will output diagnostics from 'file1.cpp' only for
-the line ranges [1,3] and [5,7], as well as all from the
-entire 'file2.h'.
-)"),
-                                       cl::init(""),
-                                       cl::cat(ClangTidyCategory));
-
-static cl::opt<bool> Fix("fix", desc(R"(
-Apply suggested fixes. Without -fix-errors
-clang-tidy will bail out if any compilation
-errors were found.
-)"),
-                         cl::init(false), cl::cat(ClangTidyCategory));
-
-static cl::opt<bool> FixErrors("fix-errors", desc(R"(
-Apply suggested fixes even if compilation
-errors were found. If compiler errors have
-attached fix-its, clang-tidy will apply them as
-well.
-)"),
-                               cl::init(false), cl::cat(ClangTidyCategory));
-
-static cl::opt<bool> FixNotes("fix-notes", desc(R"(
-If a warning has no fix, but a single fix can
-be found through an associated diagnostic note,
-apply the fix.
-Specifying this flag will implicitly enable the
-'--fix' flag.
-)"),
-                              cl::init(false), cl::cat(ClangTidyCategory));
-
-static cl::opt<std::string> FormatStyle("format-style", desc(R"(
-Style for formatting code around applied fixes:
-  - 'none' (default) turns off formatting
-  - 'file' (literally 'file', not a placeholder)
-    uses .clang-format file in the closest parent
-    directory
-  - '{ <json> }' specifies options inline, e.g.
-    -format-style='{BasedOnStyle: llvm, IndentWidth: 8}'
-  - 'llvm', 'google', 'webkit', 'mozilla'
-See clang-format documentation for the up-to-date
-information about formatting styles and options.
-This option overrides the 'FormatStyle` option in
-.clang-tidy file, if any.
-)"),
-                                        cl::init("none"),
-                                        cl::cat(ClangTidyCategory));
-
-static cl::opt<bool> ListChecks("list-checks", desc(R"(
-List all enabled checks and exit. Use with
--checks=* to list all available checks.
-)"),
-                                cl::init(false), cl::cat(ClangTidyCategory));
-
-static cl::opt<bool> ExplainConfig("explain-config", desc(R"(
-For each enabled check explains, where it is
-enabled, i.e. in clang-tidy binary, command
-line or a specific configuration file.
-)"),
-                                   cl::init(false), 
cl::cat(ClangTidyCategory));
-
-static cl::opt<std::string> Config("config", desc(R"(
-Specifies a configuration in YAML/JSON format:
-  -config="{Checks: '*',
-            CheckOptions: {x: y}}"
-When the value is empty, clang-tidy will
-attempt to find a file named .clang-tidy for
-each source file in its parent directories.
-)"),
-                                   cl::init(""), cl::cat(ClangTidyCategory));
-
-static cl::opt<std::string> ConfigFile("config-file", desc(R"(
-Specify the path of .clang-tidy or custom config file:
- e.g. --config-file=/some/path/myTidyConfigFile
-This option internally works exactly the same way as
- --config option after reading specified config file.
-Use either --config-file or --config, not both.
-)"),
-                                       cl::init(""),
-                                       cl::cat(ClangTidyCategory));
-
-static cl::opt<bool> DumpConfig("dump-config", desc(R"(
-Dumps configuration in the YAML format to
-stdout. This option can be used along with a
-file name (and '--' if the file is outside of a
-project with configured compilation database).
-The configuration used for this file will be
-printed.
-Use along with -checks=* to include
-configuration of all checks.
-)"),
-                                cl::init(false), cl::cat(ClangTidyCategory));
-
-static cl::opt<bool> EnableCheckProfile("enable-check-profile", desc(R"(
-Enable per-check timing profiles, and print a
-report to stderr.
-)"),
-                                        cl::init(false),
-                                        cl::cat(ClangTidyCategory));
-
-static cl::opt<std::string> StoreCheckProfile("store-check-profile", desc(R"(
-By default reports are printed in tabulated
-format to stderr. When this option is passed,
-these per-TU profiles are instead stored as JSON.
-)"),
-                                              cl::value_desc("prefix"),
-                                              cl::cat(ClangTidyCategory));
-
-/// This option allows enabling the experimental alpha checkers from the static
-/// analyzer. This option is set to false and not visible in help, because it 
is
-/// highly not recommended for users.
-static cl::opt<bool>
-    
AllowEnablingAnalyzerAlphaCheckers("allow-enabling-analyzer-alpha-checkers",
-                                       cl::init(false), cl::Hidden,
-                                       cl::cat(ClangTidyCategory));
-
-static cl::opt<bool> 
EnableModuleHeadersParsing("enable-module-headers-parsing",
-                                                desc(R"(
-Enables preprocessor-level module header parsing
-for C++20 and above, empowering specific checks
-to detect macro definitions within modules. This
-feature may cause performance and parsing issues
-and is therefore considered experimental.
-)"),
-                                                cl::init(false),
-                                                cl::cat(ClangTidyCategory));
-
-static cl::opt<std::string> ExportFixes("export-fixes", desc(R"(
-YAML file to store suggested fixes in. The
-stored fixes can be applied to the input source
-code with clang-apply-replacements.
-)"),
-                                        cl::value_desc("filename"),
-                                        cl::cat(ClangTidyCategory));
-
-static cl::opt<bool> Quiet("quiet", desc(R"(
-Run clang-tidy in quiet mode. This suppresses
-printing statistics about ignored warnings and
-warnings treated as errors if the respective
-options are specified.
-)"),
-                           cl::init(false), cl::cat(ClangTidyCategory));
-
-static cl::opt<std::string> VfsOverlay("vfsoverlay", desc(R"(
-Overlay the virtual filesystem described by file
-over the real file system.
-)"),
-                                       cl::value_desc("filename"),
-                                       cl::cat(ClangTidyCategory));
-
-static cl::opt<bool> UseColor("use-color", desc(R"(
-Use colors in diagnostics. If not set, colors
-will be used if the terminal connected to
-standard output supports colors.
-This option overrides the 'UseColor' option in
-.clang-tidy file, if any.
-)"),
-                              cl::init(false), cl::cat(ClangTidyCategory));
-
-static cl::opt<bool> VerifyConfig("verify-config", desc(R"(
-Check the config files to ensure each check and
-option is recognized without running any checks.
-)"),
-                                  cl::init(false), cl::cat(ClangTidyCategory));
-
-static cl::opt<bool> AllowNoChecks("allow-no-checks", desc(R"(
-Allow empty enabled checks. This suppresses
-the "no checks enabled" error when disabling
-all of the checks.
-)"),
-                                   cl::init(false), 
cl::cat(ClangTidyCategory));
-
-static cl::opt<bool> ExperimentalCustomChecks("experimental-custom-checks",
-                                              desc(R"(
-Enable experimental clang-query based
-custom checks.
-see https://clang.llvm.org/extra/clang-tidy/QueryBasedCustomChecks.html.
-)"),
-                                              cl::init(false),
-                                              cl::cat(ClangTidyCategory));
-
-static cl::list<std::string> RemovedArgs("removed-arg", desc(R"(
-List of arguments to remove from the command
-line sent to the compiler. Please note that
-removing arguments might change the semantic
-of the analyzed code, possibly leading to
-compiler errors, false positives or
-false negatives. This option is applied 
-before --extra-arg and --extra-arg-before)"),
-                                         cl::cat(ClangTidyCategory));
+static std::string Checks;
+static bool ChecksSpecified;
+static std::string WarningsAsErrors;
+static bool WarningsAsErrorsSpecified;
+static std::string HeaderFilter;
+static bool HeaderFilterSpecified;
+static std::string ExcludeHeaderFilter;
+static bool ExcludeHeaderFilterSpecified;
+static bool SystemHeaders;
+static bool SystemHeadersSpecified;
+static std::string LineFilter;
+static bool Fix;
+static bool FixErrors;
+static bool FixNotes;
+static std::string FormatStyle;
+static bool FormatStyleSpecified;
+static bool ListChecks;
+static bool ExplainConfig;
+static std::string Config;
+static bool ConfigSpecified;
+static std::string ConfigFile;
+static bool ConfigFileSpecified;
+static bool DumpConfig;
+static bool EnableCheckProfile;
+static std::string StoreCheckProfile;
+static bool AllowEnablingAnalyzerAlphaCheckers;
+static bool EnableModuleHeadersParsing;
+static std::string ExportFixes;
+static bool Quiet;
+static std::string VfsOverlay;
+static bool UseColor;
+static bool UseColorSpecified;
+static bool VerifyConfig;
+static bool AllowNoChecks;
+static bool ExperimentalCustomChecks;
+static std::vector<std::string> RemovedArgs;
+static bool RemovedArgsSpecified;
+
+static void printHelp(bool ShowHidden = false) {
+  ClangTidyOptTable Tbl;
+  Tbl.printHelp(outs(),
+                "clang-tidy [options] <source0> [... <sourceN>] "
+                "[-- <compiler arguments>]",
+                "clang-tidy", ShowHidden);
+  outs() << CommonHelp << ClangTidyParameterFileHelp << ClangTidyHelp;
+}
+
+static bool parseBoolArg(const opt::Arg *A, unsigned ValueID, bool &Value) {
+  if (!A->getOption().matches(ValueID)) {
+    Value = true;
+    return true;
+  }
+  std::optional<bool> Parsed = StringSwitch<std::optional<bool>>(A->getValue())
+                                   .CaseLower("true", true)
+                                   .Case("1", true)
+                                   .CaseLower("false", false)
+                                   .Case("0", false)
+                                   .Default(std::nullopt);
+  if (Parsed) {
+    Value = *Parsed;
+    return true;
+  }
+  errs() << "clang-tidy: invalid value '" << A->getValue() << "' for option '"
+         << A->getSpelling() << "'\n";
+  return false;
+}
+
+static bool parseBoolArg(const opt::InputArgList &Args, unsigned FlagID,
+                         unsigned ValueID, bool &Value,
+                         bool *Specified = nullptr) {
+  const opt::Arg *A = Args.getLastArg(FlagID, ValueID);
+  if (Specified)
+    *Specified = A != nullptr;
+  Value = false;
+  return !A || parseBoolArg(A, ValueID, Value);
+}
+
+static bool parseCommandLine(int argc, char **argv, BumpPtrAllocator 
&Allocator,
+                             StringSaver &Saver, ClangTidyOptTable &Tbl,
+                             opt::InputArgList &Args,
+                             std::unique_ptr<CompilationDatabase> 
&Compilations,
+                             std::vector<std::string> &SourcePaths) {
+  SmallVector<const char *> ExpandedArgs(argv, argv + argc);
+  cl::TokenizerCallback Tokenizer =
+      Triple(sys::getProcessTriple()).isOSWindows()
+          ? cl::TokenizeWindowsCommandLine
+          : cl::TokenizeGNUCommandLine;
+  cl::ExpansionContext ECtx(Allocator, Tokenizer);
+  if (Error Err = ECtx.expandResponseFiles(ExpandedArgs)) {
+    WithColor::error() << toString(std::move(Err)) << "\n";
+    return false;
+  }
+
+  int ToolArgc = static_cast<int>(ExpandedArgs.size());
+  std::string FixedDatabaseError;
+  Compilations = FixedCompilationDatabase::loadFromCommandLine(
+      ToolArgc, ExpandedArgs.data(), FixedDatabaseError);
+
+  SmallVector<char *> ToolArgv;
+  ToolArgv.reserve(ToolArgc);
+  for (const char *Arg : ArrayRef(ExpandedArgs).take_front(ToolArgc))
+    ToolArgv.push_back(const_cast<char *>(Arg));
+
+  bool HasError = false;
+  Args = Tbl.parseArgs(ToolArgc, ToolArgv.data(), OPT_UNKNOWN, Saver,
+                       [&](StringRef Message) {
+                         errs() << "clang-tidy: " << Message << '\n';
+                         HasError = true;
+                       });
+  if (HasError) {
+    if (!FixedDatabaseError.empty())
+      errs() << FixedDatabaseError;
+    return false;
+  }
+
+  Checks = Args.getLastArgValue(OPT_checks_EQ);
+  ChecksSpecified = Args.hasArg(OPT_checks_EQ);
+  WarningsAsErrors = Args.getLastArgValue(OPT_warnings_as_errors_EQ);
+  WarningsAsErrorsSpecified = Args.hasArg(OPT_warnings_as_errors_EQ);
+  HeaderFilter = Args.getLastArgValue(OPT_header_filter_EQ, ".*");
+  HeaderFilterSpecified = Args.hasArg(OPT_header_filter_EQ);
+  ExcludeHeaderFilter = Args.getLastArgValue(OPT_exclude_header_filter_EQ);
+  ExcludeHeaderFilterSpecified = Args.hasArg(OPT_exclude_header_filter_EQ);
+  LineFilter = Args.getLastArgValue(OPT_line_filter_EQ);
+  FormatStyle = Args.getLastArgValue(OPT_format_style_EQ, "none");
+  FormatStyleSpecified = Args.hasArg(OPT_format_style_EQ);
+  Config = Args.getLastArgValue(OPT_config_EQ);
+  ConfigSpecified = Args.hasArg(OPT_config_EQ);
+  ConfigFile = Args.getLastArgValue(OPT_config_file_EQ);
+  ConfigFileSpecified = Args.hasArg(OPT_config_file_EQ);
+  StoreCheckProfile = Args.getLastArgValue(OPT_store_check_profile_EQ);
+  ExportFixes = Args.getLastArgValue(OPT_export_fixes_EQ);
+  VfsOverlay = Args.getLastArgValue(OPT_vfsoverlay_EQ);
+  RemovedArgs = Args.getAllArgValues(OPT_removed_arg_EQ);
+  RemovedArgsSpecified = Args.hasArg(OPT_removed_arg_EQ);
+  SourcePaths = Args.getAllArgValues(OPT_INPUT);
+
+  if (!parseBoolArg(Args, OPT_system_headers, OPT_system_headers_EQ,
+                    SystemHeaders, &SystemHeadersSpecified) ||
+      !parseBoolArg(Args, OPT_fix, OPT_fix_EQ, Fix) ||
+      !parseBoolArg(Args, OPT_fix_errors, OPT_fix_errors_EQ, FixErrors) ||
+      !parseBoolArg(Args, OPT_fix_notes, OPT_fix_notes_EQ, FixNotes) ||
+      !parseBoolArg(Args, OPT_list_checks, OPT_list_checks_EQ, ListChecks) ||
+      !parseBoolArg(Args, OPT_explain_config, OPT_explain_config_EQ,
+                    ExplainConfig) ||
+      !parseBoolArg(Args, OPT_dump_config, OPT_dump_config_EQ, DumpConfig) ||
+      !parseBoolArg(Args, OPT_enable_check_profile, 
OPT_enable_check_profile_EQ,
+                    EnableCheckProfile) ||
+      !parseBoolArg(Args, OPT_allow_enabling_analyzer_alpha_checkers,
+                    OPT_allow_enabling_analyzer_alpha_checkers_EQ,
+                    AllowEnablingAnalyzerAlphaCheckers) ||
+      !parseBoolArg(Args, OPT_enable_module_headers_parsing,
+                    OPT_enable_module_headers_parsing_EQ,
+                    EnableModuleHeadersParsing) ||
+      !parseBoolArg(Args, OPT_quiet, OPT_quiet_EQ, Quiet) ||
+      !parseBoolArg(Args, OPT_use_color, OPT_use_color_EQ, UseColor,
+                    &UseColorSpecified) ||
+      !parseBoolArg(Args, OPT_verify_config, OPT_verify_config_EQ,
+                    VerifyConfig) ||
+      !parseBoolArg(Args, OPT_allow_no_checks, OPT_allow_no_checks_EQ,
+                    AllowNoChecks) ||
+      !parseBoolArg(Args, OPT_experimental_custom_checks,
+                    OPT_experimental_custom_checks_EQ,
+                    ExperimentalCustomChecks))
+    return false;
+
+  for (StringRef Plugin : Args.getAllArgValues(OPT_load_EQ)) {
+    PluginLoader Loader;
+    Loader = Plugin.str();
+  }
+
+  if (SourcePaths.empty()) {
+    if (!Compilations)
+      Compilations = std::make_unique<FixedCompilationDatabase>(
+          ".", std::vector<std::string>());
+    return true;
+  }
+
+  if (!Compilations) {
+    std::string ErrorMessage;
+    StringRef BuildPath = Args.getLastArgValue(OPT_p);
+    if (!BuildPath.empty())
+      Compilations =
+          CompilationDatabase::autoDetectFromDirectory(BuildPath, 
ErrorMessage);
+    else
+      Compilations = CompilationDatabase::autoDetectFromSource(
+          SourcePaths.front(), ErrorMessage);
+    if (!Compilations) {
+      errs() << "Error while trying to load a compilation database:\n"
+             << ErrorMessage << "Running without flags.\n";
+      Compilations = std::make_unique<FixedCompilationDatabase>(
+          ".", std::vector<std::string>());
+    }
+  }
+
+  auto AdjustingCompilations =
+      
std::make_unique<ArgumentsAdjustingCompilations>(std::move(Compilations));
+  ArgumentsAdjuster Adjuster =
+      getInsertArgumentAdjuster(Args.getAllArgValues(OPT_extra_arg_before_EQ),
+                                ArgumentInsertPosition::BEGIN);
+  Adjuster = combineAdjusters(
+      std::move(Adjuster),
+      getInsertArgumentAdjuster(Args.getAllArgValues(OPT_extra_arg_EQ),
+                                ArgumentInsertPosition::END));
+  AdjustingCompilations->appendArgumentsAdjuster(std::move(Adjuster));
+  Compilations = std::move(AdjustingCompilations);
+  return true;
+}
+
+} // namespace
 
 namespace clang::tidy {
 
@@ -402,7 +407,7 @@ 
createOptionsProvider(llvm::IntrusiveRefCntPtr<vfs::FileSystem> FS) {
   ClangTidyGlobalOptions GlobalOptions;
   if (const std::error_code Err = parseLineFilter(LineFilter, GlobalOptions)) {
     llvm::errs() << "Invalid LineFilter: " << Err.message() << "\n\nUsage:\n";
-    llvm::cl::PrintHelpMessage(/*Hidden=*/false, /*Categorized=*/true);
+    printHelp();
     return nullptr;
   }
 
@@ -419,21 +424,21 @@ 
createOptionsProvider(llvm::IntrusiveRefCntPtr<vfs::FileSystem> FS) {
     DefaultOptions.User = llvm::sys::Process::GetEnv("USERNAME");
 
   ClangTidyOptions OverrideOptions;
-  if (Checks.getNumOccurrences() > 0)
+  if (ChecksSpecified)
     OverrideOptions.Checks = Checks;
-  if (WarningsAsErrors.getNumOccurrences() > 0)
+  if (WarningsAsErrorsSpecified)
     OverrideOptions.WarningsAsErrors = WarningsAsErrors;
-  if (HeaderFilter.getNumOccurrences() > 0)
+  if (HeaderFilterSpecified)
     OverrideOptions.HeaderFilterRegex = HeaderFilter;
-  if (ExcludeHeaderFilter.getNumOccurrences() > 0)
+  if (ExcludeHeaderFilterSpecified)
     OverrideOptions.ExcludeHeaderFilterRegex = ExcludeHeaderFilter;
-  if (SystemHeaders.getNumOccurrences() > 0)
+  if (SystemHeadersSpecified)
     OverrideOptions.SystemHeaders = SystemHeaders;
-  if (FormatStyle.getNumOccurrences() > 0)
+  if (FormatStyleSpecified)
     OverrideOptions.FormatStyle = FormatStyle;
-  if (UseColor.getNumOccurrences() > 0)
+  if (UseColorSpecified)
     OverrideOptions.UseColor = UseColor;
-  if (RemovedArgs.getNumOccurrences() > 0)
+  if (RemovedArgsSpecified)
     OverrideOptions.RemovedArgs = RemovedArgs;
 
   auto LoadConfig =
@@ -451,8 +456,8 @@ 
createOptionsProvider(llvm::IntrusiveRefCntPtr<vfs::FileSystem> FS) {
     return nullptr;
   };
 
-  if (ConfigFile.getNumOccurrences() > 0) {
-    if (Config.getNumOccurrences() > 0) {
+  if (ConfigFileSpecified) {
+    if (ConfigSpecified) {
       llvm::errs() << "Error: --config-file and --config are "
                       "mutually exclusive. Specify only one.\n";
       return nullptr;
@@ -469,7 +474,7 @@ 
createOptionsProvider(llvm::IntrusiveRefCntPtr<vfs::FileSystem> FS) {
     return LoadConfig((*Text)->getBuffer(), ConfigFile);
   }
 
-  if (Config.getNumOccurrences() > 0)
+  if (ConfigSpecified)
     return LoadConfig(Config, "<command-line-config>");
 
   return std::make_unique<FileOptionsProvider>(
@@ -511,7 +516,8 @@ static StringRef closest(StringRef Value, const StringSet<> 
&Allowed) {
   return Closest;
 }
 
-static constexpr StringLiteral VerifyConfigWarningEnd = " [-verify-config]\n";
+static constexpr llvm::StringLiteral VerifyConfigWarningEnd =
+    " [-verify-config]\n";
 
 static bool verifyChecks(const StringSet<> &AllChecks, StringRef CheckGlob,
                          StringRef Source) {
@@ -604,34 +610,25 @@ static llvm::IntrusiveRefCntPtr<vfs::OverlayFileSystem> 
createBaseFS() {
   return BaseFS;
 }
 
-int clangTidyMain(int argc, const char **argv) {
-  const llvm::InitLLVM X(argc, argv);
-  SmallVector<const char *> Args{argv, argv + argc};
-
-  // expand parameters file to argc and argv.
-  llvm::BumpPtrAllocator Alloc;
-  llvm::cl::TokenizerCallback Tokenizer =
-      llvm::Triple(llvm::sys::getProcessTriple()).isOSWindows()
-          ? llvm::cl::TokenizeWindowsCommandLine
-          : llvm::cl::TokenizeGNUCommandLine;
-  llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
-  if (llvm::Error Err = ECtx.expandResponseFiles(Args)) {
-    llvm::WithColor::error() << llvm::toString(std::move(Err)) << "\n";
+int clangTidyMain(int argc, char **argv) {
+  BumpPtrAllocator Alloc;
+  StringSaver Saver(Alloc);
+  ClangTidyOptTable Tbl;
+  opt::InputArgList Args;
+  std::unique_ptr<CompilationDatabase> Compilations;
+  std::vector<std::string> PathList;
+  if (!parseCommandLine(argc, argv, Alloc, Saver, Tbl, Args, Compilations,
+                        PathList))
     return 1;
+
+  if (Args.hasArg(OPT_help, OPT_help_hidden)) {
+    printHelp(Args.hasArg(OPT_help_hidden));
+    return 0;
   }
-  argc = static_cast<int>(Args.size());
-  argv = Args.data();
-
-  // Enable help for -load option, if plugins are enabled.
-  if (cl::Option *LoadOpt = cl::getRegisteredOptions().lookup("load"))
-    LoadOpt->addCategory(ClangTidyCategory);
-
-  llvm::Expected<CommonOptionsParser> OptionsParser =
-      CommonOptionsParser::create(argc, argv, ClangTidyCategory,
-                                  cl::ZeroOrMore);
-  if (!OptionsParser) {
-    llvm::WithColor::error() << llvm::toString(OptionsParser.takeError());
-    return 1;
+
+  if (Args.hasArg(OPT_version)) {
+    outs() << clang::getClangToolFullVersion("clang-tidy") << '\n';
+    return 0;
   }
 
   const llvm::IntrusiveRefCntPtr<vfs::OverlayFileSystem> BaseFS =
@@ -647,7 +644,6 @@ int clangTidyMain(int argc, const char **argv) {
   const SmallString<256> ProfilePrefix = makeAbsolute(StoreCheckProfile);
 
   StringRef FileName("dummy");
-  auto PathList = OptionsParser->getSourcePathList();
   if (!PathList.empty())
     FileName = PathList.front();
 
@@ -720,13 +716,13 @@ int clangTidyMain(int argc, const char **argv) {
 
   if (EnabledChecks.empty() && !AllowNoChecks) {
     llvm::errs() << "Error: no checks enabled.\n";
-    llvm::cl::PrintHelpMessage(/*Hidden=*/false, /*Categorized=*/true);
+    printHelp();
     return 1;
   }
 
   if (PathList.empty()) {
     llvm::errs() << "Error: no input files specified.\n";
-    llvm::cl::PrintHelpMessage(/*Hidden=*/false, /*Categorized=*/true);
+    printHelp();
     return 1;
   }
 
@@ -738,8 +734,8 @@ int clangTidyMain(int argc, const char **argv) {
       std::move(OwningOptionsProvider), AllowEnablingAnalyzerAlphaCheckers,
       EnableModuleHeadersParsing, ExperimentalCustomChecks);
   std::vector<ClangTidyError> Errors =
-      runClangTidy(Context, OptionsParser->getCompilations(), PathList, BaseFS,
-                   FixNotes, EnableCheckProfile, ProfilePrefix, Quiet);
+      runClangTidy(Context, *Compilations, PathList, BaseFS, FixNotes,
+                   EnableCheckProfile, ProfilePrefix, Quiet);
   const bool FoundErrors = llvm::any_of(Errors, [](const ClangTidyError &E) {
     return E.DiagLevel == ClangTidyError::Error;
   });
diff --git a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.h 
b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.h
index 44b7a379e5277..1ea728ed29571 100644
--- a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.h
+++ b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.h
@@ -19,7 +19,7 @@
 
 namespace clang::tidy {
 
-int clangTidyMain(int argc, const char **argv);
+int clangTidyMain(int argc, char **argv);
 
 } // namespace clang::tidy
 
diff --git a/clang-tools-extra/clang-tidy/tool/ClangTidyToolMain.cpp 
b/clang-tools-extra/clang-tidy/tool/ClangTidyToolMain.cpp
index a2ba638ea15e8..086bfb6af32c5 100644
--- a/clang-tools-extra/clang-tidy/tool/ClangTidyToolMain.cpp
+++ b/clang-tools-extra/clang-tidy/tool/ClangTidyToolMain.cpp
@@ -15,7 +15,8 @@
 
//===----------------------------------------------------------------------===//
 
 #include "ClangTidyMain.h"
+#include "llvm/Support/LLVMDriver.h"
 
-int main(int argc, const char **argv) {
+int clang_tidy_main(int argc, char **argv, const llvm::ToolContext &) {
   return clang::tidy::clangTidyMain(argc, argv);
 }
diff --git a/clang-tools-extra/clang-tidy/tool/Opts.td 
b/clang-tools-extra/clang-tidy/tool/Opts.td
new file mode 100644
index 0000000000000..6610d5fe5cd97
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/tool/Opts.td
@@ -0,0 +1,245 @@
+include "llvm/Option/OptParser.td"
+
+def clang_tidy_group : OptionGroup<"clang-tidy">,
+                       HelpText<"clang-tidy options">;
+def generic_group : OptionGroup<"generic">, HelpText<"Generic Options">;
+
+class F<string name, string help>
+    : Flag<["--", "-"], name>, HelpText<help>, Group<clang_tidy_group>;
+
+multiclass B<string name, string help> {
+  def NAME : F<name, help>;
+  def NAME #_EQ : Joined<["--", "-"], name #"=">,
+                   MetaVarName<"<true|false>">,
+                   Group<clang_tidy_group>, Flags<[HelpHidden]>;
+}
+
+multiclass BH<string name> {
+  def NAME : Flag<["--", "-"], name>, Group<clang_tidy_group>,
+             Flags<[HelpHidden]>;
+  def NAME #_EQ : Joined<["--", "-"], name #"=">,
+                   MetaVarName<"<true|false>">,
+                   Group<clang_tidy_group>, Flags<[HelpHidden]>;
+}
+
+multiclass Eq<string name, string metavar, string help> {
+  def NAME #_EQ : Joined<["--", "-"], name #"=">,
+                  HelpText<help>, MetaVarName<metavar>,
+                  Group<clang_tidy_group>;
+  def : Separate<["--", "-"], name>, Alias<!cast<Joined>(NAME #_EQ)>;
+}
+
+class GF<string name, string help>
+    : Flag<["--", "-"], name>, HelpText<help>, Group<generic_group>;
+
+def help : GF<"help", "Display available options (--help-hidden for more)">;
+def help_hidden : GF<"help-hidden",
+                     "Display all available options, including hidden 
options">,
+                  Flags<[HelpHidden]>;
+def help_list
+    : GF<"help-list",
+         "Display list of available options (--help-list-hidden for more)">,
+      Alias<help>;
+def help_list_hidden
+    : GF<"help-list-hidden", "Display list of all available options">,
+      Alias<help_hidden>, Flags<[HelpHidden]>;
+def version : GF<"version", "Display the version of this program">;
+def h : GF<"h", "Alias for --help">, Alias<help>, Flags<[HelpHidden]>;
+
+defm checks : Eq<"checks", "<string>",
+                 "Comma-separated list of globs with optional '-'\n"
+                 "prefix. Globs are processed in order of\n"
+                 "appearance in the list. Globs without '-'\n"
+                 "prefix add checks with matching names to the\n"
+                 "set, globs with the '-' prefix remove checks\n"
+                 "with matching names from the set of enabled\n"
+                 "checks. This option's value is appended to the\n"
+                 "value of the 'Checks' option in .clang-tidy\n"
+                 "file, if any.">;
+defm warnings_as_errors
+    : Eq<"warnings-as-errors", "<string>",
+         "Upgrades warnings to errors. Same format as\n"
+         "'-checks'.\n"
+         "This option's value is appended to the value of\n"
+         "the 'WarningsAsErrors' option in .clang-tidy\n"
+         "file, if any.">;
+defm header_filter
+    : Eq<"header-filter", "<string>",
+         "Regular expression matching the names of the\n"
+         "headers to output diagnostics from. The default\n"
+         "value is '.*', i.e. diagnostics from all non-system\n"
+         "headers are displayed by default. Diagnostics\n"
+         "from the main file of each translation unit are\n"
+         "always displayed.\n"
+         "Can be used together with -line-filter.\n"
+         "This option overrides the 'HeaderFilterRegex'\n"
+         "option in .clang-tidy file, if any.">;
+defm exclude_header_filter
+    : Eq<"exclude-header-filter", "<string>",
+         "Regular expression matching the names of the\n"
+         "headers to exclude diagnostics from. Diagnostics\n"
+         "from the main file of each translation unit are\n"
+         "always displayed.\n"
+         "Must be used together with --header-filter.\n"
+         "Can be used together with -line-filter.\n"
+         "This option overrides the 'ExcludeHeaderFilterRegex'\n"
+         "option in .clang-tidy file, if any.">;
+defm system_headers
+    : B<"system-headers",
+        "Display the errors from system headers.\n"
+        "This option overrides the 'SystemHeaders' option\n"
+        "in .clang-tidy file, if any.">;
+defm line_filter
+    : Eq<"line-filter", "<string>",
+         "List of files and line ranges to output diagnostics from.\n"
+         "The range is inclusive on both ends. Can be used together\n"
+         "with -header-filter. The format of the list is a JSON\n"
+         "array of objects. For example:\n"
+         "  [\n"
+         "    {\"name\":\"file1.cpp\",\"lines\":[[1,3],[5,7]]},\n"
+         "    {\"name\":\"file2.h\"}\n"
+         "  ]\n"
+         "This will output diagnostics from 'file1.cpp' only for\n"
+         "the line ranges [1,3] and [5,7], as well as all from the\n"
+         "entire 'file2.h'.">;
+defm fix
+    : B<"fix", "Apply suggested fixes. Without -fix-errors\n"
+               "clang-tidy will bail out if any compilation\n"
+               "errors were found.">;
+defm fix_errors
+    : B<"fix-errors",
+        "Apply suggested fixes even if compilation\n"
+        "errors were found. If compiler errors have\n"
+        "attached fix-its, clang-tidy will apply them as\n"
+        "well.">;
+defm fix_notes
+    : B<"fix-notes",
+        "If a warning has no fix, but a single fix can\n"
+        "be found through an associated diagnostic note,\n"
+        "apply the fix.\n"
+        "Specifying this flag will implicitly enable the\n"
+        "'--fix' flag.">;
+defm format_style
+    : Eq<"format-style", "<string>",
+         "Style for formatting code around applied fixes:\n"
+         "  - 'none' (default) turns off formatting\n"
+         "  - 'file' (literally 'file', not a placeholder)\n"
+         "    uses .clang-format file in the closest parent\n"
+         "    directory\n"
+         "  - '{ <json> }' specifies options inline, e.g.\n"
+         "    -format-style='{BasedOnStyle: llvm, IndentWidth: 8}'\n"
+         "  - 'llvm', 'google', 'webkit', 'mozilla'\n"
+         "See clang-format documentation for the up-to-date\n"
+         "information about formatting styles and options.\n"
+         "This option overrides the 'FormatStyle` option in\n"
+         ".clang-tidy file, if any.">;
+defm list_checks
+    : B<"list-checks",
+        "List all enabled checks and exit. Use with\n"
+        "-checks=* to list all available checks.">;
+defm explain_config
+    : B<"explain-config",
+        "For each enabled check explains, where it is\n"
+        "enabled, i.e. in clang-tidy binary, command\n"
+        "line or a specific configuration file.">;
+defm config
+    : Eq<"config", "<string>",
+         "Specifies a configuration in YAML/JSON format:\n"
+         "  -config=\"{Checks: '*',\n"
+         "            CheckOptions: {x: y}}\"\n"
+         "When the value is empty, clang-tidy will\n"
+         "attempt to find a file named .clang-tidy for\n"
+         "each source file in its parent directories.">;
+defm config_file
+    : Eq<"config-file", "<filename>",
+         "Specify the path of .clang-tidy or custom config file:\n"
+         " e.g. --config-file=/some/path/myTidyConfigFile\n"
+         "This option internally works exactly the same way as\n"
+         " --config option after reading specified config file.\n"
+         "Use either --config-file or --config, not both.">;
+defm dump_config
+    : B<"dump-config",
+        "Dumps configuration in the YAML format to\n"
+         "stdout. This option can be used along with a\n"
+         "file name (and '--' if the file is outside of a\n"
+         "project with configured compilation database).\n"
+         "The configuration used for this file will be\n"
+         "printed.\n"
+         "Use along with -checks=* to include\n"
+         "configuration of all checks.">;
+defm enable_check_profile
+    : B<"enable-check-profile",
+        "Enable per-check timing profiles, and print a\n"
+        "report to stderr.">;
+defm store_check_profile
+    : Eq<"store-check-profile", "<prefix>",
+         "By default reports are printed in tabulated\n"
+         "format to stderr. When this option is passed,\n"
+         "these per-TU profiles are instead stored as JSON.">;
+defm allow_enabling_analyzer_alpha_checkers
+    : BH<"allow-enabling-analyzer-alpha-checkers">;
+defm enable_module_headers_parsing
+    : B<"enable-module-headers-parsing",
+        "Enables preprocessor-level module header parsing\n"
+        "for C++20 and above, empowering specific checks\n"
+        "to detect macro definitions within modules. This\n"
+        "feature may cause performance and parsing issues\n"
+        "and is therefore considered experimental.">;
+defm export_fixes
+    : Eq<"export-fixes", "<filename>",
+         "YAML file to store suggested fixes in. The\n"
+         "stored fixes can be applied to the input source\n"
+         "code with clang-apply-replacements.">;
+defm quiet
+    : B<"quiet",
+        "Run clang-tidy in quiet mode. This suppresses\n"
+        "printing statistics about ignored warnings and\n"
+        "warnings treated as errors if the respective\n"
+        "options are specified.">;
+defm vfsoverlay
+    : Eq<"vfsoverlay", "<filename>",
+         "Overlay the virtual filesystem described by file\n"
+         "over the real file system.">;
+defm use_color
+    : B<"use-color",
+        "Use colors in diagnostics. If not set, colors\n"
+        "will be used if the terminal connected to\n"
+        "standard output supports colors.\n"
+        "This option overrides the 'UseColor' option in\n"
+        ".clang-tidy file, if any.">;
+defm verify_config
+    : B<"verify-config",
+        "Check the config files to ensure each check and\n"
+        "option is recognized without running any checks.">;
+defm allow_no_checks
+    : B<"allow-no-checks",
+        "Allow empty enabled checks. This suppresses\n"
+        "the \"no checks enabled\" error when disabling\n"
+        "all of the checks.">;
+defm experimental_custom_checks
+    : B<"experimental-custom-checks",
+        "Enable experimental clang-query based\n"
+        "custom checks.\n"
+        "see https://clang.llvm.org/extra/clang-tidy/";
+        "QueryBasedCustomChecks.html.">;
+defm removed_arg
+    : Eq<"removed-arg", "<arg>",
+         "List of arguments to remove from the command\n"
+         "line sent to the compiler. Please note that\n"
+         "removing arguments might change the semantic\n"
+         "of the analyzed code, possibly leading to\n"
+         "compiler errors, false positives or\n"
+         "false negatives. This option is applied\n"
+         "before --extra-arg and --extra-arg-before">;
+
+defm extra_arg
+    : Eq<"extra-arg", "<arg>",
+         "Additional argument to append to the compiler command line">;
+defm extra_arg_before
+    : Eq<"extra-arg-before", "<arg>",
+         "Additional argument to prepend to the compiler command line">;
+def p : Separate<["-", "--"], "p">, HelpText<"Build path">,
+        MetaVarName<"<build-path>">, Group<clang_tidy_group>;
+def p_EQ : Joined<["-", "--"], "p=">, Alias<p>, Flags<[HelpHidden]>;
+defm load
+    : Eq<"load", "<pluginfilename>", "Load the specified plugin">;
diff --git a/clang-tools-extra/docs/clang-tidy/index.rst 
b/clang-tools-extra/docs/clang-tidy/index.rst
index 908dee6c18a7f..8b61e6fcd56ad 100644
--- a/clang-tools-extra/docs/clang-tidy/index.rst
+++ b/clang-tools-extra/docs/clang-tidy/index.rst
@@ -80,6 +80,7 @@ Name prefix            Description
 ``darwin-``            Checks related to Darwin coding conventions.
 ``fuchsia-``           Checks related to Fuchsia coding conventions.
 ``google-``            Checks related to Google coding conventions.
+``hicpp-``             Checks related to High Integrity C++ Coding Standard.
 ``linuxkernel-``       Checks related to the Linux Kernel coding conventions.
 ``llvm-``              Checks related to the LLVM coding conventions.
 ``llvmlibc-``          Checks related to the LLVM-libc coding standards.
@@ -126,156 +127,161 @@ An overview of all the command-line options:
 .. code-block:: console
 
   $ clang-tidy --help
-  USAGE: clang-tidy [options] <source0> [... <sourceN>]
+  OVERVIEW: clang-tidy
 
-  OPTIONS:
+  USAGE: clang-tidy [options] <source0> [... <sourceN>] [-- <compiler 
arguments>]
 
   Generic Options:
-
-    --help                           - Display available options 
(--help-hidden for more)
-    --help-list                      - Display list of available options 
(--help-list-hidden for more)
-    --version                        - Display the version of this program
+    --help-list Display list of available options (--help-list-hidden for more)
+    --help      Display available options (--help-hidden for more)
+    --version   Display the version of this program
 
   clang-tidy options:
-
-    --allow-no-checks                - Allow empty enabled checks. This 
suppresses
-                                       the "no checks enabled" error when 
disabling
-                                       all of the checks.
-    --checks=<string>                - Comma-separated list of globs with 
optional '-'
-                                       prefix. Globs are processed in order of
-                                       appearance in the list. Globs without 
'-'
-                                       prefix add checks with matching names 
to the
-                                       set, globs with the '-' prefix remove 
checks
-                                       with matching names from the set of 
enabled
-                                       checks. This option's value is appended 
to the
-                                       value of the 'Checks' option in 
.clang-tidy
-                                       file, if any.
-    --config=<string>                - Specifies a configuration in YAML/JSON 
format:
-                                         -config="{Checks: '*',
-                                                   CheckOptions: {x: y}}"
-                                       When the value is empty, clang-tidy will
-                                       attempt to find a file named 
.clang-tidy for
-                                       each source file in its parent 
directories.
-    --config-file=<string>           - Specify the path of .clang-tidy or 
custom config file:
-                                        e.g. 
--config-file=/some/path/myTidyConfigFile
-                                       This option internally works exactly 
the same way as
-                                        --config option after reading 
specified config file.
-                                       Use either --config-file or --config, 
not both.
-    --dump-config                    - Dumps configuration in the YAML format 
to
-                                       stdout. This option can be used along 
with a
-                                       file name (and '--' if the file is 
outside of a
-                                       project with configured compilation 
database).
-                                       The configuration used for this file 
will be
-                                       printed.
-                                       Use along with -checks=* to include
-                                       configuration of all checks.
-    --enable-check-profile           - Enable per-check timing profiles, and 
print a
-                                       report to stderr.
-    --enable-module-headers-parsing  - Enables preprocessor-level module 
header parsing
-                                       for C++20 and above, empowering 
specific checks
-                                       to detect macro definitions within 
modules. This
-                                       feature may cause performance and 
parsing issues
-                                       and is therefore considered 
experimental.
-    --exclude-header-filter=<string> - Regular expression matching the names 
of the
-                                       headers to exclude diagnostics from. 
Diagnostics
-                                       from the main file of each translation 
unit are
-                                       always displayed.
-                                       Must be used together with 
--header-filter.
-                                       Can be used together with -line-filter.
-                                       This option overrides the 
'ExcludeHeaderFilterRegex'
-                                       option in .clang-tidy file, if any.
-    --experimental-custom-checks     - Enable experimental clang-query based
-                                       custom checks.
-                                       see 
https://clang.llvm.org/extra/clang-tidy/QueryBasedCustomChecks.html.
-    --explain-config                 - For each enabled check explains, where 
it is
-                                       enabled, i.e. in clang-tidy binary, 
command
-                                       line or a specific configuration file.
-    --export-fixes=<filename>        - YAML file to store suggested fixes in. 
The
-                                       stored fixes can be applied to the 
input source
-                                       code with clang-apply-replacements.
-    --extra-arg=<string>             - Additional argument to append to the 
compiler command line
-    --extra-arg-before=<string>      - Additional argument to prepend to the 
compiler command line
-    --fix                            - Apply suggested fixes. Without 
-fix-errors
-                                       clang-tidy will bail out if any 
compilation
-                                       errors were found.
-    --fix-errors                     - Apply suggested fixes even if 
compilation
-                                       errors were found. If compiler errors 
have
-                                       attached fix-its, clang-tidy will apply 
them as
-                                       well.
-    --fix-notes                      - If a warning has no fix, but a single 
fix can
-                                       be found through an associated 
diagnostic note,
-                                       apply the fix.
-                                       Specifying this flag will implicitly 
enable the
-                                       '--fix' flag.
-    --format-style=<string>          - Style for formatting code around 
applied fixes:
-                                         - 'none' (default) turns off 
formatting
-                                         - 'file' (literally 'file', not a 
placeholder)
-                                           uses .clang-format file in the 
closest parent
-                                           directory
-                                         - '{ <json> }' specifies options 
inline, e.g.
-                                           -format-style='{BasedOnStyle: llvm, 
IndentWidth: 8}'
-                                         - 'llvm', 'google', 'webkit', 
'mozilla'
-                                       See clang-format documentation for the 
up-to-date
-                                       information about formatting styles and 
options.
-                                       This option overrides the 'FormatStyle` 
option in
-                                       .clang-tidy file, if any.
-    --header-filter=<string>         - Regular expression matching the names 
of the
-                                       headers to output diagnostics from. The 
default
-                                       value is '.*', i.e. diagnostics from 
all non-system
-                                       headers are displayed by default. 
Diagnostics
-                                       from the main file of each translation 
unit are
-                                       always displayed.
-                                       Can be used together with -line-filter.
-                                       This option overrides the 
'HeaderFilterRegex'
-                                       option in .clang-tidy file, if any.
-    --line-filter=<string>           - List of files and line ranges to output 
diagnostics from.
-                                       The range is inclusive on both ends. 
Can be used together
-                                       with -header-filter. The format of the 
list is a JSON
-                                       array of objects. For example:
-
-                                         [
-                                           
{"name":"file1.cpp","lines":[[1,3],[5,7]]},
-                                           {"name":"file2.h"}
-                                         ]
-
-                                       This will output diagnostics from 
'file1.cpp' only for
-                                       the line ranges [1,3] and [5,7], as 
well as all from the
-                                       entire 'file2.h'.
-    --list-checks                    - List all enabled checks and exit. Use 
with
-                                       -checks=* to list all available checks.
-    --load=<pluginfilename>          - Load the specified plugin
-    -p <string>                      - Build path
-    --quiet                          - Run clang-tidy in quiet mode. This 
suppresses
-                                       printing statistics about ignored 
warnings and
-                                       warnings treated as errors if the 
respective
-                                       options are specified.
-    --removed-arg=<string>           - List of arguments to remove from the 
command
-                                       line sent to the compiler. Please note 
that
-                                       removing arguments might change the 
semantic
-                                       of the analyzed code, possibly leading 
to
-                                       compiler errors, false positives or
-                                       false negatives. This option is applied
-                                       before --extra-arg and 
--extra-arg-before
-    --store-check-profile=<prefix>   - By default reports are printed in 
tabulated
-                                       format to stderr. When this option is 
passed,
-                                       these per-TU profiles are instead 
stored as JSON.
-    --system-headers                 - Display the errors from system headers.
-                                       This option overrides the 
'SystemHeaders' option
-                                       in .clang-tidy file, if any.
-    --use-color                      - Use colors in diagnostics. If not set, 
colors
-                                       will be used if the terminal connected 
to
-                                       standard output supports colors.
-                                       This option overrides the 'UseColor' 
option in
-                                       .clang-tidy file, if any.
-    --verify-config                  - Check the config files to ensure each 
check and
-                                       option is recognized without running 
any checks.
-    --vfsoverlay=<filename>          - Overlay the virtual filesystem 
described by file
-                                       over the real file system.
-    --warnings-as-errors=<string>    - Upgrades warnings to errors. Same 
format as
-                                       '-checks'.
-                                       This option's value is appended to the 
value of
-                                       the 'WarningsAsErrors' option in 
.clang-tidy
-                                       file, if any.
+    --allow-no-checks       Allow empty enabled checks. This suppresses
+                            the "no checks enabled" error when disabling
+                            all of the checks.
+    --checks=<string>       Comma-separated list of globs with optional '-'
+                            prefix. Globs are processed in order of
+                            appearance in the list. Globs without '-'
+                            prefix add checks with matching names to the
+                            set, globs with the '-' prefix remove checks
+                            with matching names from the set of enabled
+                            checks. This option's value is appended to the
+                            value of the 'Checks' option in .clang-tidy
+                            file, if any.
+    --config-file=<filename>
+                            Specify the path of .clang-tidy or custom config 
file:
+                             e.g. --config-file=/some/path/myTidyConfigFile
+                            This option internally works exactly the same way 
as
+                             --config option after reading specified config 
file.
+                            Use either --config-file or --config, not both.
+    --config=<string>       Specifies a configuration in YAML/JSON format:
+                              -config="{Checks: '*',
+                                        CheckOptions: {x: y}}"
+                            When the value is empty, clang-tidy will
+                            attempt to find a file named .clang-tidy for
+                            each source file in its parent directories.
+    --dump-config           Dumps configuration in the YAML format to
+                            stdout. This option can be used along with a
+                            file name (and '--' if the file is outside of a
+                            project with configured compilation database).
+                            The configuration used for this file will be
+                            printed.
+                            Use along with -checks=* to include
+                            configuration of all checks.
+    --enable-check-profile  Enable per-check timing profiles, and print a
+                            report to stderr.
+    --enable-module-headers-parsing
+                            Enables preprocessor-level module header parsing
+                            for C++20 and above, empowering specific checks
+                            to detect macro definitions within modules. This
+                            feature may cause performance and parsing issues
+                            and is therefore considered experimental.
+    --exclude-header-filter=<string>
+                            Regular expression matching the names of the
+                            headers to exclude diagnostics from. Diagnostics
+                            from the main file of each translation unit are
+                            always displayed.
+                            Must be used together with --header-filter.
+                            Can be used together with -line-filter.
+                            This option overrides the 
'ExcludeHeaderFilterRegex'
+                            option in .clang-tidy file, if any.
+    --experimental-custom-checks
+                            Enable experimental clang-query based
+                            custom checks.
+                            see 
https://clang.llvm.org/extra/clang-tidy/QueryBasedCustomChecks.html.
+    --explain-config        For each enabled check explains, where it is
+                            enabled, i.e. in clang-tidy binary, command
+                            line or a specific configuration file.
+    --export-fixes=<filename>
+                            YAML file to store suggested fixes in. The
+                            stored fixes can be applied to the input source
+                            code with clang-apply-replacements.
+    --extra-arg-before=<arg>
+                            Additional argument to prepend to the compiler 
command line
+    --extra-arg=<arg>       Additional argument to append to the compiler 
command line
+    --fix-errors            Apply suggested fixes even if compilation
+                            errors were found. If compiler errors have
+                            attached fix-its, clang-tidy will apply them as
+                            well.
+    --fix-notes             If a warning has no fix, but a single fix can
+                            be found through an associated diagnostic note,
+                            apply the fix.
+                            Specifying this flag will implicitly enable the
+                            '--fix' flag.
+    --fix                   Apply suggested fixes. Without -fix-errors
+                            clang-tidy will bail out if any compilation
+                            errors were found.
+    --format-style=<string> Style for formatting code around applied fixes:
+                              - 'none' (default) turns off formatting
+                              - 'file' (literally 'file', not a placeholder)
+                                uses .clang-format file in the closest parent
+                                directory
+                              - '{ <json> }' specifies options inline, e.g.
+                                -format-style='{BasedOnStyle: llvm, 
IndentWidth: 8}'
+                              - 'llvm', 'google', 'webkit', 'mozilla'
+                            See clang-format documentation for the up-to-date
+                            information about formatting styles and options.
+                            This option overrides the 'FormatStyle` option in
+                            .clang-tidy file, if any.
+    --header-filter=<string>
+                            Regular expression matching the names of the
+                            headers to output diagnostics from. The default
+                            value is '.*', i.e. diagnostics from all non-system
+                            headers are displayed by default. Diagnostics
+                            from the main file of each translation unit are
+                            always displayed.
+                            Can be used together with -line-filter.
+                            This option overrides the 'HeaderFilterRegex'
+                            option in .clang-tidy file, if any.
+    --line-filter=<string>  List of files and line ranges to output 
diagnostics from.
+                            The range is inclusive on both ends. Can be used 
together
+                            with -header-filter. The format of the list is a 
JSON
+                            array of objects. For example:
+                              [
+                                {"name":"file1.cpp","lines":[[1,3],[5,7]]},
+                                {"name":"file2.h"}
+                              ]
+                            This will output diagnostics from 'file1.cpp' only 
for
+                            the line ranges [1,3] and [5,7], as well as all 
from the
+                            entire 'file2.h'.
+    --list-checks           List all enabled checks and exit. Use with
+                            -checks=* to list all available checks.
+    --load=<pluginfilename> Load the specified plugin
+    -p <build-path>         Build path
+    --quiet                 Run clang-tidy in quiet mode. This suppresses
+                            printing statistics about ignored warnings and
+                            warnings treated as errors if the respective
+                            options are specified.
+    --removed-arg=<arg>     List of arguments to remove from the command
+                            line sent to the compiler. Please note that
+                            removing arguments might change the semantic
+                            of the analyzed code, possibly leading to
+                            compiler errors, false positives or
+                            false negatives. This option is applied
+                            before --extra-arg and --extra-arg-before
+    --store-check-profile=<prefix>
+                            By default reports are printed in tabulated
+                            format to stderr. When this option is passed,
+                            these per-TU profiles are instead stored as JSON.
+    --system-headers        Display the errors from system headers.
+                            This option overrides the 'SystemHeaders' option
+                            in .clang-tidy file, if any.
+    --use-color             Use colors in diagnostics. If not set, colors
+                            will be used if the terminal connected to
+                            standard output supports colors.
+                            This option overrides the 'UseColor' option in
+                            .clang-tidy file, if any.
+    --verify-config         Check the config files to ensure each check and
+                            option is recognized without running any checks.
+    --vfsoverlay=<filename> Overlay the virtual filesystem described by file
+                            over the real file system.
+    --warnings-as-errors=<string>
+                            Upgrades warnings to errors. Same format as
+                            '-checks'.
+                            This option's value is appended to the value of
+                            the 'WarningsAsErrors' option in .clang-tidy
+                            file, if any.
 
   -p <build-path> is used to read a compile command database.
 
@@ -283,7 +289,7 @@ An overview of all the command-line options:
     compile_commands.json exists (use -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
     CMake option to get this output). When no build path is specified,
     a search for compile_commands.json will be attempted through all
-    parent paths of the first input file . See:
+    parent paths of the first input file. See:
     https://clang.llvm.org/docs/HowToSetupToolingForLLVM.html for an
     example of setting up Clang Tooling on a source tree.
 
@@ -358,39 +364,6 @@ An overview of all the command-line options:
         some-check.SomeOption: 'some value'
       ...
 
-Running Clang-Tidy on CUDA Files
---------------------------------
-
-:program:`clang-tidy` supports analyzing CUDA source files. To ensure correct
-header resolution, it is important to specify the CUDA toolkit path using
-``--cuda-path``. For more details on how Clang handles CUDA, see
-`Compiling CUDA with Clang <https://llvm.org/docs/CompileCudaWithLLVM.html>`_.
-
-If you are using a GCC + NVCC build setup, the compiler command database will
-contain NVCC-specific flags that :program:`clang-tidy` does not understand.
-
-In this case, you should use the ``RemovedArgs`` configuration option (or
-``--removed-arg`` command-line option) to remove these flags, and
-``ExtraArgs`` (or ``--extra-arg``) to provide the ``--cuda-path``.
-
-For example, to remove the NVCC-specific ``-gencode`` flag and provide the
-CUDA path:
-
-.. code-block:: console
-
-  $ clang-tidy source.cu --removed-arg="-gencode" --removed-arg="arch=.." 
--extra-arg="--cuda-path=/path/to/cuda"
-
-By default, :program:`clang-tidy` will analyze both host and device code.
-To restrict the analysis to a specific side and specifically choose device
-compilation flags, use the ``--extra-arg`` flag to pass the arguments.
-
-For example, to perform device analysis only, use
-the ``--cuda-device-only`` flag:
-
-.. code-block:: console
-
-  $ clang-tidy source.cu --extra-arg="--cuda-device-only" 
--extra-arg="--cuda-path=/path/to/cuda"
-
 Clang-Tidy Automation
 =====================
 
diff --git 
a/clang-tools-extra/test/clang-tidy/infrastructure/invalid-command-line.cpp 
b/clang-tools-extra/test/clang-tidy/infrastructure/invalid-command-line.cpp
index 80540411e53e3..a389fec9070a6 100644
--- a/clang-tools-extra/test/clang-tidy/infrastructure/invalid-command-line.cpp
+++ b/clang-tools-extra/test/clang-tidy/infrastructure/invalid-command-line.cpp
@@ -1,4 +1,3 @@
 // RUN: not clang-tidy --invalid-arg 2>&1 | FileCheck %s
 
-// CHECK: error: clang-tidy{{(\.exe)?}}: Unknown command line argument 
'--invalid-arg'.  Try: '{{.*}}clang-tidy{{(\.exe)?}} --help'
-// CHECK-NEXT: clang-tidy{{(\.exe)?}}: Did you mean '--removed-arg'?
+// CHECK: clang-tidy: unknown argument '--invalid-arg'
diff --git 
a/utils/bazel/llvm-project-overlay/clang-tools-extra/clang-tidy/BUILD.bazel 
b/utils/bazel/llvm-project-overlay/clang-tools-extra/clang-tidy/BUILD.bazel
index a4e30d615a39a..aa72d0e1fd3d4 100644
--- a/utils/bazel/llvm-project-overlay/clang-tools-extra/clang-tidy/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/clang-tools-extra/clang-tidy/BUILD.bazel
@@ -6,6 +6,8 @@ load("@bazel_skylib//rules:common_settings.bzl", "bool_flag")
 load("@bazel_skylib//rules:expand_template.bzl", "expand_template")
 load("@bazel_skylib//rules:native_binary.bzl", "native_binary")
 load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")
+load("//llvm:driver.bzl", "llvm_driver_cc_binary")
+load("//mlir:tblgen.bzl", "gentbl_cc_library")
 load("defs.bzl", "clang_tidy_library")
 
 package(
@@ -385,22 +387,36 @@ CHECKS = [
     "//conditions:default": [],
 })
 
+gentbl_cc_library(
+    name = "ClangTidyOptsTableGen",
+    strip_include_prefix = "tool",
+    tbl_outs = {"tool/Opts.inc": ["-gen-opt-parser-defs"]},
+    tblgen = "//llvm:llvm-tblgen",
+    td_file = "tool/Opts.td",
+    deps = ["//llvm:OptParserTdFiles"],
+)
+
 cc_library(
     name = "tool",
-    srcs = ["tool/ClangTidyMain.cpp"],
+    srcs = [
+        "tool/ClangTidyMain.cpp",
+        "tool/ClangTidyToolMain.cpp",
+    ],
     hdrs = ["tool/ClangTidyMain.h"],
     deps = CHECKS + [
+        ":ClangTidyOptsTableGen",
         ":lib",
         ":utils",
+        "//clang:basic",
         "//clang:tooling",
+        "//llvm:Option",
         "//llvm:Support",
         "//llvm:TargetParser",
     ],
 )
 
-cc_binary(
+llvm_driver_cc_binary(
     name = "clang-tidy",
-    srcs = ["tool/ClangTidyToolMain.cpp"],
     stamp = 0,
     deps = [":tool"],
 )
diff --git a/utils/bazel/llvm-project-overlay/llvm/driver.bzl 
b/utils/bazel/llvm-project-overlay/llvm/driver.bzl
index 43c7b5c241f02..d6033d3cecd9d 100644
--- a/utils/bazel/llvm-project-overlay/llvm/driver.bzl
+++ b/utils/bazel/llvm-project-overlay/llvm/driver.bzl
@@ -10,6 +10,7 @@ load("@rules_cc//cc:defs.bzl", "CcInfo", "cc_binary")
 
 # Mapping from every tool to the cc_library that implements the tool's 
entrypoint.
 _TOOLS = {
+    "clang-tidy": "//clang-tools-extra/clang-tidy:tool",
     "clang-scan-deps": "//clang:clang-scan-deps-lib",
     "clang": "//clang:clang-driver",
     "dsymutil": "//llvm:dsymutil-lib",

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to