Skip to content

[clang] Migrate clang-rename to OptTable parsing #89167

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 21 additions & 4 deletions clang/include/clang/Tooling/CommonOptionsParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,24 @@ class CommonOptionsParser {
llvm::cl::NumOccurrencesFlag OccurrencesFlag = llvm::cl::OneOrMore,
const char *Overview = nullptr);

struct Args {
std::string BuildPath;
std::vector<std::string> SourcePaths;
std::vector<std::string> ArgsAfter;
std::vector<std::string> ArgsBefore;
};

using ArgParserCallback =
std::function<llvm::Expected<Args>(int &argc, const char **argv)>;

/// A factory method that is similar to the above factory method, except
/// this does not force use of cl::opt argument parsing. The function passed
/// in is expected to handle argument parsing, and must return values needed
/// by CommonOptionsParser.
static llvm::Expected<CommonOptionsParser>
create(int &argc, const char **argv, ArgParserCallback ArgsCallback,
llvm::cl::NumOccurrencesFlag OccurrencesFlag = llvm::cl::OneOrMore);

/// Returns a reference to the loaded compilations database.
CompilationDatabase &getCompilations() {
return *Compilations;
Expand All @@ -105,10 +123,9 @@ class CommonOptionsParser {
private:
CommonOptionsParser() = default;

llvm::Error init(int &argc, const char **argv,
llvm::cl::OptionCategory &Category,
llvm::cl::NumOccurrencesFlag OccurrencesFlag,
const char *Overview);
llvm::Error
init(int &argc, const char **argv, ArgParserCallback ArgsCallback,
llvm::cl::NumOccurrencesFlag OccurrencesFlag = llvm::cl::OneOrMore);

std::unique_ptr<CompilationDatabase> Compilations;
std::vector<std::string> SourcePathList;
Expand Down
14 changes: 14 additions & 0 deletions clang/include/clang/Tooling/CommonOptionsParser.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
include "llvm/Option/OptParser.td"

multiclass Eq<string name, string help> {
def NAME#_EQ : Joined<["--", "-"], name#"=">, HelpText<help>;
def : Separate<["--", "-"], name>, Alias<!cast<Joined>(NAME#_EQ)>;
}

defm build_path : Eq<"p", "Build path.">;
defm extra_arg
: Eq<"extra-arg",
"Additional argument to append to the compiler command line.">;
defm extra_arg_before
: Eq<"extra-arg-before",
"Additional argument to prepend to the compiler command line.">;
127 changes: 75 additions & 52 deletions clang/lib/Tooling/CommonOptionsParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,12 @@ void ArgumentsAdjustingCompilations::appendArgumentsAdjuster(
Adjusters.push_back(std::move(Adjuster));
}

std::vector<CompileCommand> ArgumentsAdjustingCompilations::getCompileCommands(
StringRef FilePath) const {
std::vector<CompileCommand>
ArgumentsAdjustingCompilations::getCompileCommands(StringRef FilePath) const {
return adjustCommands(Compilations->getCompileCommands(FilePath));
}

std::vector<std::string>
ArgumentsAdjustingCompilations::getAllFiles() const {
std::vector<std::string> ArgumentsAdjustingCompilations::getAllFiles() const {
return Compilations->getAllFiles();
}

Expand All @@ -80,58 +79,32 @@ std::vector<CompileCommand> ArgumentsAdjustingCompilations::adjustCommands(
return Commands;
}

llvm::Error CommonOptionsParser::init(
int &argc, const char **argv, cl::OptionCategory &Category,
llvm::cl::NumOccurrencesFlag OccurrencesFlag, const char *Overview) {

static cl::opt<std::string> BuildPath("p", cl::desc("Build path"),
cl::Optional, cl::cat(Category),
cl::sub(cl::SubCommand::getAll()));

static cl::list<std::string> SourcePaths(
cl::Positional, cl::desc("<source0> [... <sourceN>]"), OccurrencesFlag,
cl::cat(Category), cl::sub(cl::SubCommand::getAll()));

static cl::list<std::string> ArgsAfter(
"extra-arg",
cl::desc("Additional argument to append to the compiler command line"),
cl::cat(Category), cl::sub(cl::SubCommand::getAll()));

static cl::list<std::string> ArgsBefore(
"extra-arg-before",
cl::desc("Additional argument to prepend to the compiler command line"),
cl::cat(Category), cl::sub(cl::SubCommand::getAll()));

cl::ResetAllOptionOccurrences();

cl::HideUnrelatedOptions(Category);

llvm::Error
CommonOptionsParser::init(int &argc, const char **argv,
ArgParserCallback ArgsCallback,
llvm::cl::NumOccurrencesFlag OccurrencesFlag) {
std::string ErrorMessage;
Compilations =
FixedCompilationDatabase::loadFromCommandLine(argc, argv, ErrorMessage);
if (!ErrorMessage.empty())
ErrorMessage.append("\n");
llvm::raw_string_ostream OS(ErrorMessage);
// Stop initializing if command-line option parsing failed.
if (!cl::ParseCommandLineOptions(argc, argv, Overview, &OS)) {
OS.flush();
return llvm::make_error<llvm::StringError>(ErrorMessage,
llvm::inconvertibleErrorCode());
}

cl::PrintOptionValues();
// Stop initializing if command-line option parsing failed.
auto Args = ArgsCallback(argc, argv);
if (!Args)
return Args.takeError();

SourcePathList = SourcePaths;
SourcePathList = Args->SourcePaths;
if ((OccurrencesFlag == cl::ZeroOrMore || OccurrencesFlag == cl::Optional) &&
SourcePathList.empty())
return llvm::Error::success();
if (!Compilations) {
if (!BuildPath.empty()) {
Compilations =
CompilationDatabase::autoDetectFromDirectory(BuildPath, ErrorMessage);
if (!Args->BuildPath.empty()) {
Compilations = CompilationDatabase::autoDetectFromDirectory(
Args->BuildPath, ErrorMessage);
} else {
Compilations = CompilationDatabase::autoDetectFromSource(SourcePaths[0],
ErrorMessage);
Compilations = CompilationDatabase::autoDetectFromSource(
Args->SourcePaths[0], ErrorMessage);
}
if (!Compilations) {
llvm::errs() << "Error while trying to load a compilation database:\n"
Expand All @@ -141,24 +114,72 @@ llvm::Error CommonOptionsParser::init(
}
}
auto AdjustingCompilations =
std::make_unique<ArgumentsAdjustingCompilations>(
std::move(Compilations));
Adjuster =
getInsertArgumentAdjuster(ArgsBefore, ArgumentInsertPosition::BEGIN);
std::make_unique<ArgumentsAdjustingCompilations>(std::move(Compilations));
Adjuster = getInsertArgumentAdjuster(Args->ArgsBefore,
ArgumentInsertPosition::BEGIN);
Adjuster = combineAdjusters(
std::move(Adjuster),
getInsertArgumentAdjuster(ArgsAfter, ArgumentInsertPosition::END));
getInsertArgumentAdjuster(Args->ArgsAfter, ArgumentInsertPosition::END));
AdjustingCompilations->appendArgumentsAdjuster(Adjuster);
Compilations = std::move(AdjustingCompilations);
return llvm::Error::success();
}

CommonOptionsParser::ArgParserCallback
makeClOptParserCallback(llvm::cl::OptionCategory &Category,
llvm::cl::NumOccurrencesFlag OccurrencesFlag,
const char *Overview) {
return [&Category, OccurrencesFlag, Overview](
int &argc,
const char **argv) -> llvm::Expected<CommonOptionsParser::Args> {
static cl::opt<std::string> BuildPath("p", cl::desc("Build path"),
cl::Optional, cl::cat(Category),
cl::sub(cl::SubCommand::getAll()));

static cl::list<std::string> SourcePaths(
cl::Positional, cl::desc("<source0> [... <sourceN>]"), OccurrencesFlag,
cl::cat(Category), cl::sub(cl::SubCommand::getAll()));

static cl::list<std::string> ArgsAfter(
"extra-arg",
cl::desc("Additional argument to append to the compiler command line"),
cl::cat(Category), cl::sub(cl::SubCommand::getAll()));

static cl::list<std::string> ArgsBefore(
"extra-arg-before",
cl::desc("Additional argument to prepend to the compiler command line"),
cl::cat(Category), cl::sub(cl::SubCommand::getAll()));

cl::ResetAllOptionOccurrences();

cl::HideUnrelatedOptions(Category);

std::string ErrorMessage;
llvm::raw_string_ostream OS(ErrorMessage);
if (!cl::ParseCommandLineOptions(argc, argv, Overview, &OS)) {
OS.flush();
return llvm::make_error<llvm::StringError>(
ErrorMessage, llvm::inconvertibleErrorCode());
}
return CommonOptionsParser::Args{BuildPath, SourcePaths, ArgsAfter,
ArgsBefore};
};
}

llvm::Expected<CommonOptionsParser> CommonOptionsParser::create(
int &argc, const char **argv, llvm::cl::OptionCategory &Category,
llvm::cl::NumOccurrencesFlag OccurrencesFlag, const char *Overview) {
return create(argc, argv,
makeClOptParserCallback(Category, OccurrencesFlag, Overview),
OccurrencesFlag);
}

llvm::Expected<CommonOptionsParser>
CommonOptionsParser::create(int &argc, const char **argv,
ArgParserCallback ArgsCallback,
llvm::cl::NumOccurrencesFlag OccurrencesFlag) {
CommonOptionsParser Parser;
llvm::Error Err =
Parser.init(argc, argv, Category, OccurrencesFlag, Overview);
llvm::Error Err = Parser.init(argc, argv, ArgsCallback, OccurrencesFlag);
if (Err)
return std::move(Err);
return std::move(Parser);
Expand All @@ -167,7 +188,9 @@ llvm::Expected<CommonOptionsParser> CommonOptionsParser::create(
CommonOptionsParser::CommonOptionsParser(
int &argc, const char **argv, cl::OptionCategory &Category,
llvm::cl::NumOccurrencesFlag OccurrencesFlag, const char *Overview) {
llvm::Error Err = init(argc, argv, Category, OccurrencesFlag, Overview);
llvm::Error Err = init(
argc, argv, makeClOptParserCallback(Category, OccurrencesFlag, Overview),
OccurrencesFlag);
if (Err) {
llvm::report_fatal_error(
Twine("CommonOptionsParser: failed to parse command-line arguments. ") +
Expand Down
7 changes: 7 additions & 0 deletions clang/tools/clang-rename/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,15 @@ set(LLVM_LINK_COMPONENTS
Support
)

set(LLVM_TARGET_DEFINITIONS Opts.td)
tablegen(LLVM Opts.inc -gen-opt-parser-defs)
add_public_tablegen_target(ClangRenameOptsTableGen)

add_clang_tool(clang-rename
ClangRename.cpp

DEPENDS
ClangRenameOptsTableGen
)

clang_target_link_libraries(clang-rename
Expand Down
Loading