Browse Source

if,while: Clarify condition backtrace construction

Evaluation of the `elseif`, `else`, and `while` commands takes place
during function blocker evaluation before any actual command execution
takes place.  Therefore they do not have an entry in the backtrace
stack.  Each of their implementations needs to construct an extra
backtrace entry to use in error messages and such.  Each of them used a
slightly different approach due to evolution over time.  Clean up their
construction of the extra backtrace entry and use a named variable to
contain it for clarity.
Brad King 5 years ago
parent
commit
dc49abcb89
2 changed files with 14 additions and 15 deletions
  1. 9 7
      Source/cmIfCommand.cxx
  2. 5 8
      Source/cmWhileCommand.cxx

+ 9 - 7
Source/cmIfCommand.cxx

@@ -75,10 +75,12 @@ bool cmIfFunctionBlocker::Replay(std::vector<cmListFileFunction> functions,
     if (scopeDepth == 0 && func.Name.Lower == "else") {
     if (scopeDepth == 0 && func.Name.Lower == "else") {
 
 
       if (this->ElseSeen) {
       if (this->ElseSeen) {
-        cmListFileBacktrace bt = mf.GetBacktrace(func);
+        cmListFileBacktrace elseBT = mf.GetBacktrace().Push(
+          cmListFileContext{ func.Name.Original,
+                             this->GetStartingContext().FilePath, func.Line });
         mf.GetCMakeInstance()->IssueMessage(
         mf.GetCMakeInstance()->IssueMessage(
           MessageType::FATAL_ERROR,
           MessageType::FATAL_ERROR,
-          "A duplicate ELSE command was found inside an IF block.", bt);
+          "A duplicate ELSE command was found inside an IF block.", elseBT);
         cmSystemTools::SetFatalErrorOccured();
         cmSystemTools::SetFatalErrorOccured();
         return true;
         return true;
       }
       }
@@ -93,11 +95,12 @@ bool cmIfFunctionBlocker::Replay(std::vector<cmListFileFunction> functions,
         mf.PrintCommandTrace(func);
         mf.PrintCommandTrace(func);
       }
       }
     } else if (scopeDepth == 0 && func.Name.Lower == "elseif") {
     } else if (scopeDepth == 0 && func.Name.Lower == "elseif") {
+      cmListFileBacktrace elseifBT = mf.GetBacktrace().Push(cmListFileContext{
+        func.Name.Original, this->GetStartingContext().FilePath, func.Line });
       if (this->ElseSeen) {
       if (this->ElseSeen) {
-        cmListFileBacktrace bt = mf.GetBacktrace(func);
         mf.GetCMakeInstance()->IssueMessage(
         mf.GetCMakeInstance()->IssueMessage(
           MessageType::FATAL_ERROR,
           MessageType::FATAL_ERROR,
-          "An ELSEIF command was found after an ELSE command.", bt);
+          "An ELSEIF command was found after an ELSE command.", elseifBT);
         cmSystemTools::SetFatalErrorOccured();
         cmSystemTools::SetFatalErrorOccured();
         return true;
         return true;
       }
       }
@@ -122,7 +125,7 @@ bool cmIfFunctionBlocker::Replay(std::vector<cmListFileFunction> functions,
             func, this->GetStartingContext().FilePath);
             func, this->GetStartingContext().FilePath);
 
 
         cmConditionEvaluator conditionEvaluator(mf, conditionContext,
         cmConditionEvaluator conditionEvaluator(mf, conditionContext,
-                                                mf.GetBacktrace(func));
+                                                elseifBT);
 
 
         bool isTrue =
         bool isTrue =
           conditionEvaluator.IsTrue(expandedArguments, errorString, messType);
           conditionEvaluator.IsTrue(expandedArguments, errorString, messType);
@@ -130,8 +133,7 @@ bool cmIfFunctionBlocker::Replay(std::vector<cmListFileFunction> functions,
         if (!errorString.empty()) {
         if (!errorString.empty()) {
           std::string err =
           std::string err =
             cmStrCat(cmIfCommandError(expandedArguments), errorString);
             cmStrCat(cmIfCommandError(expandedArguments), errorString);
-          cmListFileBacktrace bt = mf.GetBacktrace(func);
-          mf.GetCMakeInstance()->IssueMessage(messType, err, bt);
+          mf.GetCMakeInstance()->IssueMessage(messType, err, elseifBT);
           if (messType == MessageType::FATAL_ERROR) {
           if (messType == MessageType::FATAL_ERROR) {
             cmSystemTools::SetFatalErrorOccured();
             cmSystemTools::SetFatalErrorOccured();
             return true;
             return true;

+ 5 - 8
Source/cmWhileCommand.cxx

@@ -17,6 +17,7 @@
 #include "cmMakefile.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
 #include "cmMessageType.h"
 #include "cmSystemTools.h"
 #include "cmSystemTools.h"
+#include "cmake.h"
 
 
 class cmWhileFunctionBlocker : public cmFunctionBlocker
 class cmWhileFunctionBlocker : public cmFunctionBlocker
 {
 {
@@ -66,14 +67,10 @@ bool cmWhileFunctionBlocker::Replay(std::vector<cmListFileFunction> functions,
   mf.ExpandArguments(this->Args, expandedArguments);
   mf.ExpandArguments(this->Args, expandedArguments);
   MessageType messageType;
   MessageType messageType;
 
 
-  cmListFileContext execContext = this->GetStartingContext();
-
-  cmCommandContext commandContext;
-  commandContext.Line = execContext.Line;
-  commandContext.Name = execContext.Name;
-
+  cmListFileBacktrace whileBT =
+    mf.GetBacktrace().Push(this->GetStartingContext());
   cmConditionEvaluator conditionEvaluator(mf, this->GetStartingContext(),
   cmConditionEvaluator conditionEvaluator(mf, this->GetStartingContext(),
-                                          mf.GetBacktrace(commandContext));
+                                          whileBT);
 
 
   bool isTrue =
   bool isTrue =
     conditionEvaluator.IsTrue(expandedArguments, errorString, messageType);
     conditionEvaluator.IsTrue(expandedArguments, errorString, messageType);
@@ -90,7 +87,7 @@ bool cmWhileFunctionBlocker::Replay(std::vector<cmListFileFunction> functions,
       err += "(";
       err += "(";
       err += errorString;
       err += errorString;
       err += ").";
       err += ").";
-      mf.IssueMessage(messageType, err);
+      mf.GetCMakeInstance()->IssueMessage(messageType, err, whileBT);
       if (messageType == MessageType::FATAL_ERROR) {
       if (messageType == MessageType::FATAL_ERROR) {
         cmSystemTools::SetFatalErrorOccured();
         cmSystemTools::SetFatalErrorOccured();
         return true;
         return true;