source_gen_main.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #include <optional>
  5. #include <system_error>
  6. #include "common/bazel_working_dir.h"
  7. #include "common/command_line.h"
  8. #include "common/init_llvm.h"
  9. #include "common/ostream.h"
  10. #include "llvm/ADT/ArrayRef.h"
  11. #include "llvm/ADT/SmallVector.h"
  12. #include "llvm/ADT/StringRef.h"
  13. #include "llvm/Support/FileSystem.h"
  14. #include "testing/base/source_gen.h"
  15. namespace Carbon::Testing {
  16. namespace {
  17. constexpr CommandLine::CommandInfo Info = {
  18. .name = "source_gen",
  19. .help = R"""(
  20. A source generator for Carbon.
  21. )""",
  22. };
  23. constexpr CommandLine::ArgInfo OutputArgInfo = {
  24. .name = "output",
  25. .value_name = "FILE",
  26. .help = R"""(
  27. Writes the generate source code to a file rather than stdout.
  28. )""",
  29. };
  30. constexpr CommandLine::ArgInfo LinesArgInfo = {
  31. .name = "lines",
  32. .value_name = "N",
  33. .help = R"""(
  34. The number of lines of code to target for a generated source file.
  35. )""",
  36. };
  37. constexpr CommandLine::ArgInfo LanguageArgInfo = {
  38. .name = "language",
  39. //.value_name = "[carbon|cpp]",
  40. .help = R"""(
  41. The language of source code to generate. The C++ source generation is best
  42. effort to try to provide as much comparable benchmarking as possible, but the
  43. primary language focus is generating Carbon.
  44. )""",
  45. };
  46. auto Run(llvm::ArrayRef<llvm::StringRef> args) -> bool {
  47. // Default to outputting to stdout and writing 10k lines of source code.
  48. llvm::StringRef output_filename = "-";
  49. int lines = 10'000;
  50. SourceGen::Language language;
  51. auto parse_result = CommandLine::Parse(
  52. args, llvm::outs(), Info, [&](CommandLine::CommandBuilder& b) {
  53. b.AddStringOption(OutputArgInfo,
  54. [&](auto& arg_b) { arg_b.Set(&output_filename); });
  55. b.AddIntegerOption(LinesArgInfo,
  56. [&](auto& arg_b) { arg_b.Set(&lines); });
  57. b.AddOneOfOption(LanguageArgInfo, [&](auto& arg_b) {
  58. arg_b.SetOneOf(
  59. {
  60. arg_b.OneOfValue("carbon", SourceGen::Language::Carbon)
  61. .Default(true),
  62. arg_b.OneOfValue("cpp", SourceGen::Language::Cpp),
  63. },
  64. &language);
  65. });
  66. // No-op action as there is only one operation for this command.
  67. b.Do([] {});
  68. });
  69. if (!parse_result.ok()) {
  70. llvm::errs() << "error: " << *parse_result << "\n";
  71. return false;
  72. } else if (*parse_result == CommandLine::ParseResult::MetaSuccess) {
  73. // Fully handled by the CLI library.
  74. return true;
  75. }
  76. std::optional<llvm::raw_fd_ostream> output_file;
  77. llvm::raw_fd_ostream* output = &llvm::outs();
  78. if (output_filename != "-") {
  79. std::error_code ec;
  80. output_file.emplace(output_filename, ec, llvm::sys::fs::OF_None);
  81. if (ec) {
  82. llvm::errs() << "ERROR: Unable to open output file '" << output_filename
  83. << "': " << ec.message() << "\n";
  84. return false;
  85. }
  86. output = &*output_file;
  87. }
  88. SourceGen gen(language);
  89. *output << gen.GenApiFileDenseDecls(lines, SourceGen::DenseDeclParams{});
  90. output->flush();
  91. return true;
  92. }
  93. } // namespace
  94. } // namespace Carbon::Testing
  95. auto main(int argc, char** argv) -> int {
  96. // Do LLVM's initialization first, this will also transform UTF-16 to UTF-8.
  97. Carbon::InitLLVM init_llvm(argc, argv);
  98. Carbon::SetWorkingDirForBazelRun();
  99. llvm::SmallVector<llvm::StringRef> args(argv + 1, argv + argc);
  100. bool success = Carbon::Testing::Run(args);
  101. return success ? EXIT_SUCCESS : EXIT_FAILURE;
  102. }