jansvoboda11 wrote:

Thanks for the concrete example! I think the key thing to realize is that the 
`DiagnosticsEngine` and `DiagnosticOptions` used for command-line parsing are 
typically throwaway and separate from those used for actual compilation. I 
suggest looking at how `cc1_main()` orchestrates this and why. The intent is 
for the `DiagnosticsEngine` used during the compilation (owned by 
`CompilerInstance`) to refer to the fully-formed `DiagnosticsOptions` (owned by 
`CompilerInvocation`).

So concretely, I'd rewrite your example as:

```c++
  clang::DiagnosticOptions diagnostic_options;
  llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> diagnostics_engine =
      clang::CompilerInstance::createDiagnostics(
          *file_system, diagnostic_options,
          new clang::TextDiagnosticPrinter(llvm::errs(), diagnostic_options));
  clang::CreateInvocationOptions ci_opts;
  ci_opts.Diags = diagnostics_engine;
  // ...
  std::shared_ptr<clang::CompilerInvocation> invocation =
      clang::createInvocation(args, ci_opts);

  auto compiler_instance =
      std::make_unique<clang::CompilerInstance>(invocation);
  compiler_instance->createDiagnostics(*file_system));
  // ...
  return compiler_instance;
```

I agree the lifetimes shouldn't be this complicated. FWIW I'd like to get rid 
of the reference count of `DiagnosticsEngine` too, and make the lifetimes 
stricter and more explicit, but that's a lower priority compared to the 
`DiagnosticOptions` refactor for me.

https://github.com/llvm/llvm-project/pull/139584
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to