diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index d49fefb457..cfbe1fe9da 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -400,20 +400,59 @@ void cmMakefile::PrintCommandTrace(cmListFileFunction const& lff, } } +cmMakefile::CallRAII::CallRAII(cmMakefile* mf, std::string const& file, + cmExecutionStatus& status) + : CallRAII(mf, cmListFileContext::FromListFilePath(file), status) +{ +} + +cmMakefile::CallRAII::CallRAII(cmMakefile* mf, const cmListFileContext& lfc, + cmExecutionStatus& status) + : Makefile{ mf } +{ + this->Makefile->Backtrace = this->Makefile->Backtrace.Push(lfc); + ++this->Makefile->RecursionDepth; + this->Makefile->ExecutionStatusStack.push_back(&status); +} + +cmMakefile::CallRAII::~CallRAII() +{ + if (this->Makefile) { + this->Detach(); + } +} + +cmMakefile* cmMakefile::CallRAII::Detach() +{ + assert(this->Makefile); + + this->Makefile->ExecutionStatusStack.pop_back(); + --this->Makefile->RecursionDepth; + this->Makefile->Backtrace = this->Makefile->Backtrace.Pop(); + + auto* const mf = this->Makefile; + this->Makefile = nullptr; + return mf; +} + // Helper class to make sure the call stack is valid. -class cmMakefileCall +class cmMakefile::CallScope : public CallRAII { public: - cmMakefileCall(cmMakefile* mf, cmListFileFunction const& lff, - cm::optional deferId, cmExecutionStatus& status) - : Makefile(mf) + CallScope(cmMakefile* mf, cmListFileFunction const& lff, + cm::optional deferId, cmExecutionStatus& status) + : CallScope{ mf, lff, + cmListFileContext::FromListFileFunction( + lff, mf->StateSnapshot.GetExecutionListFile(), + std::move(deferId)), + status } + { + } + + CallScope(cmMakefile* mf, cmListFileFunction const& lff, + cmListFileContext const& lfc, cmExecutionStatus& status) + : CallRAII{ mf, lfc, status } { - cmListFileContext const& lfc = cmListFileContext::FromListFileFunction( - lff, this->Makefile->StateSnapshot.GetExecutionListFile(), - std::move(deferId)); - this->Makefile->Backtrace = this->Makefile->Backtrace.Push(lfc); - ++this->Makefile->RecursionDepth; - this->Makefile->ExecutionStatusStack.push_back(&status); #if !defined(CMAKE_BOOTSTRAP) this->ProfilingDataRAII = this->Makefile->GetCMakeInstance()->CreateProfilingEntry( @@ -440,28 +479,25 @@ public: #endif } - ~cmMakefileCall() + ~CallScope() { #if !defined(CMAKE_BOOTSTRAP) this->ProfilingDataRAII.reset(); #endif - this->Makefile->ExecutionStatusStack.pop_back(); - --this->Makefile->RecursionDepth; - this->Makefile->Backtrace = this->Makefile->Backtrace.Pop(); + auto* const mf = this->Detach(); #ifdef CMake_ENABLE_DEBUGGER - if (this->Makefile->GetCMakeInstance()->GetDebugAdapter()) { - this->Makefile->GetCMakeInstance() - ->GetDebugAdapter() - ->OnEndFunctionCall(); + if (mf->GetCMakeInstance()->GetDebugAdapter()) { + mf->GetCMakeInstance()->GetDebugAdapter()->OnEndFunctionCall(); } +#else + static_cast(mf); #endif } - cmMakefileCall(const cmMakefileCall&) = delete; - cmMakefileCall& operator=(const cmMakefileCall&) = delete; + CallScope(const CallScope&) = delete; + CallScope& operator=(const CallScope&) = delete; private: - cmMakefile* Makefile; #if !defined(CMAKE_BOOTSTRAP) cm::optional ProfilingDataRAII; #endif @@ -485,7 +521,7 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff, } // Place this call on the call stack. - cmMakefileCall stack_manager(this, lff, std::move(deferId), status); + CallScope stack_manager(this, lff, std::move(deferId), status); static_cast(stack_manager); // Check for maximum recursion depth. diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index de22227510..620917f2c4 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -1072,6 +1072,25 @@ public: DebugFindPkgRAII& operator=(DebugFindPkgRAII const&) = delete; }; + class CallRAII + { + public: + CallRAII(cmMakefile* mf, std::string const& file, + cmExecutionStatus& status); + ~CallRAII(); + + CallRAII(CallRAII const&) = delete; + CallRAII& operator=(CallRAII const&) = delete; + + protected: + CallRAII(cmMakefile* mf, cmListFileContext const& lfc, + cmExecutionStatus& status); + + cmMakefile* Detach(); + + cmMakefile* Makefile; + }; + bool GetDebugFindPkgMode() const; void MaybeWarnCMP0074(std::string const& rootVar, cmValue rootDef, @@ -1201,8 +1220,10 @@ private: std::vector> EvaluationFiles; + class CallScope; + friend class CallScope; + std::vector ExecutionStatusStack; - friend class cmMakefileCall; friend class cmParseFileScope; std::vector> ImportedTargetsOwned;