fileapi: Support multiple backtraces for language standard

This commit is contained in:
Justin Goshi
2020-07-02 11:26:20 -07:00
parent cc96fb617b
commit 2f383d852d
8 changed files with 102 additions and 32 deletions

View File

@@ -175,6 +175,38 @@ public:
}
};
template <typename T>
class JBTs
{
public:
JBTs(T v = T(), std::vector<JBTIndex> ids = std::vector<JBTIndex>())
: Value(std::move(v))
, Backtraces(std::move(ids))
{
}
T Value;
std::vector<JBTIndex> Backtraces;
friend bool operator==(JBTs<T> const& l, JBTs<T> const& r)
{
if ((l.Value == r.Value) && (l.Backtraces.size() == r.Backtraces.size())) {
for (size_t i = 0; i < l.Backtraces.size(); i++) {
if (l.Backtraces[i].Index != r.Backtraces[i].Index) {
return false;
}
}
}
return true;
}
static bool ValueEq(JBTs<T> const& l, JBTs<T> const& r)
{
return l.Value == r.Value;
}
static bool ValueLess(JBTs<T> const& l, JBTs<T> const& r)
{
return l.Value < r.Value;
}
};
class BacktraceData
{
std::string TopSource;
@@ -277,7 +309,7 @@ struct CompileData
std::string Language;
std::string Sysroot;
JBT<std::string> LanguageStandard;
JBTs<std::string> LanguageStandard;
std::vector<JBT<std::string>> Flags;
std::vector<JBT<std::string>> Defines;
std::vector<JBT<std::string>> PrecompileHeaders;
@@ -323,8 +355,10 @@ struct hash<CompileData>
hash<Json::ArrayIndex>()(i.Backtrace.Index);
}
if (!in.LanguageStandard.Value.empty()) {
result = result ^ hash<std::string>()(in.LanguageStandard.Value) ^
hash<Json::ArrayIndex>()(in.LanguageStandard.Backtrace.Index);
result = result ^ hash<std::string>()(in.LanguageStandard.Value);
for (JBTIndex backtrace : in.LanguageStandard.Backtraces) {
result = result ^ hash<Json::ArrayIndex>()(backtrace.Index);
}
}
return result;
}
@@ -369,6 +403,16 @@ class Target
return JBT<T>(bt.Value, this->Backtraces.Add(bt.Backtrace));
}
template <typename T>
JBTs<T> ToJBTs(BTs<T> const& bts)
{
std::vector<JBTIndex> ids;
for (cmListFileBacktrace const& backtrace : bts.Backtraces) {
ids.emplace_back(this->Backtraces.Add(backtrace));
}
return JBTs<T>(bts.Value, ids);
}
void ProcessLanguages();
void ProcessLanguage(std::string const& lang);
@@ -383,7 +427,7 @@ class Target
Json::Value DumpCompileData(CompileData const& cd);
Json::Value DumpInclude(CompileData::IncludeEntry const& inc);
Json::Value DumpPrecompileHeader(JBT<std::string> const& header);
Json::Value DumpLanguageStandard(JBT<std::string> const& standard);
Json::Value DumpLanguageStandard(JBTs<std::string> const& standard);
Json::Value DumpDefine(JBT<std::string> const& def);
Json::Value DumpSources();
Json::Value DumpSource(cmGeneratorTarget::SourceAndKind const& sk,
@@ -845,10 +889,10 @@ void Target::ProcessLanguage(std::string const& lang)
for (BT<std::string> const& pch : precompileHeaders) {
cd.PrecompileHeaders.emplace_back(this->ToJBT(pch));
}
BT<std::string> const* languageStandard =
BTs<std::string> const* languageStandard =
this->GT->GetLanguageStandardProperty(lang, this->Config);
if (languageStandard) {
cd.LanguageStandard = this->ToJBT(*languageStandard);
cd.LanguageStandard = this->ToJBTs(*languageStandard);
}
}
@@ -1195,18 +1239,15 @@ Json::Value Target::DumpPrecompileHeader(JBT<std::string> const& header)
return precompileHeader;
}
Json::Value Target::DumpLanguageStandard(JBT<std::string> const& standard)
Json::Value Target::DumpLanguageStandard(JBTs<std::string> const& standard)
{
Json::Value languageStandard = Json::objectValue;
languageStandard["standard"] = standard.Value;
if (standard.Backtrace) {
// Only one backtrace is currently stored for a given language standard,
// but we represent this as an array because it's possible for multiple
// compile features to set the same language standard value. Representing
// this as an array will allow things to just work once we support storing
// multiple backtraces for a language standard value.
if (!standard.Backtraces.empty()) {
Json::Value backtraces = Json::arrayValue;
backtraces.append(standard.Backtrace.Index);
for (JBTIndex backtrace : standard.Backtraces) {
backtraces.append(backtrace.Index);
}
languageStandard["backtraces"] = backtraces;
}
return languageStandard;

View File

@@ -949,7 +949,7 @@ bool cmGeneratorTarget::HasExplicitObjectName(cmSourceFile const* file) const
return it != this->ExplicitObjectName.end();
}
BT<std::string> const* cmGeneratorTarget::GetLanguageStandardProperty(
BTs<std::string> const* cmGeneratorTarget::GetLanguageStandardProperty(
std::string const& lang, std::string const& config) const
{
std::string key = cmStrCat(cmSystemTools::UpperCase(config), '-', lang);
@@ -965,7 +965,7 @@ BT<std::string> const* cmGeneratorTarget::GetLanguageStandardProperty(
cmProp cmGeneratorTarget::GetLanguageStandard(std::string const& lang,
std::string const& config) const
{
BT<std::string> const* languageStandard =
BTs<std::string> const* languageStandard =
this->GetLanguageStandardProperty(lang, config);
if (languageStandard) {
@@ -4486,8 +4486,13 @@ bool cmGeneratorTarget::ComputeCompileFeatures(std::string const& config) const
}
if (!newRequiredStandard.empty()) {
this->LanguageStandardMap[key] =
BT<std::string>(newRequiredStandard, f.Backtrace);
BTs<std::string>& languageStandardProperty =
this->LanguageStandardMap[key];
if (languageStandardProperty.Value != newRequiredStandard) {
languageStandardProperty.Value = newRequiredStandard;
languageStandardProperty.Backtraces.clear();
}
languageStandardProperty.Backtraces.emplace_back(f.Backtrace);
}
}
@@ -4498,14 +4503,14 @@ bool cmGeneratorTarget::ComputeCompileFeatures(
std::string const& config, std::set<LanguagePair> const& languagePairs) const
{
for (const auto& language : languagePairs) {
BT<std::string> const* generatorTargetLanguageStandard =
BTs<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);
BT<std::string> const* standardToCopy =
BTs<std::string> const* standardToCopy =
this->GetLanguageStandardProperty(language.second, config);
if (standardToCopy != nullptr) {
this->LanguageStandardMap[key] = *standardToCopy;
@@ -4514,7 +4519,7 @@ bool cmGeneratorTarget::ComputeCompileFeatures(
cmProp defaultStandard = this->Makefile->GetDef(
cmStrCat("CMAKE_", language.second, "_STANDARD_DEFAULT"));
if (defaultStandard != nullptr) {
this->LanguageStandardMap[key] = BT<std::string>(*defaultStandard);
this->LanguageStandardMap[key] = BTs<std::string>(*defaultStandard);
generatorTargetLanguageStandard = &this->LanguageStandardMap[key];
}
}

View File

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

View File

@@ -58,7 +58,11 @@ struct StanardLevelComputer
std::string& newRequiredStandard,
std::string* error) const
{
newRequiredStandard.clear();
if (currentLangStandardValue) {
newRequiredStandard = *currentLangStandardValue;
} else {
newRequiredStandard.clear();
}
auto needed = this->HighestStandardNeeded(makefile, feature);

View File

@@ -186,7 +186,7 @@ public:
std::vector<cmInstallTargetGenerator*> InstallGenerators;
std::set<std::string> SystemIncludeDirectories;
cmTarget::LinkLibraryVectorType OriginalLinkLibraries;
std::map<std::string, BT<std::string>> LanguageStandardProperties;
std::map<std::string, BTs<std::string>> LanguageStandardProperties;
std::vector<std::string> IncludeDirectoriesEntries;
std::vector<cmListFileBacktrace> IncludeDirectoriesBacktraces;
std::vector<std::string> CompileOptionsEntries;
@@ -600,7 +600,7 @@ cmGlobalGenerator* cmTarget::GetGlobalGenerator() const
return impl->Makefile->GetGlobalGenerator();
}
BT<std::string> const* cmTarget::GetLanguageStandardProperty(
BTs<std::string> const* cmTarget::GetLanguageStandardProperty(
const std::string& propertyName) const
{
auto entry = impl->LanguageStandardProperties.find(propertyName);
@@ -625,8 +625,13 @@ void cmTarget::SetLanguageStandardProperty(std::string const& lang,
}
}
impl->LanguageStandardProperties[cmStrCat(lang, "_STANDARD")] =
BT<std::string>(value, featureBacktrace);
BTs<std::string>& languageStandardProperty =
impl->LanguageStandardProperties[cmStrCat(lang, "_STANDARD")];
if (languageStandardProperty.Value != value) {
languageStandardProperty.Value = value;
languageStandardProperty.Backtraces.clear();
}
languageStandardProperty.Backtraces.emplace_back(featureBacktrace);
}
void cmTarget::AddUtility(std::string const& name, bool cross, cmMakefile* mf)
@@ -1357,7 +1362,7 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
prop == propOBJCXX_STANDARD) {
if (value) {
impl->LanguageStandardProperties[prop] =
BT<std::string>(value, impl->Makefile->GetBacktrace());
BTs<std::string>(value, impl->Makefile->GetBacktrace());
} else {
impl->LanguageStandardProperties.erase(prop);
}

View File

@@ -236,7 +236,7 @@ public:
void AddSystemIncludeDirectories(std::set<std::string> const& incs);
std::set<std::string> const& GetSystemIncludeDirectories() const;
BT<std::string> const* GetLanguageStandardProperty(
BTs<std::string> const* GetLanguageStandardProperty(
const std::string& propertyName) const;
void SetLanguageStandardProperty(std::string const& lang,

View File

@@ -15,8 +15,22 @@
"command": null,
"hasParent": false
}
],
[
{
"file": "^cxx/CMakeLists\\.txt$",
"line": 30,
"command": "target_compile_features",
"hasParent": true
},
{
"file": "^cxx/CMakeLists\\.txt$",
"line": null,
"command": null,
"hasParent": false
}
]
],
"standard" : "11"
],
"standard" : "11"
}
}

View File

@@ -27,5 +27,6 @@ add_executable(cxx_standard_compile_feature_exe ../empty.cxx)
set_property(TARGET cxx_standard_compile_feature_exe PROPERTY CXX_STANDARD 98)
if(CMAKE_CXX_STANDARD_DEFAULT AND DEFINED CMAKE_CXX11_STANDARD_COMPILE_OPTION)
target_compile_features(cxx_standard_compile_feature_exe PRIVATE cxx_std_11)
target_compile_features(cxx_standard_compile_feature_exe PRIVATE cxx_decltype)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cxx_std_11.txt" "")
endif()