aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2018-11-05 09:01:53 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2018-11-05 09:01:53 +0200
commitfa05a1a11dc42b393c99059cd0705912b48b050d (patch)
tree9d1a0660d4b75f0e7ef0b5e03d5a3b22638b9274
parentbebadb5220d7387ebbc0f916f35ce9f460f36a66 (diff)
Handle MSVC command line warnings
-rw-r--r--build2/cc/compile-rule.cxx49
-rw-r--r--build2/cc/msvc.cxx53
2 files changed, 66 insertions, 36 deletions
diff --git a/build2/cc/compile-rule.cxx b/build2/cc/compile-rule.cxx
index 1866e13..720b9d0 100644
--- a/build2/cc/compile-rule.cxx
+++ b/build2/cc/compile-rule.cxx
@@ -1337,40 +1337,14 @@ namespace build2
// translation, etc.
//
// It turns out C1083 is also used when we are unable to open the main
- // source file and the error line looks like this:
+ // source file and the error line (which is printed after the first line
+ // containing the file name) looks like this:
//
// c1xx: fatal error C1083: Cannot open source file: 's.cpp': No such
// file or directory
- // Sense whether this is an include note (return npos) or a diagnostics
- // line (return postion of the NNNN code in CNNNN).
- //
- static inline size_t
- next_show_sense (const string& l)
- {
- size_t p (l.find (':'));
-
- for (size_t n (l.size ());
- p != string::npos;
- p = ++p != n ? l.find (':', p) : string::npos)
- {
- auto isnum = [](char c) {return c >= '0' && c <= '9';};
-
- if (p > 5 &&
- l[p - 6] == ' ' &&
- l[p - 5] == 'C' &&
- isnum (l[p - 4]) &&
- isnum (l[p - 3]) &&
- isnum (l[p - 2]) &&
- isnum (l[p - 1]))
- {
- p -= 4; // Start of the error code.
- break;
- }
- }
-
- return p;
- }
+ size_t
+ msvc_sense_diag (const string&, char); // msvc.cxx
// Extract the include path from the VC /showIncludes output line. Return
// empty string if the line is not an include note or include error. Set
@@ -1384,7 +1358,7 @@ namespace build2
//
assert (!good_error);
- size_t p (next_show_sense (l));
+ size_t p (msvc_sense_diag (l, 'C'));
if (p == string::npos)
{
// Include note.
@@ -2596,8 +2570,19 @@ namespace build2
// exist). In this case the first line (and everything
// after it) is presumably diagnostics.
//
+ // It can, however, be a command line warning, for
+ // example:
+ //
+ // cl : Command line warning D9025 : overriding '/W3' with '/W4'
+ //
+ // So we try to detect and skip them assuming they will
+ // also show up during the compilation proper.
+ //
if (l != src.path ().leaf ().string ())
{
+ if (msvc_sense_diag (l, 'D') != string::npos)
+ continue;
+
text << l;
bad_error = true;
break;
@@ -2746,7 +2731,7 @@ namespace build2
//
for (; !eof (getline (is, l)); )
{
- size_t p (next_show_sense (l));
+ size_t p (msvc_sense_diag (l, 'C'));
if (p != string::npos && l.compare (p, 4, "1083") != 0)
diag_stream_lock () << l << endl;
}
diff --git a/build2/cc/msvc.cxx b/build2/cc/msvc.cxx
index 9eb3de0..272b48c 100644
--- a/build2/cc/msvc.cxx
+++ b/build2/cc/msvc.cxx
@@ -42,17 +42,62 @@ namespace build2
return m;
}
+ // Sense whether this is a diagnostics line returning the postion of the
+ // NNNN code in XNNNN and npos otherwise.
+ //
+ size_t
+ msvc_sense_diag (const string& l, char f)
+ {
+ size_t p (l.find (':'));
+
+ // Note that while the C-numbers seems to all be in the ' CNNNN:' form,
+ // the D ones can be ' DNNNN :', for example:
+ //
+ // cl : Command line warning D9025 : overriding '/W3' with '/W4'
+ //
+ for (size_t n (l.size ());
+ p != string::npos;
+ p = ++p != n ? l.find_first_of (": ", p) : string::npos)
+ {
+ auto isnum = [](char c) {return c >= '0' && c <= '9';};
+
+ if (p > 5 &&
+ l[p - 6] == ' ' &&
+ l[p - 5] == f &&
+ isnum (l[p - 4]) &&
+ isnum (l[p - 3]) &&
+ isnum (l[p - 2]) &&
+ isnum (l[p - 1]))
+ {
+ p -= 4; // Start of the error code.
+ break;
+ }
+ }
+
+ return p;
+ }
+
// Filter cl.exe and link.exe noise.
//
void
msvc_filter_cl (ifdstream& is, const path& src)
{
// While it appears VC always prints the source name (event if the
- // file does not exist), let's do a sanity check.
+ // file does not exist), let's do a sanity check. Also handle the
+ // command line warnings which come before the file name.
//
- string l;
- if (getline (is, l) && l != src.leaf ().string ())
- diag_stream_lock () << l << endl;
+ for (string l; !eof (getline (is, l)); )
+ {
+ if (l != src.leaf ().string ())
+ {
+ diag_stream_lock () << l << endl;
+
+ if (msvc_sense_diag (l, 'D') != string::npos)
+ continue;
+ }
+
+ break;
+ }
}
void