Browse Source

cmListFileBacktrace: Implement in terms of cmState::Snapshot.

Avoid copying many strings into each backtrace object.
Stephen Kelly 10 years ago
parent
commit
d2475bb5c4
5 changed files with 37 additions and 52 deletions
  1. 1 4
      Source/cmIfCommand.cxx
  2. 24 14
      Source/cmListFileCache.cxx
  3. 5 5
      Source/cmListFileCache.h
  4. 6 28
      Source/cmMakefile.cxx
  5. 1 1
      Source/cmMakefile.h

+ 1 - 4
Source/cmIfCommand.cxx

@@ -115,10 +115,7 @@ IsFunctionBlocked(const cmListFileFunction& lff,
               {
               std::string err = cmIfCommandError(expandedArguments);
               err += errorString;
-              cmListFileContext lfc =
-                  cmListFileContext::FromCommandContext(
-                    this->Functions[c], this->GetStartingContext().FilePath);
-              cmListFileBacktrace bt = mf.GetBacktrace(lfc);
+              cmListFileBacktrace bt = mf.GetBacktrace(this->Functions[c]);
               mf.GetCMakeInstance()->IssueMessage(messType, err, bt);
               if (messType == cmake::FATAL_ERROR)
                 {

+ 24 - 14
Source/cmListFileCache.cxx

@@ -398,40 +398,50 @@ bool cmListFileParser::AddArgument(cmListFileLexer_Token* token,
     }
 }
 
-void cmListFileBacktrace::Append(cmListFileContext const& context)
-{
-  this->push_back(context);
-}
-
 void cmListFileBacktrace::PrintTitle(std::ostream& out)
 {
-  if (this->empty())
+  if (!this->Snapshot.IsValid())
     {
     return;
     }
-
   cmOutputConverter converter(this->Snapshot);
-  cmListFileContext lfc = this->front();
+  cmListFileContext lfc =
+      cmListFileContext::FromCommandContext(
+        this->Context, this->Snapshot.GetExecutionListFile());
   lfc.FilePath = converter.Convert(lfc.FilePath, cmOutputConverter::HOME);
   out << (lfc.Line ? " at " : " in ") << lfc;
 }
 
 void cmListFileBacktrace::PrintCallStack(std::ostream& out)
 {
-  if (size() <= 1)
+  if (!this->Snapshot.IsValid())
+    {
+    return;
+    }
+  cmState::Snapshot parent = this->Snapshot.GetCallStackParent();
+  if (!parent.IsValid() || parent.GetExecutionListFile().empty())
     {
     return;
     }
 
   cmOutputConverter converter(this->Snapshot);
-  const_iterator i = this->begin() + 1;
+  std::string commandName = this->Snapshot.GetEntryPointCommand();
+  long commandLine = this->Snapshot.GetEntryPointLine();
+
   out << "Call Stack (most recent call first):\n";
-  while(i != this->end())
+  while(parent.IsValid())
     {
-    cmListFileContext lfc = *i;
-    lfc.FilePath = converter.Convert(lfc.FilePath, cmOutputConverter::HOME);
+    cmListFileContext lfc;
+    lfc.Name = commandName;
+    lfc.Line = commandLine;
+
+    lfc.FilePath = converter.Convert(parent.GetExecutionListFile(),
+                                     cmOutputConverter::HOME);
     out << "  " << lfc << "\n";
-    ++i;
+
+    commandName = parent.GetEntryPointCommand();
+    commandLine = parent.GetEntryPointLine();
+    parent = parent.GetCallStackParent();
     }
 }
 

+ 5 - 5
Source/cmListFileCache.h

@@ -86,19 +86,19 @@ struct cmListFileFunction: public cmCommandContext
   std::vector<cmListFileArgument> Arguments;
 };
 
-class cmListFileBacktrace: private std::vector<cmListFileContext>
+class cmListFileBacktrace
 {
   public:
-    cmListFileBacktrace(cmState::Snapshot snapshot = cmState::Snapshot())
-      : Snapshot(snapshot)
+    cmListFileBacktrace(cmState::Snapshot snapshot = cmState::Snapshot(),
+                        cmCommandContext const& cc = cmCommandContext())
+      : Context(cc), Snapshot(snapshot)
     {
     }
 
-    void Append(cmListFileContext const& context);
-
     void PrintTitle(std::ostream& out);
     void PrintCallStack(std::ostream& out);
   private:
+    cmCommandContext Context;
     cmState::Snapshot Snapshot;
 };
 

+ 6 - 28
Source/cmMakefile.cxx

@@ -275,43 +275,21 @@ void cmMakefile::IssueMessage(cmake::MessageType t,
 //----------------------------------------------------------------------------
 cmListFileBacktrace cmMakefile::GetBacktrace() const
 {
-  cmListFileBacktrace backtrace(this->StateSnapshot);
-  cmState::Snapshot snp = this->StateSnapshot;
-  for(std::vector<cmCommandContext const*>::const_reverse_iterator
-      i = this->ContextStack.rbegin();
-      i != this->ContextStack.rend();
-      ++i, snp = snp.GetCallStackParent())
+  cmListFileBacktrace backtrace;
+  if (!this->ContextStack.empty())
     {
-    assert(snp.IsValid());
-    cmListFileContext frame =
-        cmListFileContext::FromCommandContext(*(*i),
-                                              snp.GetExecutionListFile());
-    backtrace.Append(frame);
+    backtrace = cmListFileBacktrace(this->StateSnapshot,
+                                    *this->ContextStack.back());
     }
   return backtrace;
 }
 
 //----------------------------------------------------------------------------
 cmListFileBacktrace
-cmMakefile::GetBacktrace(cmListFileContext const& lfc) const
+cmMakefile::GetBacktrace(cmCommandContext const& cc) const
 {
-  cmListFileBacktrace backtrace(this->StateSnapshot);
-  backtrace.Append(lfc);
   cmState::Snapshot snp = this->StateSnapshot;
-  assert(snp.GetExecutionListFile() == lfc.FilePath);
-  snp = snp.GetCallStackParent();
-  for(std::vector<cmCommandContext const*>::const_reverse_iterator
-      i = this->ContextStack.rbegin();
-      i != this->ContextStack.rend();
-      ++i, snp = snp.GetCallStackParent())
-    {
-    assert(snp.IsValid());
-    cmListFileContext frame =
-        cmListFileContext::FromCommandContext(*(*i),
-                                              snp.GetExecutionListFile());
-    backtrace.Append(frame);
-    }
-  return backtrace;
+  return cmListFileBacktrace(snp, cc);
 }
 
 //----------------------------------------------------------------------------

+ 1 - 1
Source/cmMakefile.h

@@ -547,7 +547,7 @@ public:
    * Get the current context backtrace.
    */
   cmListFileBacktrace GetBacktrace() const;
-  cmListFileBacktrace GetBacktrace(cmListFileContext const& lfc) const;
+  cmListFileBacktrace GetBacktrace(cmCommandContext const& lfc) const;
   cmListFileContext GetExecutionContext() const;
 
   /**