Repository: carbon-language/carbon-lang
File: toolchain/check/import_cpp.cpp (C++)

Code before:
static auto GenerateCppIncludesHeaderCode(
    Context& context, llvm::ArrayRef<Parse::Tree::PackagingNames> imports)
    -> std::string {
  std::string code;
  llvm::raw_string_ostream code_stream(code);
  for (const Parse::Tree::PackagingNames& import : imports) {
    code_stream << "#include \""
                << FormatEscaped(
                       context.string_literal_values().Get(import.library_id))
                << "\"\n";
  }
  return code;
}

namespace {

class CarbonClangDiagnosticConsumer : public clang::DiagnosticConsumer {
 public:
  CarbonClangDiagnosticConsumer(Context& context, SemIRLoc loc)
      : context_(context), loc_(loc) {}

  void HandleDiagnostic(clang::DiagnosticsEngine::Level diag_level,
                        const clang::Diagnostic& info) override {
    DiagnosticConsumer::HandleDiagnostic(diag_level, info);

    llvm::SmallString<100> message;
    info.FormatDiagnostic(message);

    std::string diagnostics_str;
    llvm::raw_string_ostream diagnostics_stream(diagnostics_str);
    clang::TextDiagnostic text_diagnostic(
        diagnostics_stream,
        // TODO: Consider allowing setting `LangOptions` or use
        // `ASTContext::getLangOptions()`.
        clang::LangOptions(),
        // TODO: Consider allowing setting `DiagnosticOptions` or use
        // `ASTUnit::getDiagnostics().::getLangOptions().getDiagnosticOptions()`.
        new clang::DiagnosticOptions());
    text_diagnostic.emitDiagnostic(
        clang::FullSourceLoc(info.getLocation(), info.getSourceManager()),
        diag_level, message, info.getRanges(), info.getFixItHints());

    switch (diag_level) {
      case clang::DiagnosticsEngine::Ignored:
      case clang::DiagnosticsEngine::Note:
      case clang::DiagnosticsEngine::Remark: {
        context_.TODO(
            loc_, llvm::formatv(
                      "Unsupported: C++ diagnostic level for diagnostic {0}",
                      diagnostics_str));
        return;

Review comment (suggestion):
Had you considered 256 here, rather than 100? Note that there are trade-offs here, like memory alignment, where a power-of-2 choice might do better. Also, diagnostic messages seem likely to frequently be over 100 chars; some might fit into 256, and comparing with other code I see at least some doing 256 for diagnostic messages. (example: https://github.com/llvm/llvm-project/blob/main/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp#L576)

Code after:
static auto GenerateCppIncludesHeaderCode(
    Context& context, llvm::ArrayRef<Parse::Tree::PackagingNames> imports)
    -> std::string {
  std::string code;
  llvm::raw_string_ostream code_stream(code);
  for (const Parse::Tree::PackagingNames& import : imports) {
    code_stream << "#include \""
                << FormatEscaped(
                       context.string_literal_values().Get(import.library_id))
                << "\"\n";
  }
  return code;
}

namespace {

// Used to convert Clang diagnostics to Carbon diagnostics.
class CarbonClangDiagnosticConsumer : public clang::DiagnosticConsumer {
 public:
  // Creates an instance with the location that triggers calling Clang.
  // `context` must not be null.
  explicit CarbonClangDiagnosticConsumer(Context* context, SemIRLoc loc)
      : context_(context), loc_(loc) {}

  // Generates a Carbon warning for each Clang warning and a Carbon error for
  // each Clang error or fatal.
  auto HandleDiagnostic(clang::DiagnosticsEngine::Level diag_level,
                        const clang::Diagnostic& info) -> void override {
    DiagnosticConsumer::HandleDiagnostic(diag_level, info);

    llvm::SmallString<256> message;
    info.FormatDiagnostic(message);

    RawStringOstream diagnostics_stream;
    clang::TextDiagnostic text_diagnostic(
        diagnostics_stream,
        // TODO: Consider allowing setting `LangOptions` or use
        // `ASTContext::getLangOptions()`.
        clang::LangOptions(),
        // TODO: Consider allowing setting `DiagnosticOptions` or use
        // `ASTUnit::getDiagnostics().::getLangOptions().getDiagnosticOptions()`.
        new clang::DiagnosticOptions());
    text_diagnostic.emitDiagnostic(
        clang::FullSourceLoc(info.getLocation(), info.getSourceManager()),
        diag_level, message, info.getRanges(), info.getFixItHints());

    std::string diagnostics_str = diagnostics_stream.TakeStr();

    switch (diag_level) {
      case clang::DiagnosticsEngine::Ignored:
      case clang::DiagnosticsEngine::Note: