CMake/Source/cmListFileCache.h

170 lines
4.4 KiB
C
Raw Normal View History

/*============================================================================
CMake - Cross Platform Makefile Generator
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
Distributed under the OSI-approved BSD License (the "License");
see accompanying file Copyright.txt for details.
This software is distributed WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
#ifndef cmListFileCache_h
#define cmListFileCache_h
#include <cmConfigure.h>
#include "cmStandardIncludes.h"
#include "cmState.h"
/** \class cmListFileCache
* \brief A class to cache list file contents.
*
* cmListFileCache is a class used to cache the contents of parsed
* cmake list files.
*/
class cmMessenger;
struct cmCommandContext
{
std::string Name;
long Line;
cmCommandContext()
: Name()
, Line(0)
{
}
};
struct cmListFileArgument
{
enum Delimiter
{
Unquoted,
Quoted,
Bracket
};
cmListFileArgument()
: Value()
, Delim(Unquoted)
, Line(0)
{
}
cmListFileArgument(const cmListFileArgument& r)
: Value(r.Value)
, Delim(r.Delim)
, Line(r.Line)
{
}
cmListFileArgument(const std::string& v, Delimiter d, long line)
: Value(v)
, Delim(d)
, Line(line)
{
}
bool operator==(const cmListFileArgument& r) const
{
return (this->Value == r.Value) && (this->Delim == r.Delim);
}
bool operator!=(const cmListFileArgument& r) const { return !(*this == r); }
std::string Value;
Delimiter Delim;
long Line;
};
class cmListFileContext
{
public:
2006-03-15 19:02:08 +03:00
std::string Name;
std::string FilePath;
2006-03-15 19:02:08 +03:00
long Line;
cmListFileContext()
: Name()
, FilePath()
, Line(0)
{
}
static cmListFileContext FromCommandContext(cmCommandContext const& lfcc,
std::string const& fileName)
{
cmListFileContext lfc;
lfc.FilePath = fileName;
lfc.Line = lfcc.Line;
lfc.Name = lfcc.Name;
return lfc;
}
};
std::ostream& operator<<(std::ostream&, cmListFileContext const&);
bool operator<(const cmListFileContext& lhs, const cmListFileContext& rhs);
bool operator==(cmListFileContext const& lhs, cmListFileContext const& rhs);
bool operator!=(cmListFileContext const& lhs, cmListFileContext const& rhs);
struct cmListFileFunction : public cmCommandContext
{
std::vector<cmListFileArgument> Arguments;
};
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.
2016-04-14 18:24:08 +03:00
// Represent a backtrace (call stack). Provide value semantics
// but use efficient reference-counting underneath to avoid copies.
class cmListFileBacktrace
{
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.
2016-04-14 18:24:08 +03:00
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;
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.
2016-04-14 18:24:08 +03:00
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
{
bool ParseFile(const char* path, cmMessenger* messenger,
cmListFileBacktrace const& lfbt);
2006-03-15 19:02:08 +03:00
std::vector<cmListFileFunction> Functions;
};
#endif