From df42dbb3558a6ba604ab584b21dfe7f8722eb025 Mon Sep 17 00:00:00 2001
From: Stephen Kelly <steveire@gmail.com>
Date: Wed, 5 Aug 2015 18:17:55 +0200
Subject: cmGeneratorTarget: Move link implementation from cmTarget.

---
 Source/cmGeneratorExpressionNode.cxx |   2 +-
 Source/cmGeneratorTarget.cxx         | 172 +++++++++++++++++++++++++++++---
 Source/cmGeneratorTarget.h           |  23 +++++
 Source/cmLocalGenerator.cxx          |   4 +-
 Source/cmTarget.cxx                  | 185 ++---------------------------------
 Source/cmTarget.h                    |  26 +----
 6 files changed, 200 insertions(+), 212 deletions(-)

diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 1c350ab..b61e26f 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -1122,7 +1122,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
     else if(!interfacePropertyName.empty())
       {
       if(cmLinkImplementationLibraries const* impl =
-         target->GetLinkImplementationLibraries(context->Config))
+         gtgt->GetLinkImplementationLibraries(context->Config))
         {
         linkedTargetsContent =
           getLinkedTargetsContent(impl->Libraries, target,
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 1a0bbe8..278194e 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -847,7 +847,7 @@ static void AddInterfaceEntries(
   std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries)
 {
   if(cmLinkImplementationLibraries const* impl =
-     thisTarget->Target->GetLinkImplementationLibraries(config))
+     thisTarget->GetLinkImplementationLibraries(config))
     {
     for (std::vector<cmLinkImplItem>::const_iterator
            it = impl->Libraries.begin(), end = impl->Libraries.end();
@@ -1901,7 +1901,7 @@ cmGeneratorTarget::GetLinkImplementationClosure(
     std::set<cmTarget const*> emitted;
 
     cmLinkImplementationLibraries const* impl
-      = this->Target->GetLinkImplementationLibraries(config);
+      = this->GetLinkImplementationLibraries(config);
 
     for(std::vector<cmLinkImplItem>::const_iterator
           it = impl->Libraries.begin();
@@ -2501,7 +2501,7 @@ cmGeneratorTarget::GetIncludeDirectories(const std::string& config,
   if(this->Makefile->IsOn("APPLE"))
     {
     cmLinkImplementationLibraries const* impl =
-        this->Target->GetLinkImplementationLibraries(config);
+        this->GetLinkImplementationLibraries(config);
     for(std::vector<cmLinkImplItem>::const_iterator
         it = impl->Libraries.begin();
         it != impl->Libraries.end(); ++it)
@@ -4363,8 +4363,7 @@ void cmGeneratorTarget::ComputeLinkInterface(const std::string& config,
     {
     // The link implementation is the default link interface.
     cmLinkImplementationLibraries const*
-      impl = this->Target->GetLinkImplementationLibrariesInternal(config,
-                                                                headTarget);
+      impl = this->GetLinkImplementationLibrariesInternal(config, headTarget);
     iface.ImplementationIsInterface = true;
     iface.WrongConfigLibraries = impl->WrongConfigLibraries;
     }
@@ -4558,8 +4557,7 @@ cmGeneratorTarget::ComputeLinkInterfaceLibraries(
     {
     // The link implementation is the default link interface.
     cmLinkImplementationLibraries const* impl =
-      this->Target->GetLinkImplementationLibrariesInternal(config,
-                                                           headTarget);
+      this->GetLinkImplementationLibrariesInternal(config, headTarget);
     iface.Libraries.insert(iface.Libraries.end(),
                            impl->Libraries.begin(), impl->Libraries.end());
     if(this->Target->GetPolicyStatusCMP0022() == cmPolicies::WARN &&
@@ -4674,12 +4672,12 @@ cmGeneratorTarget::GetLinkImplementation(const std::string& config) const
     return 0;
     }
 
-  cmOptionalLinkImplementation& impl = this->Target->GetLinkImplMap(config);
+  std::string CONFIG = cmSystemTools::UpperCase(config);
+  cmOptionalLinkImplementation& impl = this->LinkImplMap[CONFIG][this->Target];
   if(!impl.LibrariesDone)
     {
     impl.LibrariesDone = true;
-    this->Target->ComputeLinkImplementationLibraries(config, impl,
-                                                     this->Target);
+    this->ComputeLinkImplementationLibraries(config, impl, this->Target);
     }
   if(!impl.LanguagesDone)
     {
@@ -4819,9 +4817,161 @@ bool cmGeneratorTarget::HaveBuildTreeRPATH(const std::string& config) const
     return false;
     }
   if(cmLinkImplementationLibraries const* impl =
-     this->Target->GetLinkImplementationLibraries(config))
+     this->GetLinkImplementationLibraries(config))
     {
     return !impl->Libraries.empty();
     }
   return false;
 }
+
+//----------------------------------------------------------------------------
+cmLinkImplementationLibraries const*
+cmGeneratorTarget::GetLinkImplementationLibraries(
+    const std::string& config) const
+{
+  return this->GetLinkImplementationLibrariesInternal(config, this->Target);
+}
+
+//----------------------------------------------------------------------------
+cmLinkImplementationLibraries const*
+cmGeneratorTarget::GetLinkImplementationLibrariesInternal(
+    const std::string& config, cmTarget const* head) const
+{
+  // There is no link implementation for imported targets.
+  if(this->IsImported())
+    {
+    return 0;
+    }
+
+  // Populate the link implementation libraries for this configuration.
+  std::string CONFIG = cmSystemTools::UpperCase(config);
+  HeadToLinkImplementationMap& hm =
+    this->LinkImplMap[CONFIG];
+
+  // If the link implementation does not depend on the head target
+  // then return the one we computed first.
+  if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition)
+    {
+    return &hm.begin()->second;
+    }
+
+  cmOptionalLinkImplementation& impl = hm[head];
+  if(!impl.LibrariesDone)
+    {
+    impl.LibrariesDone = true;
+    this->ComputeLinkImplementationLibraries(config, impl, head);
+    }
+  return &impl;
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::ComputeLinkImplementationLibraries(
+  const std::string& config,
+  cmOptionalLinkImplementation& impl,
+  cmTarget const* head) const
+{
+  cmStringRange entryRange =
+      this->Target->GetLinkImplementationEntries();
+  cmBacktraceRange btRange =
+      this->Target->GetLinkImplementationBacktraces();
+  cmBacktraceRange::const_iterator btIt = btRange.begin();
+  // Collect libraries directly linked in this configuration.
+  for (cmStringRange::const_iterator le = entryRange.begin(),
+      end = entryRange.end(); le != end; ++le, ++btIt)
+    {
+    std::vector<std::string> llibs;
+    cmGeneratorExpressionDAGChecker dagChecker(
+                                        this->GetName(),
+                                        "LINK_LIBRARIES", 0, 0);
+    cmGeneratorExpression ge(*btIt);
+    cmsys::auto_ptr<cmCompiledGeneratorExpression> const cge =
+      ge.Parse(*le);
+    std::string const evaluated =
+      cge->Evaluate(this->Makefile, config, false, head, &dagChecker);
+    cmSystemTools::ExpandListArgument(evaluated, llibs);
+    if(cge->GetHadHeadSensitiveCondition())
+      {
+      impl.HadHeadSensitiveCondition = true;
+      }
+
+    for(std::vector<std::string>::const_iterator li = llibs.begin();
+        li != llibs.end(); ++li)
+      {
+      // Skip entries that resolve to the target itself or are empty.
+      std::string name = this->Target->CheckCMP0004(*li);
+      if(name == this->GetName() || name.empty())
+        {
+        if(name == this->GetName())
+          {
+          bool noMessage = false;
+          cmake::MessageType messageType = cmake::FATAL_ERROR;
+          std::ostringstream e;
+          switch(this->Target->GetPolicyStatusCMP0038())
+            {
+            case cmPolicies::WARN:
+              {
+              e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0038) << "\n";
+              messageType = cmake::AUTHOR_WARNING;
+              }
+              break;
+            case cmPolicies::OLD:
+              noMessage = true;
+            case cmPolicies::REQUIRED_IF_USED:
+            case cmPolicies::REQUIRED_ALWAYS:
+            case cmPolicies::NEW:
+              // Issue the fatal message.
+              break;
+            }
+
+          if(!noMessage)
+            {
+            e << "Target \"" << this->GetName() << "\" links to itself.";
+            this->LocalGenerator->GetCMakeInstance()->IssueMessage(
+              messageType, e.str(), this->Target->GetBacktrace());
+            if (messageType == cmake::FATAL_ERROR)
+              {
+              return;
+              }
+            }
+          }
+        continue;
+        }
+
+      // The entry is meant for this configuration.
+      impl.Libraries.push_back(
+        cmLinkImplItem(name, this->Target->FindTargetToLink(name),
+                       *btIt, evaluated != *le));
+      }
+
+    std::set<std::string> const& seenProps = cge->GetSeenTargetProperties();
+    for (std::set<std::string>::const_iterator it = seenProps.begin();
+        it != seenProps.end(); ++it)
+      {
+      if (!this->GetProperty(*it))
+        {
+        this->Target->LinkImplicitNullProperties.insert(*it);
+        }
+      }
+    cge->GetMaxLanguageStandard(this->Target,
+                                this->MaxLanguageStandards);
+    }
+
+  cmTarget::LinkLibraryType linkType = this->Target->ComputeLinkType(config);
+  cmTarget::LinkLibraryVectorType const& oldllibs =
+    this->Target->GetOriginalLinkLibraries();
+  for(cmTarget::LinkLibraryVectorType::const_iterator li = oldllibs.begin();
+      li != oldllibs.end(); ++li)
+    {
+    if(li->second != cmTarget::GENERAL && li->second != linkType)
+      {
+      std::string name = this->Target->CheckCMP0004(li->first);
+      if(name == this->GetName() || name.empty())
+        {
+        continue;
+        }
+      // Support OLD behavior for CMP0003.
+      impl.WrongConfigLibraries.push_back(
+        cmLinkItem(name, this->Target->FindTargetToLink(name)));
+      }
+    }
+}
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index e8c5e04..f5805f1 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -207,6 +207,13 @@ public:
                                           cmOptionalLinkImplementation& impl
                                           ) const;
 
+  cmLinkImplementationLibraries const*
+    GetLinkImplementationLibraries(const std::string& config) const;
+
+  void ComputeLinkImplementationLibraries(const std::string& config,
+                                          cmOptionalLinkImplementation& impl,
+                                          cmTarget const* head) const;
+
   // Compute the set of languages compiled by the target.  This is
   // computed every time it is called because the languages can change
   // when source file properties are changed and we do not have enough
@@ -462,6 +469,16 @@ private:
   void GetSourceFiles(std::vector<std::string>& files,
                       const std::string& config) const;
 
+  struct HeadToLinkImplementationMap:
+    public std::map<cmTarget const*, cmOptionalLinkImplementation> {};
+  typedef std::map<std::string,
+                   HeadToLinkImplementationMap> LinkImplMapType;
+  mutable LinkImplMapType LinkImplMap;
+
+  cmLinkImplementationLibraries const*
+    GetLinkImplementationLibrariesInternal(const std::string& config,
+                                           cmTarget const* head) const;
+
   typedef std::pair<std::string, bool> OutputNameKey;
   typedef std::map<OutputNameKey, std::string> OutputNameMapType;
   mutable OutputNameMapType OutputNameMap;
@@ -477,6 +494,12 @@ public:
   std::vector<cmTarget const*> const&
     GetLinkImplementationClosure(const std::string& config) const;
 
+  mutable std::map<std::string, std::string> MaxLanguageStandards;
+  std::map<std::string, std::string> const&
+  GetMaxLanguageStandards() const
+  {
+    return this->MaxLanguageStandards;
+  }
 };
 
 struct cmStrictTargetComparison {
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 6647894..06eb004 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -1152,8 +1152,8 @@ void cmLocalGenerator::AddCompileOptions(
     }
 
   for(std::map<std::string, std::string>::const_iterator it
-      = target->GetMaxLanguageStandards().begin();
-      it != target->GetMaxLanguageStandards().end(); ++it)
+      = gtgt->GetMaxLanguageStandards().begin();
+      it != gtgt->GetMaxLanguageStandards().end(); ++it)
     {
     const char* standard = target->GetProperty(it->first + "_STANDARD");
     if(!standard)
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 63c7740..e1642cc 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -95,12 +95,6 @@ public:
   typedef std::map<std::string, cmTarget::ImportInfo> ImportInfoMapType;
   ImportInfoMapType ImportInfoMap;
 
-  struct HeadToLinkImplementationMap:
-    public std::map<cmTarget const*, cmOptionalLinkImplementation> {};
-  typedef std::map<std::string,
-                   HeadToLinkImplementationMap> LinkImplMapType;
-  LinkImplMapType LinkImplMap;
-
   std::set<cmLinkItem> UtilityItems;
   bool UtilityItemsDone;
 
@@ -405,7 +399,6 @@ void cmTarget::FinishConfigure()
   // on-demand during the configuration.  This ensures that build
   // system generation uses up-to-date information even if other cache
   // invalidation code in this source file is buggy.
-  this->ClearLinkMaps();
 
 #if defined(_WIN32) && !defined(__CYGWIN__)
   // Do old-style link dependency analysis only for CM_USE_OLD_VS6.
@@ -417,12 +410,6 @@ void cmTarget::FinishConfigure()
 }
 
 //----------------------------------------------------------------------------
-void cmTarget::ClearLinkMaps()
-{
-  this->Internal->LinkImplMap.clear();
-}
-
-//----------------------------------------------------------------------------
 cmListFileBacktrace const& cmTarget::GetBacktrace() const
 {
   return this->Internal->Backtrace;
@@ -884,7 +871,6 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf,
   this->LinkLibrariesForVS6.push_back( tmp );
 #endif
   this->OriginalLinkLibraries.push_back(tmp);
-  this->ClearLinkMaps();
 
   // Add the explicit dependency information for this target. This is
   // simply a set of libraries separated by ";". There should always
@@ -983,6 +969,16 @@ cmBacktraceRange cmTarget::GetSourceBacktraces() const
   return cmMakeRange(this->Internal->SourceBacktraces);
 }
 
+cmStringRange cmTarget::GetLinkImplementationEntries() const
+{
+  return cmMakeRange(this->Internal->LinkImplementationPropertyEntries);
+}
+
+cmBacktraceRange cmTarget::GetLinkImplementationBacktraces() const
+{
+  return cmMakeRange(this->Internal->LinkImplementationPropertyBacktraces);
+}
+
 #if defined(_WIN32) && !defined(__CYGWIN__)
 //----------------------------------------------------------------------------
 void
@@ -1611,10 +1607,6 @@ void cmTarget::MaybeInvalidatePropertyCache(const std::string& prop)
     {
     this->Internal->ImportInfoMap.clear();
     }
-  if(!this->IsImported() && cmHasLiteralPrefix(prop, "LINK_INTERFACE_"))
-    {
-    this->ClearLinkMaps();
-    }
 }
 
 //----------------------------------------------------------------------------
@@ -3162,163 +3154,6 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config,
     }
 }
 
-cmOptionalLinkImplementation&
-cmTarget::GetLinkImplMap(std::string const& config) const
-{
-  // Populate the link implementation for this configuration.
-  std::string CONFIG = cmSystemTools::UpperCase(config);
-  return Internal->LinkImplMap[CONFIG][this];
-}
-
-//----------------------------------------------------------------------------
-cmLinkImplementationLibraries const*
-cmTarget::GetLinkImplementationLibraries(const std::string& config) const
-{
-  return this->GetLinkImplementationLibrariesInternal(config, this);
-}
-
-//----------------------------------------------------------------------------
-cmLinkImplementationLibraries const*
-cmTarget::GetLinkImplementationLibrariesInternal(const std::string& config,
-                                                 cmTarget const* head) const
-{
-  // There is no link implementation for imported targets.
-  if(this->IsImported())
-    {
-    return 0;
-    }
-
-  // Populate the link implementation libraries for this configuration.
-  std::string CONFIG = cmSystemTools::UpperCase(config);
-  cmTargetInternals::HeadToLinkImplementationMap& hm =
-    this->Internal->LinkImplMap[CONFIG];
-
-  // If the link implementation does not depend on the head target
-  // then return the one we computed first.
-  if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition)
-    {
-    return &hm.begin()->second;
-    }
-
-  cmOptionalLinkImplementation& impl = hm[head];
-  if(!impl.LibrariesDone)
-    {
-    impl.LibrariesDone = true;
-    this->ComputeLinkImplementationLibraries(config, impl, head);
-    }
-  return &impl;
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::ComputeLinkImplementationLibraries(
-  const std::string& config,
-  cmOptionalLinkImplementation& impl,
-  cmTarget const* head) const
-{
-  std::vector<cmListFileBacktrace>::const_iterator btIt =
-      this->Internal->LinkImplementationPropertyBacktraces.begin();
-  // Collect libraries directly linked in this configuration.
-  for (std::vector<std::string>::const_iterator
-      le = this->Internal->LinkImplementationPropertyEntries.begin(),
-      end = this->Internal->LinkImplementationPropertyEntries.end();
-      le != end; ++le, ++btIt)
-    {
-    std::vector<std::string> llibs;
-    cmGeneratorExpressionDAGChecker dagChecker(
-                                        this->GetName(),
-                                        "LINK_LIBRARIES", 0, 0);
-    cmGeneratorExpression ge(*btIt);
-    cmsys::auto_ptr<cmCompiledGeneratorExpression> const cge =
-      ge.Parse(*le);
-    std::string const evaluated =
-      cge->Evaluate(this->Makefile, config, false, head, &dagChecker);
-    cmSystemTools::ExpandListArgument(evaluated, llibs);
-    if(cge->GetHadHeadSensitiveCondition())
-      {
-      impl.HadHeadSensitiveCondition = true;
-      }
-
-    for(std::vector<std::string>::const_iterator li = llibs.begin();
-        li != llibs.end(); ++li)
-      {
-      // Skip entries that resolve to the target itself or are empty.
-      std::string name = this->CheckCMP0004(*li);
-      if(name == this->GetName() || name.empty())
-        {
-        if(name == this->GetName())
-          {
-          bool noMessage = false;
-          cmake::MessageType messageType = cmake::FATAL_ERROR;
-          std::ostringstream e;
-          switch(this->GetPolicyStatusCMP0038())
-            {
-            case cmPolicies::WARN:
-              {
-              e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0038) << "\n";
-              messageType = cmake::AUTHOR_WARNING;
-              }
-              break;
-            case cmPolicies::OLD:
-              noMessage = true;
-            case cmPolicies::REQUIRED_IF_USED:
-            case cmPolicies::REQUIRED_ALWAYS:
-            case cmPolicies::NEW:
-              // Issue the fatal message.
-              break;
-            }
-
-          if(!noMessage)
-            {
-            e << "Target \"" << this->GetName() << "\" links to itself.";
-            this->Makefile->GetCMakeInstance()->IssueMessage(
-              messageType, e.str(), this->GetBacktrace());
-            if (messageType == cmake::FATAL_ERROR)
-              {
-              return;
-              }
-            }
-          }
-        continue;
-        }
-
-      // The entry is meant for this configuration.
-      impl.Libraries.push_back(
-        cmLinkImplItem(name, this->FindTargetToLink(name),
-                       *btIt, evaluated != *le));
-      }
-
-    std::set<std::string> const& seenProps = cge->GetSeenTargetProperties();
-    for (std::set<std::string>::const_iterator it = seenProps.begin();
-        it != seenProps.end(); ++it)
-      {
-      if (!this->GetProperty(*it))
-        {
-        this->LinkImplicitNullProperties.insert(*it);
-        }
-      }
-    cge->GetMaxLanguageStandard(this, this->MaxLanguageStandards);
-    }
-
-  cmTarget::LinkLibraryType linkType = this->ComputeLinkType(config);
-  cmTarget::LinkLibraryVectorType const& oldllibs =
-    this->GetOriginalLinkLibraries();
-  for(cmTarget::LinkLibraryVectorType::const_iterator li = oldllibs.begin();
-      li != oldllibs.end(); ++li)
-    {
-    if(li->second != cmTarget::GENERAL && li->second != linkType)
-      {
-      std::string name = this->CheckCMP0004(li->first);
-      if(name == this->GetName() || name.empty())
-        {
-        continue;
-        }
-      // Support OLD behavior for CMP0003.
-      impl.WrongConfigLibraries.push_back(
-        cmLinkItem(name, this->FindTargetToLink(name)));
-      }
-    }
-}
-
 //----------------------------------------------------------------------------
 cmTarget const* cmTarget::FindTargetToLink(std::string const& name) const
 {
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 354eda2..aab9582 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -225,16 +225,6 @@ public:
 
   void GetObjectLibrariesCMP0026(std::vector<cmTarget*>& objlibs) const;
 
-  cmLinkImplementationLibraries const*
-    GetLinkImplementationLibraries(const std::string& config) const;
-
-  void ComputeLinkImplementationLibraries(const std::string& config,
-                                          cmOptionalLinkImplementation& impl,
-                                          cmTarget const* head) const;
-
-  cmOptionalLinkImplementation&
-  GetLinkImplMap(std::string const& config) const;
-
   cmTarget const* FindTargetToLink(std::string const& name) const;
 
   /** Strip off leading and trailing whitespace from an item named in
@@ -365,12 +355,6 @@ public:
   bool LinkLanguagePropagatesToDependents() const
   { return this->TargetTypeValue == STATIC_LIBRARY; }
 
-  std::map<std::string, std::string> const&
-  GetMaxLanguageStandards() const
-  {
-    return this->MaxLanguageStandards;
-  }
-
   cmStringRange GetIncludeDirectoriesEntries() const;
   cmBacktraceRange GetIncludeDirectoriesBacktraces() const;
 
@@ -385,6 +369,9 @@ public:
 
   cmStringRange GetSourceEntries() const;
   cmBacktraceRange GetSourceBacktraces() const;
+  cmStringRange GetLinkImplementationEntries() const;
+  cmBacktraceRange GetLinkImplementationBacktraces() const;
+
 
 #if defined(_WIN32) && !defined(__CYGWIN__)
   const LinkLibraryVectorType &GetLinkLibrariesForVS6() const {
@@ -471,7 +458,6 @@ private:
   std::set<std::string> Utilities;
   mutable std::set<std::string> LinkImplicitNullProperties;
   std::map<std::string, cmListFileBacktrace> UtilityBacktraces;
-  mutable std::map<std::string, std::string> MaxLanguageStandards;
   cmPolicies::PolicyMap PolicyMap;
   std::string Name;
   std::string InstallPath;
@@ -529,14 +515,8 @@ private:
   void ComputeImportInfo(std::string const& desired_config,
                          ImportInfo& info) const;
 
-  cmLinkImplementationLibraries const*
-    GetLinkImplementationLibrariesInternal(const std::string& config,
-                                           cmTarget const* head) const;
-
   std::string ProcessSourceItemCMP0049(const std::string& s);
 
-  void ClearLinkMaps();
-
   void MaybeInvalidatePropertyCache(const std::string& prop);
 
   // Internal representation details.
-- 
cgit v0.12