diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.cpp index a95fce1c5aa96..5d67a51b26905 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.cpp @@ -18,7 +18,10 @@ lldb_private::ASTConsumerForwarder::~ASTConsumerForwarder() = default; void lldb_private::ASTConsumerForwarder::PrintStats() { m_c->PrintStats(); } -lldb_private::SemaSourceWithPriorities::~SemaSourceWithPriorities() = default; +lldb_private::SemaSourceWithPriorities::~SemaSourceWithPriorities() { + for (auto *Source : Sources) + Source->Release(); +} void lldb_private::SemaSourceWithPriorities::PrintStats() { for (size_t i = 0; i < Sources.size(); ++i) diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h b/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h index 79ed74b79f04f..44e52e8dd6511 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h +++ b/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h @@ -14,6 +14,7 @@ #include "clang/Sema/MultiplexExternalSemaSource.h" #include "clang/Sema/Sema.h" #include "clang/Sema/SemaConsumer.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" #include namespace clang { @@ -24,13 +25,15 @@ class Module; namespace lldb_private { -/// Wraps an ExternalASTSource into an ExternalSemaSource. Doesn't take -/// ownership of the provided source. +/// Wraps an ExternalASTSource into an ExternalSemaSource. +/// +/// Assumes shared ownership of the underlying source. class ExternalASTSourceWrapper : public clang::ExternalSemaSource { - ExternalASTSource *m_Source; + llvm::IntrusiveRefCntPtr m_Source; public: - ExternalASTSourceWrapper(ExternalASTSource *Source) : m_Source(Source) { + explicit ExternalASTSourceWrapper(ExternalASTSource *Source) + : m_Source(Source) { assert(m_Source && "Can't wrap nullptr ExternalASTSource"); } @@ -256,10 +259,18 @@ class SemaSourceWithPriorities : public clang::ExternalSemaSource { /// Construct a SemaSourceWithPriorities with a 'high quality' source that /// has the higher priority and a 'low quality' source that will be used /// as a fallback. - SemaSourceWithPriorities(clang::ExternalSemaSource &high_quality_source, - clang::ExternalSemaSource &low_quality_source) { - Sources.push_back(&high_quality_source); - Sources.push_back(&low_quality_source); + /// + /// This class assumes shared ownership of the sources provided to it. + SemaSourceWithPriorities(clang::ExternalSemaSource *high_quality_source, + clang::ExternalSemaSource *low_quality_source) { + assert(high_quality_source); + assert(low_quality_source); + + high_quality_source->Retain(); + low_quality_source->Retain(); + + Sources.push_back(high_quality_source); + Sources.push_back(low_quality_source); } ~SemaSourceWithPriorities() override; diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp index c441153d1efb0..d37787ebae26c 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp @@ -1224,15 +1224,15 @@ ClangExpressionParser::ParseInternal(DiagnosticManager &diagnostic_manager, clang::ExternalASTSource *ast_source = decl_map->CreateProxy(); if (ast_context.getExternalSource()) { - auto module_wrapper = + auto *module_wrapper = new ExternalASTSourceWrapper(ast_context.getExternalSource()); - auto ast_source_wrapper = new ExternalASTSourceWrapper(ast_source); + auto *ast_source_wrapper = new ExternalASTSourceWrapper(ast_source); - auto multiplexer = - new SemaSourceWithPriorities(*module_wrapper, *ast_source_wrapper); - IntrusiveRefCntPtr Source(multiplexer); - ast_context.setExternalSource(Source); + auto *multiplexer = + new SemaSourceWithPriorities(module_wrapper, ast_source_wrapper); + + ast_context.setExternalSource(multiplexer); } else { ast_context.setExternalSource(ast_source); }