Merge topic 'const-stack'

11cc728e75 cmConstStack: Factor out of cmListFileBacktrace
9123193758 cmListFileBacktrace: Clarify call sites that only push a file path

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !7135
diff --git a/.gitattributes b/.gitattributes
index 79a0f04..71ecacf 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -36,6 +36,7 @@
 *.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 @@
   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 <vector>
 
 #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 <memory>
+
+/** 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 <typename T, typename Stack>
+class cmConstStack
+{
+  struct Entry;
+  std::shared_ptr<Entry const> 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<Entry const> parent, T value);
+  cmConstStack(std::shared_ptr<Entry const> 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 <cassert>
+#include <memory>
+#include <utility>
+
+template <typename T, typename Stack>
+struct cmConstStack<T, Stack>::Entry
+{
+  Entry(std::shared_ptr<Entry const> parent, T value)
+    : Value(std::move(value))
+    , Parent(std::move(parent))
+  {
+  }
+
+  T Value;
+  std::shared_ptr<Entry const> Parent;
+};
+
+template <typename T, typename Stack>
+cmConstStack<T, Stack>::cmConstStack() = default;
+
+template <typename T, typename Stack>
+Stack cmConstStack<T, Stack>::Push(T value) const
+{
+  return Stack(this->TopEntry, std::move(value));
+}
+
+template <typename T, typename Stack>
+Stack cmConstStack<T, Stack>::Pop() const
+{
+  assert(this->TopEntry);
+  return Stack(this->TopEntry->Parent);
+}
+
+template <typename T, typename Stack>
+T const& cmConstStack<T, Stack>::Top() const
+{
+  assert(this->TopEntry);
+  return this->TopEntry->Value;
+}
+
+template <typename T, typename Stack>
+bool cmConstStack<T, Stack>::Empty() const
+{
+  return !this->TopEntry;
+}
+
+template <typename T, typename Stack>
+cmConstStack<T, Stack>::cmConstStack(std::shared_ptr<Entry const> parent,
+                                     T value)
+  : TopEntry(
+      std::make_shared<Entry const>(std::move(parent), std::move(value)))
+{
+}
+
+template <typename T, typename Stack>
+cmConstStack<T, Stack>::cmConstStack(std::shared_ptr<Entry const> 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 <vector>
 
 #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 <vector>
 
 #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 <vector>
 
 #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 <vector>
 
 #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 <vector>
 
 #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 <vector>
 
 #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 <utility>
 #include <vector>
 
+#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 <string>
 
 #include "cmInstallGenerator.h"
-#include "cmListFileCache.h"
 
+class cmListFileBacktrace;
 class cmLocalGenerator;
 class cmMakefile;
 
diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx
index b90af08..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 <cassert>
 #include <memory>
 #include <sstream>
 #include <utility>
@@ -445,64 +445,8 @@
   return cm::nullopt;
 }
 
-// We hold a call/file context.
-struct cmListFileBacktrace::Entry
-{
-  Entry(std::shared_ptr<Entry const> parent, cmListFileContext lfc)
-    : Context(std::move(lfc))
-    , Parent(std::move(parent))
-  {
-  }
-
-  cmListFileContext Context;
-  std::shared_ptr<Entry const> Parent;
-};
-
-/* NOLINTNEXTLINE(performance-unnecessary-value-param) */
-cmListFileBacktrace::cmListFileBacktrace(std::shared_ptr<Entry const> parent,
-                                         cmListFileContext const& lfc)
-  : TopEntry(std::make_shared<Entry const>(std::move(parent), lfc))
-{
-}
-
-cmListFileBacktrace::cmListFileBacktrace(std::shared_ptr<Entry const> top)
-  : TopEntry(std::move(top))
-{
-}
-
-cmListFileBacktrace cmListFileBacktrace::Push(std::string const& file) const
-{
-  // We are entering a file-level scope but have not yet reached
-  // any specific line or command invocation within it.  This context
-  // is useful to print when it is at the top but otherwise can be
-  // skipped during call stack printing.
-  cmListFileContext lfc;
-  lfc.FilePath = file;
-  return this->Push(lfc);
-}
-
-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<cmListFileContext, cmListFileBacktrace>;
 
 std::ostream& operator<<(std::ostream& os, cmListFileContext const& lfc)
 {
diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h
index c3da81b..f7c2509 100644
--- a/Source/cmListFileCache.h
+++ b/Source/cmListFileCache.h
@@ -12,6 +12,7 @@
 
 #include <cm/optional>
 
+#include "cmConstStack.h"
 #include "cmSystemTools.h"
 
 /** \class cmListFileCache
@@ -128,6 +129,17 @@
   {
   }
 
+  static cmListFileContext FromListFilePath(std::string const& filePath)
+  {
+    // We are entering a file-level scope but have not yet reached
+    // any specific line or command invocation within it.  This context
+    // is useful to print when it is at the top but otherwise can be
+    // skipped during call stack printing.
+    cmListFileContext lfc;
+    lfc.FilePath = filePath;
+    return lfc;
+  }
+
   static cmListFileContext FromListFileFunction(
     cmListFileFunction const& lff, std::string const& fileName,
     cm::optional<std::string> deferId = {})
@@ -146,38 +158,16 @@
 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<cmListFileContext, cmListFileBacktrace>
 {
-public:
-  // Default-constructed backtrace is empty.
-  cmListFileBacktrace() = default;
-
-  // Get a backtrace with the given file scope added to the top.
-  cmListFileBacktrace Push(std::string const& file) const;
-
-  // 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<Entry const> TopEntry;
-  cmListFileBacktrace(std::shared_ptr<Entry const> parent,
-                      cmListFileContext const& lfc);
-  cmListFileBacktrace(std::shared_ptr<Entry const> top);
+  using cmConstStack::cmConstStack;
+  friend class cmConstStack<cmListFileContext, cmListFileBacktrace>;
 };
+#ifndef cmListFileCache_cxx
+extern template class cmConstStack<cmListFileContext, cmListFileBacktrace>;
+#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 <string>
 #include <vector>
 
-#include "cmListFileCache.h"
 #include "cmLocalCommonGenerator.h"
 #include "cmNinjaTypes.h"
 #include "cmOutputConverter.h"
@@ -21,6 +20,7 @@
 class cmGeneratorTarget;
 class cmGlobalGenerator;
 class cmGlobalNinjaGenerator;
+class cmListFileBacktrace;
 class cmMakefile;
 class cmRulePlaceholderExpander;
 class cmake;
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index a781d59..91d7ac5 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -491,7 +491,8 @@
   , CheckCMP0011(false)
   , ReportError(true)
 {
-  this->Makefile->Backtrace = this->Makefile->Backtrace.Push(filenametoread);
+  this->Makefile->Backtrace = this->Makefile->Backtrace.Push(
+    cmListFileContext::FromListFilePath(filenametoread));
 
   this->Makefile->PushFunctionBlockerBarrier();
 
@@ -624,7 +625,8 @@
     : Makefile(mf)
     , ReportError(true)
   {
-    this->Makefile->Backtrace = this->Makefile->Backtrace.Push(filenametoread);
+    this->Makefile->Backtrace = this->Makefile->Backtrace.Push(
+      cmListFileContext::FromListFilePath(filenametoread));
 
     this->Makefile->StateSnapshot =
       this->Makefile->GetState()->CreateInlineListFileSnapshot(
@@ -1587,7 +1589,8 @@
   // Add the bottom of all backtraces within this directory.
   // We will never pop this scope because it should be available
   // for messages during the generate step too.
-  this->Backtrace = this->Backtrace.Push(currentStart);
+  this->Backtrace =
+    this->Backtrace.Push(cmListFileContext::FromListFilePath(currentStart));
 
   BuildsystemFileScope scope(this);
 
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 cmStateSnapshot;
 class cmMessenger;
 class cmExecutionStatus;
+class cmListFileBacktrace;
+struct cmListFileArgument;
+
+template <typename T>
+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 <cmext/string_view>
 
 #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 <typename T>
+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: [ "<curses.h>", private, "\"cmCursesStandardIncludes.h\"", public ] },
   { include: [ "\"form.h\"", private, "\"cmCursesStandardIncludes.h\"", public ] },
   { include: [ "<form.h>", private, "\"cmCursesStandardIncludes.h\"", public ] },
+
+  # Help IWYU understand our explicit instantiation for cmConstStack.
+  { symbol: [ "cmConstStack::cmConstStack<T, Stack>", private, "\"cmConstStack.h\"", public ] },
 ]
 
 # vim: set ft=toml: