From 49fd34cb82d8edae683526a5d9fdd3c86136e646 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 30 May 2017 10:23:27 +0200 Subject: Rework C/C++ standard translation in preparation for experimental/modules Also fix bug in clang-apple versioning. --- build2/c/init.cxx | 104 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 59 insertions(+), 45 deletions(-) (limited to 'build2/c') diff --git a/build2/c/init.cxx b/build2/c/init.cxx index ada8596..998bc40 100644 --- a/build2/c/init.cxx +++ b/build2/c/init.cxx @@ -20,6 +20,7 @@ namespace build2 { namespace c { + using cc::compiler_id; using cc::compiler_info; class config_module: public cc::config_module @@ -29,64 +30,77 @@ namespace build2 config_module (config_data&& d) : config_data (move (d)), cc::config_module (move (d)) {} - string + strings translate_std (const compiler_info&, scope&, - const string&) const override; + const string*) const override; }; using cc::module; - string config_module:: - translate_std (const compiler_info& ci, scope& rs, const string& v) const + strings config_module:: + translate_std (const compiler_info& ci, scope& rs, const string* v) const { - string r; + strings r; - if (ci.id.type == "msvc") + switch (ci.id.value ()) { - // Standard-wise, with VC you get what you get. The question is - // whether we should verify that the requested standard is provided by - // this VC version. And if so, from which version should we say VC - // supports 90, 99, and 11? We should probably be as loose as possible - // here since the author will always be able to tighten (but not - // loosen) this in the buildfile (i.e., detect unsupported versions). - // - // The state of affairs seem to be (from Herb Sutter's blog): - // - // 10.0 - most of C95 plus a few C99 features - // 11.0 - partial support for the C++11 subset of C11 - // 12.0 - more C11 features from the C++11 subset, most of C99 - // - // So let's say C99 is supported from 10.0 and C11 from 11.0. And C90 - // is supported by everything we care to support. - // - if (v != "90") + case compiler_id::msvc: { - uint64_t cver (ci.version.major); - - if ((v == "99" && cver < 16) || // Since VS2010/10.0. - (v == "11" && cver < 17)) // Since VS2012/11.0. + // Standard-wise, with VC you get what you get. The question is + // whether we should verify that the requested standard is provided + // by this VC version. And if so, from which version should we say + // VC supports 90, 99, and 11? We should probably be as loose as + // possible here since the author will always be able to tighten + // (but not loosen) this in the buildfile (i.e., detect unsupported + // versions). + // + // The state of affairs seem to be (from Herb Sutter's blog): + // + // 10.0 - most of C95 plus a few C99 features + // 11.0 - partial support for the C++11 subset of C11 + // 12.0 - more C11 features from the C++11 subset, most of C99 + // + // So let's say C99 is supported from 10.0 and C11 from 11.0. And + // C90 is supported by everything we care to support. + // + if (v == nullptr) + ; + else if (*v != "90") { - fail << "C" << v << " is not supported by " << ci.signature << - info << "required by " << project (rs) << '@' << rs.out_path (); + uint64_t cver (ci.version.major); + + if ((*v == "99" && cver < 16) || // Since VS2010/10.0. + (*v == "11" && cver < 17)) // Since VS2012/11.0. + { + fail << "C" << *v << " is not supported by " << ci.signature << + info << "required by " << project (rs) << '@' << rs.out_path (); + } } + break; + } + case compiler_id::gcc: + case compiler_id::clang: + case compiler_id::icc: + { + // 90 and 89 are the same standard. Translate 99 to 9x and 11 to 1x + // for compatibility with older versions of the compilers. + // + if (v == nullptr) + ; + else + { + string o ("-std="); + + if (*v == "90") o += "c90"; + else if (*v == "99") o += "c9x"; + else if (*v == "11") o += "c1x"; + else o += *v; // In case the user specifies e.g., 'gnu11'. + + r.push_back (move (o)); + } + break; } - } - else - { - // 90 and 89 are the same standard. Translate 99 to 9x and 11 to 1x - // for compatibility with older versions of the compilers. - // - r = "-std="; - - if (v == "90") - r += "c90"; - else if (v == "99") - r += "c9x"; - else if (v == "11") - r += "c1x"; - else - r += v; // In case the user specifies something like 'gnu11'. } return r; -- cgit v1.1