From 11cc728e75d2c215abdb2e402aa50f415060fef3 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 30 Mar 2022 16:35:23 -0400 Subject: cmConstStack: Factor out of cmListFileBacktrace This presents value semantics for a stack of constant values. Internally it shares ownership to avoid copies. Previously this was implemented by `cmListFileBacktrace` explicitly, but the approach can be re-used for other kinds of stacks. --- .gitattributes | 1 + Source/CMakeLists.txt | 2 + Source/cmComputeTargetDepends.h | 2 +- Source/cmConstStack.h | 39 ++++++++++++++ Source/cmConstStack.tcc | 62 ++++++++++++++++++++++ Source/cmFLTKWrapUICommand.cxx | 2 +- Source/cmInstallCommand.cxx | 3 +- Source/cmInstallDirectoryGenerator.cxx | 1 + Source/cmInstallDirectoryGenerator.h | 2 +- Source/cmInstallExportGenerator.cxx | 1 + Source/cmInstallExportGenerator.h | 2 +- Source/cmInstallFileSetGenerator.cxx | 1 + Source/cmInstallFileSetGenerator.h | 2 +- Source/cmInstallFilesGenerator.cxx | 1 + Source/cmInstallFilesGenerator.h | 2 +- .../cmInstallGetRuntimeDependenciesGenerator.cxx | 1 + Source/cmInstallGetRuntimeDependenciesGenerator.h | 2 +- Source/cmInstallRuntimeDependencySetGenerator.h | 2 +- Source/cmInstallSubdirectoryGenerator.cxx | 1 + Source/cmInstallSubdirectoryGenerator.h | 2 +- Source/cmListFileCache.cxx | 51 ++---------------- Source/cmListFileCache.h | 34 +++--------- Source/cmLocalNinjaGenerator.h | 2 +- Source/cmState.h | 6 ++- Source/cmStateDirectory.cxx | 1 + Source/cmStateDirectory.h | 5 +- Utilities/IWYU/mapping.imp | 3 ++ 27 files changed, 146 insertions(+), 87 deletions(-) create mode 100644 Source/cmConstStack.h create mode 100644 Source/cmConstStack.tcc diff --git a/.gitattributes b/.gitattributes index 79a0f04..71ecacf 100644 --- a/.gitattributes +++ b/.gitattributes @@ -36,6 +36,7 @@ configure eol=lf *.hpp our-c-style *.hxx our-c-style *.notcu our-c-style +*.tcc our-c-style *.cmake whitespace=tab-in-indent *.rst whitespace=tab-in-indent conflict-marker-size=79 diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index d6e0096..7661235 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -182,6 +182,8 @@ set(SRCS cmComputeTargetDepends.cxx cmConsoleBuf.h cmConsoleBuf.cxx + cmConstStack.h + cmConstStack.tcc cmCPackPropertiesGenerator.h cmCPackPropertiesGenerator.cxx cmCryptoHash.cxx diff --git a/Source/cmComputeTargetDepends.h b/Source/cmComputeTargetDepends.h index 0eab368..cdb66f8 100644 --- a/Source/cmComputeTargetDepends.h +++ b/Source/cmComputeTargetDepends.h @@ -10,12 +10,12 @@ #include #include "cmGraphAdjacencyList.h" -#include "cmListFileCache.h" class cmComputeComponentGraph; class cmGeneratorTarget; class cmGlobalGenerator; class cmLinkItem; +class cmListFileBacktrace; class cmSourceFile; class cmTargetDependSet; diff --git a/Source/cmConstStack.h b/Source/cmConstStack.h new file mode 100644 index 0000000..f0bca32 --- /dev/null +++ b/Source/cmConstStack.h @@ -0,0 +1,39 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#pragma once + +#include "cmConfigure.h" // IWYU pragma: keep + +#include + +/** Base class template for CRTP to represent a stack of constant values. + Provide value semantics, but use efficient reference-counting underneath + to avoid copies. */ +template +class cmConstStack +{ + struct Entry; + std::shared_ptr TopEntry; + +public: + /** Default-construct an empty stack. */ + cmConstStack(); + + /** Get a stack with the given call context added to the top. */ + Stack Push(T value) const; + + /** Get a stack with the top level removed. + May not be called until after a matching Push. */ + Stack Pop() const; + + /** Get the value at the top of the stack. + This may be called only if Empty() would return false. */ + T const& Top() const; + + /** Return true if this stack is empty. */ + bool Empty() const; + +protected: + cmConstStack(std::shared_ptr parent, T value); + cmConstStack(std::shared_ptr top); +}; diff --git a/Source/cmConstStack.tcc b/Source/cmConstStack.tcc new file mode 100644 index 0000000..81918ee --- /dev/null +++ b/Source/cmConstStack.tcc @@ -0,0 +1,62 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#include +#include +#include + +template +struct cmConstStack::Entry +{ + Entry(std::shared_ptr parent, T value) + : Value(std::move(value)) + , Parent(std::move(parent)) + { + } + + T Value; + std::shared_ptr Parent; +}; + +template +cmConstStack::cmConstStack() = default; + +template +Stack cmConstStack::Push(T value) const +{ + return Stack(this->TopEntry, std::move(value)); +} + +template +Stack cmConstStack::Pop() const +{ + assert(this->TopEntry); + return Stack(this->TopEntry->Parent); +} + +template +T const& cmConstStack::Top() const +{ + assert(this->TopEntry); + return this->TopEntry->Value; +} + +template +bool cmConstStack::Empty() const +{ + return !this->TopEntry; +} + +template +cmConstStack::cmConstStack(std::shared_ptr parent, + T value) + : TopEntry( + std::make_shared(std::move(parent), std::move(value))) +{ +} + +template +cmConstStack::cmConstStack(std::shared_ptr top) + : TopEntry(std::move(top)) +{ +} diff --git a/Source/cmFLTKWrapUICommand.cxx b/Source/cmFLTKWrapUICommand.cxx index 80c069f..373a3cf 100644 --- a/Source/cmFLTKWrapUICommand.cxx +++ b/Source/cmFLTKWrapUICommand.cxx @@ -10,7 +10,6 @@ #include "cmCustomCommand.h" #include "cmCustomCommandLines.h" #include "cmExecutionStatus.h" -#include "cmListFileCache.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmMessageType.h" @@ -20,6 +19,7 @@ #include "cmSystemTools.h" #include "cmake.h" +class cmListFileBacktrace; class cmTarget; static void FinalAction(cmMakefile& makefile, std::string const& name, diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index 8ce7ed1..1ed698d 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -35,7 +35,6 @@ #include "cmInstallRuntimeDependencySetGenerator.h" #include "cmInstallScriptGenerator.h" #include "cmInstallTargetGenerator.h" -#include "cmListFileCache.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmPolicies.h" @@ -49,6 +48,8 @@ #include "cmTargetExport.h" #include "cmValue.h" +class cmListFileBacktrace; + namespace { struct RuntimeDependenciesArgs diff --git a/Source/cmInstallDirectoryGenerator.cxx b/Source/cmInstallDirectoryGenerator.cxx index 86362e4..8462b99 100644 --- a/Source/cmInstallDirectoryGenerator.cxx +++ b/Source/cmInstallDirectoryGenerator.cxx @@ -6,6 +6,7 @@ #include "cmGeneratorExpression.h" #include "cmInstallType.h" +#include "cmListFileCache.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmStringAlgorithms.h" diff --git a/Source/cmInstallDirectoryGenerator.h b/Source/cmInstallDirectoryGenerator.h index 0f91a59..419fd8c 100644 --- a/Source/cmInstallDirectoryGenerator.h +++ b/Source/cmInstallDirectoryGenerator.h @@ -9,9 +9,9 @@ #include #include "cmInstallGenerator.h" -#include "cmListFileCache.h" #include "cmScriptGenerator.h" +class cmListFileBacktrace; class cmLocalGenerator; /** \class cmInstallDirectoryGenerator diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx index 820f24a..627f59d 100644 --- a/Source/cmInstallExportGenerator.cxx +++ b/Source/cmInstallExportGenerator.cxx @@ -15,6 +15,7 @@ #include "cmExportInstallFileGenerator.h" #include "cmExportSet.h" #include "cmInstallType.h" +#include "cmListFileCache.h" #include "cmLocalGenerator.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" diff --git a/Source/cmInstallExportGenerator.h b/Source/cmInstallExportGenerator.h index efeae86..54c59f1 100644 --- a/Source/cmInstallExportGenerator.h +++ b/Source/cmInstallExportGenerator.h @@ -11,11 +11,11 @@ #include #include "cmInstallGenerator.h" -#include "cmListFileCache.h" #include "cmScriptGenerator.h" class cmExportInstallFileGenerator; class cmExportSet; +class cmListFileBacktrace; class cmLocalGenerator; /** \class cmInstallExportGenerator diff --git a/Source/cmInstallFileSetGenerator.cxx b/Source/cmInstallFileSetGenerator.cxx index 7121ea3..8c37312 100644 --- a/Source/cmInstallFileSetGenerator.cxx +++ b/Source/cmInstallFileSetGenerator.cxx @@ -11,6 +11,7 @@ #include "cmGeneratorExpression.h" #include "cmGlobalGenerator.h" #include "cmInstallType.h" +#include "cmListFileCache.h" #include "cmLocalGenerator.h" #include "cmStringAlgorithms.h" diff --git a/Source/cmInstallFileSetGenerator.h b/Source/cmInstallFileSetGenerator.h index 8d067d9..56341d4 100644 --- a/Source/cmInstallFileSetGenerator.h +++ b/Source/cmInstallFileSetGenerator.h @@ -8,11 +8,11 @@ #include #include "cmInstallGenerator.h" -#include "cmListFileCache.h" #include "cmScriptGenerator.h" class cmGeneratorTarget; class cmFileSet; +class cmListFileBacktrace; class cmLocalGenerator; class cmInstallFileSetGenerator : public cmInstallGenerator diff --git a/Source/cmInstallFilesGenerator.cxx b/Source/cmInstallFilesGenerator.cxx index 04aaa29..378b9fc 100644 --- a/Source/cmInstallFilesGenerator.cxx +++ b/Source/cmInstallFilesGenerator.cxx @@ -6,6 +6,7 @@ #include "cmGeneratorExpression.h" #include "cmInstallType.h" +#include "cmListFileCache.h" #include "cmStringAlgorithms.h" class cmLocalGenerator; diff --git a/Source/cmInstallFilesGenerator.h b/Source/cmInstallFilesGenerator.h index af7f113..2276ab8 100644 --- a/Source/cmInstallFilesGenerator.h +++ b/Source/cmInstallFilesGenerator.h @@ -9,9 +9,9 @@ #include #include "cmInstallGenerator.h" -#include "cmListFileCache.h" #include "cmScriptGenerator.h" +class cmListFileBacktrace; class cmLocalGenerator; /** \class cmInstallFilesGenerator diff --git a/Source/cmInstallGetRuntimeDependenciesGenerator.cxx b/Source/cmInstallGetRuntimeDependenciesGenerator.cxx index 4d585ce..3e493bc 100644 --- a/Source/cmInstallGetRuntimeDependenciesGenerator.cxx +++ b/Source/cmInstallGetRuntimeDependenciesGenerator.cxx @@ -15,6 +15,7 @@ #include "cmGeneratorExpression.h" #include "cmInstallRuntimeDependencySet.h" +#include "cmListFileCache.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmOutputConverter.h" diff --git a/Source/cmInstallGetRuntimeDependenciesGenerator.h b/Source/cmInstallGetRuntimeDependenciesGenerator.h index 19f6cc6..a2d6593 100644 --- a/Source/cmInstallGetRuntimeDependenciesGenerator.h +++ b/Source/cmInstallGetRuntimeDependenciesGenerator.h @@ -7,9 +7,9 @@ #include #include "cmInstallGenerator.h" -#include "cmListFileCache.h" #include "cmScriptGenerator.h" +class cmListFileBacktrace; class cmLocalGenerator; class cmInstallRuntimeDependencySet; diff --git a/Source/cmInstallRuntimeDependencySetGenerator.h b/Source/cmInstallRuntimeDependencySetGenerator.h index 8e98b57..680361b 100644 --- a/Source/cmInstallRuntimeDependencySetGenerator.h +++ b/Source/cmInstallRuntimeDependencySetGenerator.h @@ -7,10 +7,10 @@ #include #include "cmInstallGenerator.h" -#include "cmListFileCache.h" #include "cmScriptGenerator.h" class cmInstallRuntimeDependencySet; +class cmListFileBacktrace; class cmLocalGenerator; class cmInstallRuntimeDependencySetGenerator : public cmInstallGenerator diff --git a/Source/cmInstallSubdirectoryGenerator.cxx b/Source/cmInstallSubdirectoryGenerator.cxx index 0a8e065..dd71332 100644 --- a/Source/cmInstallSubdirectoryGenerator.cxx +++ b/Source/cmInstallSubdirectoryGenerator.cxx @@ -7,6 +7,7 @@ #include #include +#include "cmListFileCache.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmPolicies.h" diff --git a/Source/cmInstallSubdirectoryGenerator.h b/Source/cmInstallSubdirectoryGenerator.h index f174d07..7a472ed 100644 --- a/Source/cmInstallSubdirectoryGenerator.h +++ b/Source/cmInstallSubdirectoryGenerator.h @@ -8,8 +8,8 @@ #include #include "cmInstallGenerator.h" -#include "cmListFileCache.h" +class cmListFileBacktrace; class cmLocalGenerator; class cmMakefile; diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx index 941d283..5133521 100644 --- a/Source/cmListFileCache.cxx +++ b/Source/cmListFileCache.cxx @@ -1,8 +1,8 @@ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ +#define cmListFileCache_cxx #include "cmListFileCache.h" -#include #include #include #include @@ -445,53 +445,8 @@ cm::optional cmListFileParser::CheckNesting() const return cm::nullopt; } -// We hold a call/file context. -struct cmListFileBacktrace::Entry -{ - Entry(std::shared_ptr parent, cmListFileContext lfc) - : Context(std::move(lfc)) - , Parent(std::move(parent)) - { - } - - cmListFileContext Context; - std::shared_ptr Parent; -}; - -/* NOLINTNEXTLINE(performance-unnecessary-value-param) */ -cmListFileBacktrace::cmListFileBacktrace(std::shared_ptr parent, - cmListFileContext const& lfc) - : TopEntry(std::make_shared(std::move(parent), lfc)) -{ -} - -cmListFileBacktrace::cmListFileBacktrace(std::shared_ptr top) - : TopEntry(std::move(top)) -{ -} - -cmListFileBacktrace cmListFileBacktrace::Push( - cmListFileContext const& lfc) const -{ - return cmListFileBacktrace(this->TopEntry, lfc); -} - -cmListFileBacktrace cmListFileBacktrace::Pop() const -{ - assert(this->TopEntry); - return cmListFileBacktrace(this->TopEntry->Parent); -} - -cmListFileContext const& cmListFileBacktrace::Top() const -{ - assert(this->TopEntry); - return this->TopEntry->Context; -} - -bool cmListFileBacktrace::Empty() const -{ - return !this->TopEntry; -} +#include "cmConstStack.tcc" +template class cmConstStack; std::ostream& operator<<(std::ostream& os, cmListFileContext const& lfc) { diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h index 7c19f24..f7c2509 100644 --- a/Source/cmListFileCache.h +++ b/Source/cmListFileCache.h @@ -12,6 +12,7 @@ #include +#include "cmConstStack.h" #include "cmSystemTools.h" /** \class cmListFileCache @@ -157,35 +158,16 @@ bool operator<(const cmListFileContext& lhs, const cmListFileContext& rhs); bool operator==(cmListFileContext const& lhs, cmListFileContext const& rhs); bool operator!=(cmListFileContext const& lhs, cmListFileContext const& rhs); -// Represent a backtrace (call stack). Provide value semantics -// but use efficient reference-counting underneath to avoid copies. +// Represent a backtrace (call stack) with efficient value semantics. class cmListFileBacktrace + : public cmConstStack { -public: - // Default-constructed backtrace is empty. - cmListFileBacktrace() = default; - - // Get a backtrace with the given call context added to the top. - cmListFileBacktrace Push(cmListFileContext const& lfc) const; - - // Get a backtrace with the top level removed. - // May not be called until after a matching Push. - cmListFileBacktrace Pop() const; - - // Get the context at the top of the backtrace. - // This may be called only if Empty() would return false. - cmListFileContext const& Top() const; - - // Return true if this backtrace is empty. - bool Empty() const; - -private: - struct Entry; - std::shared_ptr TopEntry; - cmListFileBacktrace(std::shared_ptr parent, - cmListFileContext const& lfc); - cmListFileBacktrace(std::shared_ptr top); + using cmConstStack::cmConstStack; + friend class cmConstStack; }; +#ifndef cmListFileCache_cxx +extern template class cmConstStack; +#endif // Wrap type T as a value with a backtrace. For purposes of // ordering and equality comparison, only the original value is diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h index 3118bb4..4d393d9 100644 --- a/Source/cmLocalNinjaGenerator.h +++ b/Source/cmLocalNinjaGenerator.h @@ -10,7 +10,6 @@ #include #include -#include "cmListFileCache.h" #include "cmLocalCommonGenerator.h" #include "cmNinjaTypes.h" #include "cmOutputConverter.h" @@ -21,6 +20,7 @@ class cmGeneratedFileStream; class cmGeneratorTarget; class cmGlobalGenerator; class cmGlobalNinjaGenerator; +class cmListFileBacktrace; class cmMakefile; class cmRulePlaceholderExpander; class cmake; diff --git a/Source/cmState.h b/Source/cmState.h index 4f2b7df..ee133fc 100644 --- a/Source/cmState.h +++ b/Source/cmState.h @@ -14,7 +14,6 @@ #include "cmDefinitions.h" #include "cmLinkedTree.h" -#include "cmListFileCache.h" #include "cmPolicies.h" #include "cmProperty.h" #include "cmPropertyDefinition.h" @@ -30,6 +29,11 @@ class cmMakefile; class cmStateSnapshot; class cmMessenger; class cmExecutionStatus; +class cmListFileBacktrace; +struct cmListFileArgument; + +template +class BT; class cmState { diff --git a/Source/cmStateDirectory.cxx b/Source/cmStateDirectory.cxx index b42e5c3..20e4604 100644 --- a/Source/cmStateDirectory.cxx +++ b/Source/cmStateDirectory.cxx @@ -13,6 +13,7 @@ #include #include "cmAlgorithms.h" +#include "cmListFileCache.h" #include "cmProperty.h" #include "cmPropertyMap.h" #include "cmRange.h" diff --git a/Source/cmStateDirectory.h b/Source/cmStateDirectory.h index 6429f32..8c6b09d 100644 --- a/Source/cmStateDirectory.h +++ b/Source/cmStateDirectory.h @@ -10,11 +10,14 @@ #include "cmAlgorithms.h" #include "cmLinkedTree.h" -#include "cmListFileCache.h" #include "cmStatePrivate.h" #include "cmStateSnapshot.h" #include "cmValue.h" +class cmListFileBacktrace; +template +class BT; + class cmStateDirectory { cmStateDirectory( diff --git a/Utilities/IWYU/mapping.imp b/Utilities/IWYU/mapping.imp index 8c55c85..b80fc22 100644 --- a/Utilities/IWYU/mapping.imp +++ b/Utilities/IWYU/mapping.imp @@ -131,6 +131,9 @@ { include: [ "", private, "\"cmCursesStandardIncludes.h\"", public ] }, { include: [ "\"form.h\"", private, "\"cmCursesStandardIncludes.h\"", public ] }, { include: [ "", private, "\"cmCursesStandardIncludes.h\"", public ] }, + + # Help IWYU understand our explicit instantiation for cmConstStack. + { symbol: [ "cmConstStack::cmConstStack", private, "\"cmConstStack.h\"", public ] }, ] # vim: set ft=toml: -- cgit v0.12