From 788463e72af847d11476793fdd5d57a104b18b3d Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Wed, 25 May 2022 08:45:41 -0400 Subject: [PATCH] [pseudo-gen] Add -o flag, make --grammar required Virtually all LLVM tools accept a `-o` flag, so add one. This will make it possible to possibly add a --write-if-changed flag later. It also makes it so that the file isn't partially written if the tool oesn't run successfully. Marking --grammar as `Required` allows removing some manual verification code for it. Differential Revision: https://reviews.llvm.org/D126373 --- clang-tools-extra/pseudo/gen/Main.cpp | 33 +++++++++++++------ .../pseudo/include/CMakeLists.txt | 4 +-- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/clang-tools-extra/pseudo/gen/Main.cpp b/clang-tools-extra/pseudo/gen/Main.cpp index 535f863268df..47ba7f2e71b5 100644 --- a/clang-tools-extra/pseudo/gen/Main.cpp +++ b/clang-tools-extra/pseudo/gen/Main.cpp @@ -15,13 +15,17 @@ #include "clang-pseudo/Grammar.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/ToolOutputFile.h" #include using llvm::cl::desc; using llvm::cl::init; using llvm::cl::opt; +using llvm::cl::Required; +using llvm::cl::value_desc; using llvm::cl::values; namespace { @@ -31,13 +35,17 @@ enum EmitType { }; opt Grammar("grammar", desc("Parse a BNF grammar file."), - init("")); + Required); opt Emit(desc("which information to emit:"), values(clEnumValN(EmitSymbolList, "emit-symbol-list", "Print nonterminal symbols (default)"), clEnumValN(EmitGrammarContent, "emit-grammar-content", "Print the BNF grammar content as a string"))); + +opt OutputFilename("o", init("-"), desc("Output"), + value_desc("file")); + std::string readOrDie(llvm::StringRef Path) { llvm::ErrorOr> Text = llvm::MemoryBuffer::getFile(Path); @@ -52,10 +60,6 @@ std::string readOrDie(llvm::StringRef Path) { int main(int argc, char *argv[]) { llvm::cl::ParseCommandLineOptions(argc, argv, ""); - if (!Grammar.getNumOccurrences()) { - llvm::errs() << "Grammar file must be provided!\n"; - return 1; - } std::string GrammarText = readOrDie(Grammar); std::vector Diags; @@ -65,25 +69,34 @@ int main(int argc, char *argv[]) { llvm::errs() << llvm::join(Diags, "\n"); return 1; } - switch (Emit) { + std::error_code EC; + llvm::ToolOutputFile Out{OutputFilename, EC, llvm::sys::fs::OF_None}; + if (EC) { + llvm::errs() << EC.message() << '\n'; + return 1; + } + + switch (Emit) { case EmitSymbolList: for (clang::pseudo::SymbolID ID = 0; ID < G->table().Nonterminals.size(); ++ID) { std::string Name = G->symbolName(ID).str(); // translation-unit -> translation_unit std::replace(Name.begin(), Name.end(), '-', '_'); - llvm::outs() << (llvm::formatv("NONTERMINAL({0}, {1})\n", Name, ID)); + Out.os() << llvm::formatv("NONTERMINAL({0}, {1})\n", Name, ID); } break; case EmitGrammarContent: for (llvm::StringRef Line : llvm::split(GrammarText, '\n')) { - llvm::outs() << '"'; - llvm::outs().write_escaped((Line + "\n").str()); - llvm::outs() << "\"\n"; + Out.os() << '"'; + Out.os().write_escaped((Line + "\n").str()); + Out.os() << "\"\n"; } break; } + Out.keep(); + return 0; } diff --git a/clang-tools-extra/pseudo/include/CMakeLists.txt b/clang-tools-extra/pseudo/include/CMakeLists.txt index e2a6f0efc0a3..a79dd0dab818 100644 --- a/clang-tools-extra/pseudo/include/CMakeLists.txt +++ b/clang-tools-extra/pseudo/include/CMakeLists.txt @@ -7,7 +7,7 @@ add_custom_command(OUTPUT ${cxx_symbols_inc} COMMAND "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/pseudo-gen" --grammar ${cxx_bnf} --emit-symbol-list - > ${cxx_symbols_inc} + -o ${cxx_symbols_inc} COMMENT "Generating nonterminal symbol file for cxx grammar..." DEPENDS pseudo-gen VERBATIM) @@ -17,7 +17,7 @@ add_custom_command(OUTPUT ${cxx_bnf_inc} COMMAND "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/pseudo-gen" --grammar ${cxx_bnf} --emit-grammar-content - > ${cxx_bnf_inc} + -o ${cxx_bnf_inc} COMMENT "Generating bnf string file for cxx grammar..." DEPENDS pseudo-gen VERBATIM)