Browse Source

Add backtrace support for language standard

Justin Goshi 5 years ago
parent
commit
ba835874a4
5 changed files with 109 additions and 15 deletions
  1. 26 11
      Source/cmGeneratorTarget.cxx
  2. 4 1
      Source/cmGeneratorTarget.h
  3. 3 3
      Source/cmMakefile.cxx
  4. 69 0
      Source/cmTarget.cxx
  5. 7 0
      Source/cmTarget.h

+ 26 - 11
Source/cmGeneratorTarget.cxx

@@ -947,8 +947,8 @@ bool cmGeneratorTarget::HasExplicitObjectName(cmSourceFile const* file) const
   return it != this->ExplicitObjectName.end();
 }
 
-cmProp cmGeneratorTarget::GetLanguageStandard(std::string const& lang,
-                                              std::string const& config) const
+BT<std::string> const* cmGeneratorTarget::GetLanguageStandardProperty(
+  std::string const& lang, std::string const& config) const
 {
   std::string key = cmStrCat(cmSystemTools::UpperCase(config), '-', lang);
   auto langStandardIter = this->LanguageStandardMap.find(key);
@@ -956,7 +956,21 @@ cmProp cmGeneratorTarget::GetLanguageStandard(std::string const& lang,
     return &langStandardIter->second;
   }
 
-  return this->Target->GetProperty(cmStrCat(lang, "_STANDARD"));
+  return this->Target->GetLanguageStandardProperty(
+    cmStrCat(lang, "_STANDARD"));
+}
+
+cmProp cmGeneratorTarget::GetLanguageStandard(std::string const& lang,
+                                              std::string const& config) const
+{
+  BT<std::string> const* languageStandard =
+    this->GetLanguageStandardProperty(lang, config);
+
+  if (languageStandard) {
+    return &(languageStandard->Value);
+  }
+
+  return nullptr;
 }
 
 cmProp cmGeneratorTarget::GetPropertyWithPairedLanguageSupport(
@@ -4469,7 +4483,8 @@ bool cmGeneratorTarget::ComputeCompileFeatures(std::string const& config) const
     }
 
     if (!newRequiredStandard.empty()) {
-      this->LanguageStandardMap[key] = newRequiredStandard;
+      this->LanguageStandardMap[key] =
+        BT<std::string>(newRequiredStandard, f.Backtrace);
     }
   }
 
@@ -4480,15 +4495,15 @@ bool cmGeneratorTarget::ComputeCompileFeatures(
   std::string const& config, std::set<LanguagePair> const& languagePairs) const
 {
   for (const auto& language : languagePairs) {
-    cmProp generatorTargetLanguageStandard =
-      this->GetLanguageStandard(language.first, config);
+    BT<std::string> const* generatorTargetLanguageStandard =
+      this->GetLanguageStandardProperty(language.first, config);
     if (!generatorTargetLanguageStandard) {
       // If the standard isn't explicitly set we copy it over from the
       // specified paired language.
       std::string key =
         cmStrCat(cmSystemTools::UpperCase(config), '-', language.first);
-      cmProp standardToCopy =
-        this->GetLanguageStandard(language.second, config);
+      BT<std::string> const* standardToCopy =
+        this->GetLanguageStandardProperty(language.second, config);
       if (standardToCopy != nullptr) {
         this->LanguageStandardMap[key] = *standardToCopy;
         generatorTargetLanguageStandard = &this->LanguageStandardMap[key];
@@ -4496,7 +4511,7 @@ bool cmGeneratorTarget::ComputeCompileFeatures(
         cmProp defaultStandard = this->Makefile->GetDef(
           cmStrCat("CMAKE_", language.second, "_STANDARD_DEFAULT"));
         if (defaultStandard != nullptr) {
-          this->LanguageStandardMap[key] = *defaultStandard;
+          this->LanguageStandardMap[key] = BT<std::string>(*defaultStandard);
           generatorTargetLanguageStandard = &this->LanguageStandardMap[key];
         }
       }
@@ -4504,8 +4519,8 @@ bool cmGeneratorTarget::ComputeCompileFeatures(
       // Custom updates for the CUDA standard.
       if (generatorTargetLanguageStandard != nullptr &&
           language.first == "CUDA") {
-        if (*generatorTargetLanguageStandard == "98") {
-          this->LanguageStandardMap[key] = "03";
+        if (generatorTargetLanguageStandard->Value == "98") {
+          this->LanguageStandardMap[key].Value = "03";
         }
       }
     }

+ 4 - 1
Source/cmGeneratorTarget.h

@@ -148,6 +148,9 @@ public:
   bool HasExplicitObjectName(cmSourceFile const* file) const;
   void AddExplicitObjectName(cmSourceFile const* sf);
 
+  BT<std::string> const* GetLanguageStandardProperty(
+    std::string const& lang, std::string const& config) const;
+
   cmProp GetLanguageStandard(std::string const& lang,
                              std::string const& config) const;
 
@@ -1050,7 +1053,7 @@ private:
   bool GetRPATH(const std::string& config, const std::string& prop,
                 std::string& rpath) const;
 
-  mutable std::map<std::string, std::string> LanguageStandardMap;
+  mutable std::map<std::string, BT<std::string>> LanguageStandardMap;
 
   cmProp GetPropertyWithPairedLanguageSupport(std::string const& lang,
                                               const char* suffix) const;

+ 3 - 3
Source/cmMakefile.cxx

@@ -5070,7 +5070,7 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
         target->GetProperty(cmStrCat(lang, "_STANDARD")), newRequiredStandard,
         error)) {
     if (!newRequiredStandard.empty()) {
-      target->SetProperty(cmStrCat(lang, "_STANDARD"), newRequiredStandard);
+      target->SetLanguageStandardProperty(lang, newRequiredStandard, feature);
     }
     return true;
   }
@@ -5251,7 +5251,7 @@ bool cmMakefile::AddRequiredTargetCudaFeature(cmTarget* target,
         target->GetProperty(cmStrCat(lang, "_STANDARD")), newRequiredStandard,
         error)) {
     if (!newRequiredStandard.empty()) {
-      target->SetProperty(cmStrCat(lang, "_STANDARD"), newRequiredStandard);
+      target->SetLanguageStandardProperty(lang, newRequiredStandard, feature);
     }
     return true;
   }
@@ -5356,7 +5356,7 @@ bool cmMakefile::AddRequiredTargetCFeature(cmTarget* target,
         target->GetProperty(cmStrCat(lang, "_STANDARD")), newRequiredStandard,
         error)) {
     if (!newRequiredStandard.empty()) {
-      target->SetProperty(cmStrCat(lang, "_STANDARD"), newRequiredStandard);
+      target->SetLanguageStandardProperty(lang, newRequiredStandard, feature);
     }
     return true;
   }

+ 69 - 0
Source/cmTarget.cxx

@@ -7,6 +7,7 @@
 #include <cstring>
 #include <initializer_list>
 #include <iterator>
+#include <map>
 #include <set>
 #include <sstream>
 #include <unordered_set>
@@ -185,6 +186,7 @@ public:
   std::vector<cmInstallTargetGenerator*> InstallGenerators;
   std::set<std::string> SystemIncludeDirectories;
   cmTarget::LinkLibraryVectorType OriginalLinkLibraries;
+  std::map<std::string, BT<std::string>> LanguageStandardProperties;
   std::vector<std::string> IncludeDirectoriesEntries;
   std::vector<cmListFileBacktrace> IncludeDirectoriesBacktraces;
   std::vector<std::string> CompileOptionsEntries;
@@ -598,6 +600,35 @@ cmGlobalGenerator* cmTarget::GetGlobalGenerator() const
   return impl->Makefile->GetGlobalGenerator();
 }
 
+BT<std::string> const* cmTarget::GetLanguageStandardProperty(
+  const std::string& propertyName) const
+{
+  auto entry = impl->LanguageStandardProperties.find(propertyName);
+  if (entry != impl->LanguageStandardProperties.end()) {
+    return &entry->second;
+  }
+
+  return nullptr;
+}
+
+void cmTarget::SetLanguageStandardProperty(std::string const& lang,
+                                           std::string const& value,
+                                           const std::string& feature)
+{
+  cmListFileBacktrace featureBacktrace;
+  for (size_t i = 0; i < impl->CompileFeaturesEntries.size(); i++) {
+    if (impl->CompileFeaturesEntries[i] == feature) {
+      if (i < impl->CompileFeaturesBacktraces.size()) {
+        featureBacktrace = impl->CompileFeaturesBacktraces[i];
+      }
+      break;
+    }
+  }
+
+  impl->LanguageStandardProperties[cmStrCat(lang, "_STANDARD")] =
+    BT<std::string>(value, featureBacktrace);
+}
+
 void cmTarget::AddUtility(std::string const& name, bool cross, cmMakefile* mf)
 {
   impl->Utilities.insert(BT<std::pair<std::string, bool>>(
@@ -1127,6 +1158,11 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
     return;
   }
 #define MAKE_STATIC_PROP(PROP) static const std::string prop##PROP = #PROP
+  MAKE_STATIC_PROP(C_STANDARD);
+  MAKE_STATIC_PROP(CXX_STANDARD);
+  MAKE_STATIC_PROP(CUDA_STANDARD);
+  MAKE_STATIC_PROP(OBJC_STANDARD);
+  MAKE_STATIC_PROP(OBJCXX_STANDARD);
   MAKE_STATIC_PROP(COMPILE_DEFINITIONS);
   MAKE_STATIC_PROP(COMPILE_FEATURES);
   MAKE_STATIC_PROP(COMPILE_OPTIONS);
@@ -1310,6 +1346,15 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
     cmProp tmp = reusedTarget->GetProperty("COMPILE_PDB_NAME");
     this->SetProperty("COMPILE_PDB_NAME", tmp ? tmp->c_str() : nullptr);
     this->AddUtility(reusedFrom, false, impl->Makefile);
+  } else if (prop == propC_STANDARD || prop == propCXX_STANDARD ||
+             prop == propCUDA_STANDARD || prop == propOBJC_STANDARD ||
+             prop == propOBJCXX_STANDARD) {
+    if (value) {
+      impl->LanguageStandardProperties[prop] =
+        BT<std::string>(value, impl->Makefile->GetBacktrace());
+    } else {
+      impl->LanguageStandardProperties.erase(prop);
+    }
   } else {
     impl->Properties.SetProperty(prop, value);
   }
@@ -1413,6 +1458,11 @@ void cmTarget::AppendProperty(const std::string& prop,
   } else if (cmHasLiteralPrefix(prop, "IMPORTED_LIBNAME")) {
     impl->Makefile->IssueMessage(MessageType::FATAL_ERROR,
                                  prop + " property may not be APPENDed.");
+  } else if (prop == "C_STANDARD" || prop == "CXX_STANDARD" ||
+             prop == "CUDA_STANDARD" || prop == "OBJC_STANDARD" ||
+             prop == "OBJCXX_STANDARD") {
+    impl->Makefile->IssueMessage(MessageType::FATAL_ERROR,
+                                 prop + " property may not be appended.");
   } else {
     impl->Properties.AppendProperty(prop, value, asString);
   }
@@ -1626,6 +1676,11 @@ cmProp cmTarget::GetComputedProperty(const std::string& prop,
 cmProp cmTarget::GetProperty(const std::string& prop) const
 {
 #define MAKE_STATIC_PROP(PROP) static const std::string prop##PROP = #PROP
+  MAKE_STATIC_PROP(C_STANDARD);
+  MAKE_STATIC_PROP(CXX_STANDARD);
+  MAKE_STATIC_PROP(CUDA_STANDARD);
+  MAKE_STATIC_PROP(OBJC_STANDARD);
+  MAKE_STATIC_PROP(OBJCXX_STANDARD);
   MAKE_STATIC_PROP(LINK_LIBRARIES);
   MAKE_STATIC_PROP(TYPE);
   MAKE_STATIC_PROP(INCLUDE_DIRECTORIES);
@@ -1646,6 +1701,11 @@ cmProp cmTarget::GetProperty(const std::string& prop) const
   MAKE_STATIC_PROP(TRUE);
 #undef MAKE_STATIC_PROP
   static std::unordered_set<std::string> const specialProps{
+    propC_STANDARD,
+    propCXX_STANDARD,
+    propCUDA_STANDARD,
+    propOBJC_STANDARD,
+    propOBJCXX_STANDARD,
     propLINK_LIBRARIES,
     propTYPE,
     propINCLUDE_DIRECTORIES,
@@ -1664,6 +1724,15 @@ cmProp cmTarget::GetProperty(const std::string& prop) const
     propSOURCES
   };
   if (specialProps.count(prop)) {
+    if (prop == propC_STANDARD || prop == propCXX_STANDARD ||
+        prop == propCUDA_STANDARD || prop == propOBJC_STANDARD ||
+        prop == propOBJCXX_STANDARD) {
+      auto propertyIter = impl->LanguageStandardProperties.find(prop);
+      if (propertyIter == impl->LanguageStandardProperties.end()) {
+        return nullptr;
+      }
+      return &(propertyIter->second.Value);
+    }
     if (prop == propLINK_LIBRARIES) {
       if (impl->LinkImplementationPropertyEntries.empty()) {
         return nullptr;

+ 7 - 0
Source/cmTarget.h

@@ -233,6 +233,13 @@ public:
   void AddSystemIncludeDirectories(std::set<std::string> const& incs);
   std::set<std::string> const& GetSystemIncludeDirectories() const;
 
+  BT<std::string> const* GetLanguageStandardProperty(
+    const std::string& propertyName) const;
+
+  void SetLanguageStandardProperty(std::string const& lang,
+                                   std::string const& value,
+                                   const std::string& feature);
+
   cmStringRange GetIncludeDirectoriesEntries() const;
   cmBacktraceRange GetIncludeDirectoriesBacktraces() const;