diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index 24f713a7fa..243061edb8 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -28,6 +28,7 @@ #include "cmDependencyProvider.h" #include "cmExecutionStatus.h" #include "cmExperimental.h" +#include "cmFindPackageStack.h" #include "cmList.h" #include "cmListFileCache.h" #include "cmMakefile.h" @@ -1221,8 +1222,7 @@ bool cmFindPackageCommand::FindPackage( FlushDebugBufferOnExit flushDebugBufferOnExit(*this); PushPopRootPathStack pushPopRootPathStack(*this); SetRestoreFindDefinitions setRestoreFindDefinitions(*this); - cmMakefile::FindPackageStackRAII findPackageStackRAII(this->Makefile, - this->Name); + cmFindPackageStackRAII findPackageStackRAII(this->Makefile, this->Name); // See if we have been told to delegate to FetchContent or some other // redirected config package first. We have to check all names that diff --git a/Source/cmFindPackageStack.cxx b/Source/cmFindPackageStack.cxx index 4a824bae23..6f5045ae74 100644 --- a/Source/cmFindPackageStack.cxx +++ b/Source/cmFindPackageStack.cxx @@ -4,5 +4,12 @@ #include "cmFindPackageStack.h" #include "cmStack.tcc" // IWYU pragma: keep -template class cmStack; +template class cmStack; + +template cmFindPackageCall& +cmStack::Top(); + +cmFindPackageCall const& cmFindPackageStack::Top() const +{ + return this->cmStack::Top(); +} diff --git a/Source/cmFindPackageStack.h b/Source/cmFindPackageStack.h index 0f7be25187..f2bb6c6bc9 100644 --- a/Source/cmFindPackageStack.h +++ b/Source/cmFindPackageStack.h @@ -9,6 +9,8 @@ #include "cmStack.h" +class cmMakefile; + /** * Represents one call to find_package. */ @@ -19,16 +21,48 @@ public: unsigned int Index; }; +/** + * RAII type to manage the find_package call stack. + */ +// Note: implemented in cmMakefile.cxx +class cmFindPackageStackRAII +{ + cmMakefile* Makefile; + cmFindPackageCall** Value = nullptr; + +public: + cmFindPackageStackRAII(cmMakefile* mf, std::string const& pkg); + ~cmFindPackageStackRAII(); + + cmFindPackageStackRAII(cmFindPackageStackRAII const&) = delete; + cmFindPackageStackRAII& operator=(cmFindPackageStackRAII const&) = delete; + + /** Get a mutable pointer to the top of the stack. + The pointer is invalidated if BindTop is called again or when the + cmFindPackageStackRAII goes out of scope. */ + void BindTop(cmFindPackageCall*& value); +}; + /** * Represents a stack of find_package calls with efficient value semantics. */ class cmFindPackageStack - : public cmConstStack + : protected cmStack { using cmStack::cmStack; friend cmFindPackageStack::Base; + friend class cmFindPackageStackRAII; + +public: + using cmStack::Push; + using cmStack::Pop; + using cmStack::Empty; + + cmFindPackageCall const& Top() const; }; #ifndef cmFindPackageStack_cxx -extern template class cmStack; +extern template class cmStack; + +extern template cmFindPackageCall& +cmStack::Top(); #endif diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index bc947e9548..5ceb35e4cb 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -4231,8 +4231,8 @@ cmMakefile::MacroPushPop::~MacroPushPop() this->Makefile->PopMacroScope(this->ReportError); } -cmMakefile::FindPackageStackRAII::FindPackageStackRAII(cmMakefile* mf, - std::string const& name) +cmFindPackageStackRAII::cmFindPackageStackRAII(cmMakefile* mf, + std::string const& name) : Makefile(mf) { this->Makefile->FindPackageStack = @@ -4243,8 +4243,21 @@ cmMakefile::FindPackageStackRAII::FindPackageStackRAII(cmMakefile* mf, this->Makefile->FindPackageStackNextIndex++; } -cmMakefile::FindPackageStackRAII::~FindPackageStackRAII() +void cmFindPackageStackRAII::BindTop(cmFindPackageCall*& value) { + if (this->Value) { + *this->Value = nullptr; + } + this->Value = &value; + value = &this->Makefile->FindPackageStack.cmStack::Top(); +} + +cmFindPackageStackRAII::~cmFindPackageStackRAII() +{ + if (this->Value) { + *this->Value = nullptr; + } + this->Makefile->FindPackageStackNextIndex = this->Makefile->FindPackageStack.Top().Index + 1; this->Makefile->FindPackageStack = this->Makefile->FindPackageStack.Pop(); diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index ab0c75f4f9..17904182d4 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -1034,17 +1034,7 @@ public: // searches std::deque> FindPackageRootPathStack; - class FindPackageStackRAII - { - cmMakefile* Makefile; - - public: - FindPackageStackRAII(cmMakefile* mf, std::string const& pkg); - ~FindPackageStackRAII(); - - FindPackageStackRAII(FindPackageStackRAII const&) = delete; - FindPackageStackRAII& operator=(FindPackageStackRAII const&) = delete; - }; + friend class cmFindPackageStackRAII; class DebugFindPkgRAII {