From 71d9aedda0919fb22e39d6e6ce60506ceb69812e Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 25 May 2017 11:32:01 +0200 Subject: Add compiler_id enum --- build2/cc/compile.cxx | 136 +++++++++++++++++++++++++++++--------------------- 1 file changed, 80 insertions(+), 56 deletions(-) (limited to 'build2/cc/compile.cxx') diff --git a/build2/cc/compile.cxx b/build2/cc/compile.cxx index 21f7ecf..9982a91 100644 --- a/build2/cc/compile.cxx +++ b/build2/cc/compile.cxx @@ -954,29 +954,38 @@ namespace build2 // const char* pp (nullptr); - if (cid == "msvc") pp = "/C"; - else if (cid == "gcc") + switch (cid) { - // -fdirectives-only is available since GCC 4.3.0. - // - if (cmaj > 4 || (cmaj == 4 && cmin >= 3)) - pp = "-fdirectives-only"; - } - else if (cid == "clang") - { - // -frewrite-includes is available since Clang 3.2.0. - // - if (cmaj > 3 || (cmaj == 3 && cmin >= 2)) - pp = "-frewrite-includes"; - } - else if (cid == "clang-apple") - { - // Apple Clang 5.0 is based on LLVM 3.3svn so it should have this - // option (4.2 is based on 3.2svc so it may or may not have it and, - // no, we are not going to try to find out). - // - if (cmaj >= 5) - pp = "-frewrite-includes"; + case compiler_id::gcc: + { + // -fdirectives-only is available since GCC 4.3.0. + // + if (cmaj > 4 || (cmaj == 4 && cmin >= 3)) + pp = "-fdirectives-only"; + + break; + } + case compiler_id::clang: + { + // -frewrite-includes is available since vanilla Clang 3.2.0. + // + // Apple Clang 5.0 is based on LLVM 3.3svn so it should have this + // option (4.2 is based on 3.2svc so it may or may not have it and, + // no, we are not going to try to find out). + // + if (cvar == "" ? (cmaj > 3 || (cmaj == 3 && cmin >= 2)) : + cvar == "apple" ? (cmaj >= 5) : false) + pp = "-frewrite-includes"; + + break; + } + case compiler_id::msvc: + { + pp = "/C"; + break; + } + case compiler_id::icc: + break; } // Initialize lazily, only if required. @@ -1138,7 +1147,7 @@ namespace build2 args.push_back ("-fPIC"); } - if (cid == "msvc") + if (cid == compiler_id::msvc) { assert (pp != nullptr); @@ -1186,7 +1195,7 @@ namespace build2 // Clang's -M does not imply -w (disable warnings). We also don't // need them in the -MD case (see above) so disable for both. // - if (cid == "clang" || cid == "clang-apple") + if (cid == compiler_id::clang) args.push_back ("-w"); // Previously we used '*' as a target name but it gets expanded to @@ -1215,7 +1224,7 @@ namespace build2 // GCC is not capable of writing the dependency info to stdout. // We also need to sense the diagnostics on the -E runs. // - if (cid == "gcc") + if (cid == compiler_id::gcc) { // Use the .t extension (for "temporary"; .d is taken). // @@ -1260,7 +1269,7 @@ namespace build2 args[i + 2] = rels.string ().c_str (); args[i + 3] = nullptr; - if (cid == "gcc") + if (cid == compiler_id::gcc) { sense_diag = false; } @@ -1274,7 +1283,7 @@ namespace build2 args[i + 2] = pp; args[i + 3] = "-MF"; - if (cid == "gcc") + if (cid == compiler_id::gcc) { r = &drm.path (); sense_diag = true; @@ -1648,7 +1657,7 @@ namespace build2 args.data (), 0, -1, - cid == "msvc" ? 1 : gen ? 2 : -2); + cid == compiler_id::msvc ? 1 : gen ? 2 : -2); } else { @@ -1712,7 +1721,7 @@ namespace build2 // Parse different dependency output formats. // - if (cid == "msvc") + if (cid == compiler_id::msvc) { if (first) { @@ -1840,9 +1849,9 @@ namespace build2 // eof, this and all subsequent writes to cerr will fail (and // you won't see a thing). // - if (is.peek () != ifdstream::traits_type::eof () && - cid == "msvc" && - bad_error) + if (bad_error && + cid == compiler_id::msvc && + is.peek () != ifdstream::traits_type::eof ()) cerr << is.rdbuf (); is.close (); @@ -1990,7 +1999,7 @@ namespace build2 append_std (args); - if (cid == "msvc") + if (cid == compiler_id::msvc) { // The /F*: option variants with separate names only became available // in VS2013/12.0. Why do we bother? Because the command line suddenly @@ -2117,21 +2126,32 @@ namespace build2 // This should match with how we setup preprocessing. // - if (cid == "gcc") + switch (cid) { - // The -fpreprocessed in implied by .i/.ii. - // - args.push_back ("-fdirectives-only"); - } - else if (cid == "clang" || cid == "clang-apple") - { - // Without this Clang will treat .i/.ii as fully preprocessed. - // - args.push_back ("-x"); - args.push_back (x_name); - } - else if (cid != "msvc") // Nothing to do (/TP or /TC already there). + case compiler_id::gcc: + { + // The -fpreprocessed in implied by .i/.ii. + // + args.push_back ("-fdirectives-only"); + break; + } + case compiler_id::clang: + { + // Without this Clang will treat .i/.ii as fully preprocessed. + // + args.push_back ("-x"); + args.push_back (x_name); + break; + } + case compiler_id::msvc: + { + // Nothing to do (/TP or /TC already there). + // + break; + } + case compiler_id::icc: assert (false); + } args.push_back (rels.string ().c_str ()); args.push_back (nullptr); @@ -2157,7 +2177,7 @@ namespace build2 // tries to pull off something similar. For sane compilers this should // be harmless. // - bool filter (cid == "msvc"); + bool filter (cid == compiler_id::msvc); process pr (xc, args.data (), 0, (filter ? -1 : 2)); @@ -2213,18 +2233,22 @@ namespace build2 } target_state compile:: - perform_clean (action act, const target& xt) const + perform_clean (action a, const target& xt) const { const file& t (xt.as ()); - if (cid == "msvc") - return clean_extra (act, t, {".d", x_pext, ".idb", ".pdb"}); - else if (cid == "gcc") - return clean_extra (act, t, {".d", x_pext, ".t"}); - else if (cid == "clang" || cid == "clang-apple") - return clean_extra (act, t, {".d", x_pext}); - else - return clean_extra (act, t, {".d"}); + using id = compiler_id; + + switch (cid) + { + case id::gcc: return clean_extra (a, t, {".d", x_pext, ".t"}); + case id::clang: return clean_extra (a, t, {".d", x_pext}); + case id::msvc: return clean_extra (a, t, {".d", x_pext, ".idb", ".pdb"}); + case id::icc: return clean_extra (a, t, {".d"}); + } + + assert (false); + return target_state::unchanged; } } } -- cgit v1.1