The way we parse DiagnosticOptions is a bit involved.
DiagnosticOptions are parsed as part of the cc1-parsing function CompilerInvocation::CreateFromArgs which takes DiagnosticsEngine as an argument to be able to report errors in command-line arguments. But to create DiagnosticsEngine, DiagnosticOptions are needed. This is solved by exposing the ParseDiagnosticArgs to clients and making its DiagnosticsEngine argument optional, essentially breaking the dependency cycle.
The ParseDiagnosticArgs function takes llvm::opt::ArgList &, which each client needs to create from the command-line (typically represented as std::vector<const char *>). Creating this data structure in this context is somewhat particular. This code pattern is copy-pasted in some places across the upstream code base and also in downstream repos. To make things a bit more uniform, this patch extracts the code into a new reusable function: CreateAndPopulateDiagOpts.
Please return std::unique_ptr<DiagnosticOptions if this is an owning pointer. The caller can call .release if it needs to unpack it (although the current caller needn't do anything since there's an implicit conversion to IntrusiveRefCntPtr from std::unique_ptr).
Also, I'd prefer to propagate the lowerCamelCase style for functions recommended by the coding standards... up to you I guess since I know this file has a lot of UpperCamelCase.