diff options
author | Brad King <brad.king@kitware.com> | 2016-04-14 15:24:08 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2016-04-18 13:21:19 (GMT) |
commit | 7c36d2067b00996fcead56310f4fc4fa58434247 (patch) | |
tree | 6f0b8771c11e3cb6b20e91680b0b17114c52bb06 /Source/cmListFileCache.h | |
parent | 1f6bd8a93f602f9d4dde1c3ea697211897f25827 (diff) | |
download | CMake-7c36d2067b00996fcead56310f4fc4fa58434247.zip CMake-7c36d2067b00996fcead56310f4fc4fa58434247.tar.gz CMake-7c36d2067b00996fcead56310f4fc4fa58434247.tar.bz2 |
cmListFileBacktrace: Refactor storage to provide efficient value semantics
Since commit v3.4.0-rc1~321^2~2 (Genex: Store a backtrace, not a pointer
to one, 2015-07-08) we treat cmListFileBacktrace instances as
lightweight values. This was true at the time only because the
backtrace information was kept in the cmState snapshot hierarchy.
However, that forced us to accumulate a lot of otherwise short-lived
snapshots just to have the backtrace fields available for reference by
cmListFileBacktrace instances. Recent refactoring made backtrace
instances independent of the snapshot hierarchy to avoid accumulating
short-lived snapshots. This came at the cost of making backtrace values
heavy again, leading to lots of string coying and slower execution.
Fix this by refactoring cmListFileBacktrace to provide value semantics
with efficient shared storage underneath. Teach cmMakefile to maintain
its call stack using an instance of cmListFileBacktrace. This approach
allows the current backtrace to be efficiently saved whenever it is
needed.
Also teach cmListFileBacktrace the notion of a file-level scope. This
is useful for messages about the whole file (e.g. during parsing) that
are not specific to any line within it. Push the CMakeLists.txt scope
for each directory and never pop it. This ensures that we always have
some context information and simplifies cmMakefile::IssueMessage.
Push/pop a file-level scope as each included file is processed. This
supersedes cmParseFileScope and improves diagnostic message context
information in a few places. Fix the corresponding test cases to expect
the improved output.
Diffstat (limited to 'Source/cmListFileCache.h')
-rw-r--r-- | Source/cmListFileCache.h | 56 |
1 files changed, 46 insertions, 10 deletions
diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h index d3cab22..9fa8585 100644 --- a/Source/cmListFileCache.h +++ b/Source/cmListFileCache.h @@ -87,17 +87,53 @@ struct cmListFileFunction: public cmCommandContext std::vector<cmListFileArgument> Arguments; }; -class cmListFileBacktrace: private std::vector<cmListFileContext> +// Represent a backtrace (call stack). Provide value semantics +// but use efficient reference-counting underneath to avoid copies. +class cmListFileBacktrace { - public: - cmListFileBacktrace(cmState::Snapshot snapshot = cmState::Snapshot(), - cmCommandContext const& cc = cmCommandContext()); - ~cmListFileBacktrace(); - - void PrintTitle(std::ostream& out) const; - void PrintCallStack(std::ostream& out) const; - private: - cmState::Snapshot Snapshot; +public: + // Default-constructed backtrace may not be used until after + // set via assignment from a backtrace constructed with a + // valid snapshot. + cmListFileBacktrace(); + + // Construct an empty backtrace whose bottom sits in the directory + // indicated by the given valid snapshot. + cmListFileBacktrace(cmState::Snapshot snapshot); + + // Backtraces may be copied and assigned as values. + cmListFileBacktrace(cmListFileBacktrace const& r); + cmListFileBacktrace& operator=(cmListFileBacktrace const& r); + ~cmListFileBacktrace(); + + // Get a backtrace with the given file scope added to the top. + // May not be called until after construction with a valid snapshot. + cmListFileBacktrace Push(std::string const& file) const; + + // Get a backtrace with the given call context added to the top. + // May not be called until after construction with a valid snapshot. + 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. + // Returns an empty context if the backtrace is empty. + cmListFileContext const& Top() const; + + // Print the top of the backtrace. + void PrintTitle(std::ostream& out) const; + + // Print the call stack below the top of the backtrace. + void PrintCallStack(std::ostream& out) const; +private: + struct Entry; + cmState::Snapshot Bottom; + Entry* Cur; + cmListFileBacktrace(cmState::Snapshot bottom, Entry* up, + cmListFileContext const& lfc); + cmListFileBacktrace(cmState::Snapshot bottom, Entry* cur); }; struct cmListFile |