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

Code before:
              SemIR::LocId(info.import_ir_inst_id),
              info.level == clang::DiagnosticsEngine::Warning
                  ? CppInteropParseWarning
                  : CppInteropParseError,
              info.message);
          for (;
               i + 1 < diagnostic_infos_.size() &&
               diagnostic_infos_[i + 1].level == clang::DiagnosticsEngine::Note;
               ++i) {
            const ClangDiagnosticInfo& note_info = diagnostic_infos_[i + 1];
            CARBON_DIAGNOSTIC(CppInteropParseNote, Note, "{0}", std::string);
            builder.Note(SemIR::LocId(note_info.import_ir_inst_id),
                         CppInteropParseNote, note_info.message);
          }
          builder.Emit();
          break;
        }
      }
    }
    diagnostic_infos_.clear();
  }

 private:
  // Callback to flush Clang diagnostics into the Carbon diagnostics engine.
  struct DiagnosticFlusher {
    CarbonClangDiagnosticConsumer* consumer_;
    void operator()() const { consumer_->EmitDiagnostics(); }
  };

  // The type-checking context in which we're running Clang.
  Context* context_;

  // The compiler invocation that is producing the diagnostics.
  std::shared_ptr<clang::CompilerInvocation> invocation_;

  // Information on a Clang diagnostic that can be converted to a Carbon
  // diagnostic.
  struct ClangDiagnosticInfo {
    // The Clang diagnostic level.
    clang::DiagnosticsEngine::Level level;

    // The ID of the ImportIR instruction referring to the Clang source
    // location.
    SemIR::ImportIRInstId import_ir_inst_id;

    // The Clang diagnostic textual message.
    std::string message;
  };

  // Collects the information for all Clang diagnostics to be converted to
  // Carbon diagnostics after the context has been initialized with the Clang

Review comment (bug):
Consider explicitly initializing to nullptr to avoid accidentally having it unset.
```suggestion
    CarbonClangDiagnosticConsumer* consumer_ = nullptr;
```
Alternatively, we can make it a class with a private data member and initialize the data member in the constructor.

Code after:
              SemIR::LocId(info.import_ir_inst_id),
              info.level == clang::DiagnosticsEngine::Warning
                  ? CppInteropParseWarning
                  : CppInteropParseError,
              info.message);
          for (;
               i + 1 < diagnostic_infos_.size() &&
               diagnostic_infos_[i + 1].level == clang::DiagnosticsEngine::Note;
               ++i) {
            const ClangDiagnosticInfo& note_info = diagnostic_infos_[i + 1];
            CARBON_DIAGNOSTIC(CppInteropParseNote, Note, "{0}", std::string);
            builder.Note(SemIR::LocId(note_info.import_ir_inst_id),
                         CppInteropParseNote, note_info.message);
          }
          builder.Emit();
          break;
        }
      }
    }
    diagnostic_infos_.clear();
  }

 private:
  // The type-checking context in which we're running Clang.
  Context* context_;

  // The compiler invocation that is producing the diagnostics.
  std::shared_ptr<clang::CompilerInvocation> invocation_;

  // Information on a Clang diagnostic that can be converted to a Carbon
  // diagnostic.
  struct ClangDiagnosticInfo {
    // The Clang diagnostic level.
    clang::DiagnosticsEngine::Level level;

    // The ID of the ImportIR instruction referring to the Clang source
    // location.
    SemIR::ImportIRInstId import_ir_inst_id;

    // The Clang diagnostic textual message.
    std::string message;
  };

  // Collects the information for all Clang diagnostics to be converted to
  // Carbon diagnostics after the context has been initialized with the Clang
  // AST.
  llvm::SmallVector<ClangDiagnosticInfo> diagnostic_infos_;
};

}  // namespace