source_gen_main.cpp 3.5 KB

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