2012-10-02 09:12:39 +02:00
/****************************************************************************
2008-12-02 12:01:29 +01:00
* *
2016-01-15 14:57:40 +01:00
* * Copyright ( C ) 2016 The Qt Company Ltd .
* * Contact : https : //www.qt.io/licensing/
2008-12-02 12:01:29 +01:00
* *
2012-10-02 09:12:39 +02:00
* * This file is part of Qt Creator .
2008-12-02 12:01:29 +01:00
* *
2012-10-02 09:12:39 +02:00
* * Commercial License Usage
* * Licensees holding valid commercial Qt licenses may use this file in
* * accordance with the commercial license agreement provided with the
* * Software or , alternatively , in accordance with the terms contained in
2016-01-15 14:57:40 +01:00
* * a written agreement between you and The Qt Company . For licensing terms
* * and conditions see https : //www.qt.io/terms-conditions. For further
* * information use the contact form at https : //www.qt.io/contact-us.
2008-12-02 14:17:16 +01:00
* *
2016-01-15 14:57:40 +01:00
* * GNU General Public License Usage
* * Alternatively , this file may be used under the terms of the GNU
* * General Public License version 3 as published by the Free Software
* * Foundation with exceptions as appearing in the file LICENSE . GPL3 - EXCEPT
* * included in the packaging of this file . Please review the following
* * information to ensure the GNU General Public License requirements will
* * be met : https : //www.gnu.org/licenses/gpl-3.0.html.
2010-12-17 16:01:08 +01:00
* *
2012-10-02 09:12:39 +02:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-12-02 12:01:29 +01:00
# include "msvcparser.h"
2009-02-16 13:12:12 +01:00
# include "projectexplorerconstants.h"
2015-04-20 17:13:45 +02:00
# include "buildmanager.h"
2013-06-17 12:05:06 +03:00
2013-07-19 11:37:46 +03:00
# include <utils/qtcassert.h>
2013-10-23 22:07:46 +03:00
# include <utils/fileutils.h>
2008-12-02 12:01:29 +01:00
2017-04-03 09:02:42 +03:00
using namespace Utils ;
2015-05-22 15:13:18 +02:00
// As of MSVC 2015: "foo.cpp(42) :" -> "foo.cpp(42):"
2017-04-02 17:01:55 +03:00
static const char FILE_POS_PATTERN [ ] = " ^(?: \\ d+>)?(cl|LINK|.+[^ ]) ?: " ;
2011-05-19 16:11:59 +02:00
2017-04-03 09:02:42 +03:00
static QPair < FileName , int > parseFileName ( const QString & input )
2011-05-19 16:11:59 +02:00
{
QString fileName = input ;
2017-04-03 09:02:42 +03:00
if ( fileName . startsWith ( " LINK " ) | | fileName . startsWith ( " cl " ) )
return qMakePair ( FileName ( ) , - 1 ) ;
2011-05-19 16:11:59 +02:00
// Extract linenumber (if it is there):
int linenumber = - 1 ;
2017-04-03 09:02:42 +03:00
if ( fileName . endsWith ( ' ) ' ) ) {
int pos = fileName . lastIndexOf ( ' ( ' ) ;
2011-05-19 16:11:59 +02:00
if ( pos > = 0 ) {
2016-02-03 13:10:33 +01:00
// clang-cl gives column, too: "foo.cpp(34,1)" as opposed to MSVC "foo.cpp(34)".
2017-04-03 09:02:42 +03:00
int endPos = fileName . indexOf ( ' , ' , pos + 1 ) ;
2016-02-03 13:10:33 +01:00
if ( endPos < 0 )
endPos = fileName . size ( ) - 1 ;
2011-05-19 16:11:59 +02:00
bool ok = false ;
2016-02-03 13:10:33 +01:00
const int n = fileName . midRef ( pos + 1 , endPos - pos - 1 ) . toInt ( & ok ) ;
2011-05-19 16:11:59 +02:00
if ( ok ) {
fileName = fileName . left ( pos ) ;
linenumber = n ;
}
}
}
2017-04-03 09:02:42 +03:00
const QString normalized = FileUtils : : normalizePathName ( fileName ) ;
return qMakePair ( FileName : : fromUserInput ( normalized ) , linenumber ) ;
2010-08-13 13:27:02 +02:00
}
2009-02-16 13:12:12 +01:00
using namespace ProjectExplorer ;
2008-12-02 12:01:29 +01:00
2016-02-04 13:29:04 +01:00
// nmake/jom messages.
static bool handleNmakeJomMessage ( const QString & line , Task * task )
{
int matchLength = 0 ;
2017-04-03 09:02:42 +03:00
if ( line . startsWith ( " Error: " ) )
2016-02-04 13:29:04 +01:00
matchLength = 6 ;
2017-04-03 09:02:42 +03:00
else if ( line . startsWith ( " Warning: " ) )
2016-02-04 13:29:04 +01:00
matchLength = 8 ;
if ( ! matchLength )
return false ;
* task = Task ( Task : : Error ,
line . mid ( matchLength ) . trimmed ( ) , /* description */
2017-04-03 09:02:42 +03:00
FileName ( ) , /* fileName */
2016-02-04 13:29:04 +01:00
- 1 , /* linenumber */
Constants : : TASK_CATEGORY_COMPILE ) ;
return true ;
}
static Task : : TaskType taskType ( const QString & category )
{
Task : : TaskType type = Task : : Unknown ;
2017-04-03 09:02:42 +03:00
if ( category = = " warning " )
2016-02-04 13:29:04 +01:00
type = Task : : Warning ;
2017-04-03 09:02:42 +03:00
else if ( category = = " error " )
2016-02-04 13:29:04 +01:00
type = Task : : Error ;
return type ;
}
2008-12-02 12:01:29 +01:00
MsvcParser : : MsvcParser ( )
{
2017-04-03 09:02:42 +03:00
setObjectName ( " MsvcParser " ) ;
2017-04-02 17:12:44 +03:00
m_compileRegExp . setPattern ( QString ( FILE_POS_PATTERN )
2018-04-24 09:58:48 +02:00
+ " .*(?:(warning|error) ([A-Z]+ \\ d{4} ?: )|note: )(.*)$ " ) ;
2013-07-19 11:37:46 +03:00
QTC_CHECK ( m_compileRegExp . isValid ( ) ) ;
2017-04-03 09:02:42 +03:00
m_additionalInfoRegExp . setPattern ( " ^ (?:(could be |or ) \\ s*')?(.*) \\ (( \\ d+) \\ ) : (.*)$ " ) ;
2013-07-19 11:37:46 +03:00
QTC_CHECK ( m_additionalInfoRegExp . isValid ( ) ) ;
2008-12-02 12:01:29 +01:00
}
2009-12-09 13:54:46 +01:00
void MsvcParser : : stdOutput ( const QString & line )
2008-12-02 12:01:29 +01:00
{
2014-09-22 16:02:49 +02:00
QRegularExpressionMatch match = m_additionalInfoRegExp . match ( line ) ;
2017-04-03 09:02:42 +03:00
if ( line . startsWith ( " " ) & & ! match . hasMatch ( ) ) {
2010-09-02 16:43:22 +02:00
if ( m_lastTask . isNull ( ) )
return ;
2017-04-03 09:02:42 +03:00
m_lastTask . description . append ( ' \n ' ) ;
2010-09-02 16:43:22 +02:00
m_lastTask . description . append ( line . mid ( 8 ) ) ;
// trim trailing spaces:
int i = 0 ;
for ( i = m_lastTask . description . length ( ) - 1 ; i > = 0 ; - - i ) {
if ( ! m_lastTask . description . at ( i ) . isSpace ( ) )
break ;
}
m_lastTask . description . truncate ( i + 1 ) ;
if ( m_lastTask . formats . isEmpty ( ) ) {
QTextLayout : : FormatRange fr ;
2017-04-03 09:02:42 +03:00
fr . start = m_lastTask . description . indexOf ( ' \n ' ) + 1 ;
2010-09-02 16:43:22 +02:00
fr . length = m_lastTask . description . length ( ) - fr . start ;
fr . format . setFontItalic ( true ) ;
m_lastTask . formats . append ( fr ) ;
} else {
m_lastTask . formats [ 0 ] . length = m_lastTask . description . length ( ) - m_lastTask . formats [ 0 ] . start ;
}
2015-04-20 17:13:45 +02:00
+ + m_lines ;
2010-09-02 16:43:22 +02:00
return ;
}
2010-09-08 18:17:52 +02:00
if ( processCompileLine ( line ) )
2009-11-12 15:54:45 +01:00
return ;
2016-02-04 13:29:04 +01:00
if ( handleNmakeJomMessage ( line , & m_lastTask ) ) {
2015-04-20 17:13:45 +02:00
m_lines = 1 ;
2012-10-12 16:33:00 +02:00
return ;
}
2014-09-22 16:02:49 +02:00
if ( match . hasMatch ( ) ) {
QString description = match . captured ( 1 )
+ match . captured ( 4 ) . trimmed ( ) ;
if ( ! match . captured ( 1 ) . isEmpty ( ) )
2013-11-18 09:39:17 +02:00
description . chop ( 1 ) ; // Remove trailing quote
m_lastTask = Task ( Task : : Unknown , description ,
2017-04-03 09:02:42 +03:00
FileName : : fromUserInput ( match . captured ( 2 ) ) , /* fileName */
2014-09-22 16:02:49 +02:00
match . captured ( 3 ) . toInt ( ) , /* linenumber */
2013-08-19 15:51:26 +02:00
Constants : : TASK_CATEGORY_COMPILE ) ;
2015-04-20 17:13:45 +02:00
m_lines = 1 ;
2009-11-12 15:54:45 +01:00
return ;
2008-12-02 12:01:29 +01:00
}
2010-07-27 14:22:23 +02:00
IOutputParser : : stdOutput ( line ) ;
2008-12-02 12:01:29 +01:00
}
2010-09-01 12:55:03 +02:00
void MsvcParser : : stdError ( const QString & line )
2010-09-08 18:17:52 +02:00
{
if ( processCompileLine ( line ) )
return ;
2013-09-27 00:51:39 +03:00
// Jom outputs errors to stderr
2016-02-04 13:29:04 +01:00
if ( handleNmakeJomMessage ( line , & m_lastTask ) ) {
2015-04-20 17:13:45 +02:00
m_lines = 1 ;
2013-09-27 00:51:39 +03:00
return ;
}
2010-09-08 18:17:52 +02:00
IOutputParser : : stdError ( line ) ;
}
2017-04-14 21:45:41 +02:00
Core : : Id MsvcParser : : id ( )
{
return Core : : Id ( " ProjectExplorer.OutputParser.Msvc " ) ;
}
2010-09-08 18:17:52 +02:00
bool MsvcParser : : processCompileLine ( const QString & line )
2010-09-01 12:55:03 +02:00
{
2013-05-03 16:08:00 +02:00
doFlush ( ) ;
2010-09-02 16:43:22 +02:00
2014-09-22 16:02:49 +02:00
QRegularExpressionMatch match = m_compileRegExp . match ( line ) ;
if ( match . hasMatch ( ) ) {
2017-04-03 09:02:42 +03:00
QPair < FileName , int > position = parseFileName ( match . captured ( 1 ) ) ;
2017-04-02 17:12:44 +03:00
m_lastTask = Task ( taskType ( match . captured ( 2 ) ) ,
match . captured ( 3 ) + match . captured ( 4 ) . trimmed ( ) , // description
2011-05-19 16:11:59 +02:00
position . first , position . second ,
2013-08-19 15:51:26 +02:00
Constants : : TASK_CATEGORY_COMPILE ) ;
2015-04-20 17:13:45 +02:00
m_lines = 1 ;
2010-09-08 18:17:52 +02:00
return true ;
2010-09-01 12:55:03 +02:00
}
2010-09-08 18:17:52 +02:00
return false ;
2010-09-01 12:55:03 +02:00
}
2013-05-03 16:08:00 +02:00
void MsvcParser : : doFlush ( )
2010-09-02 16:43:22 +02:00
{
if ( m_lastTask . isNull ( ) )
return ;
2013-05-03 16:08:00 +02:00
Task t = m_lastTask ;
m_lastTask . clear ( ) ;
2015-04-20 17:13:45 +02:00
emit addTask ( t , m_lines , 1 ) ;
2010-09-02 16:43:22 +02:00
}
2016-02-03 13:10:33 +01:00
// --------------------------------------------------------------------------
// ClangClParser: The compiler errors look similar to MSVC, except that the
// column number is also given and there are no 4digit CXXXX error numbers.
// They are output to stderr.
// --------------------------------------------------------------------------
// ".\qwindowsgdinativeinterface.cpp(48,3) : error: unknown type name 'errr'"
static inline QString clangClCompilePattern ( )
{
2017-04-03 09:02:42 +03:00
return QLatin1String ( FILE_POS_PATTERN ) + " (warning|error): (.*)$ " ;
2016-02-03 13:10:33 +01:00
}
ClangClParser : : ClangClParser ( )
2017-04-03 09:02:42 +03:00
: m_compileRegExp ( clangClCompilePattern ( ) )
2016-02-03 13:10:33 +01:00
{
2017-04-03 09:02:42 +03:00
setObjectName ( " ClangClParser " ) ;
2016-02-03 13:10:33 +01:00
QTC_CHECK ( m_compileRegExp . isValid ( ) ) ;
}
void ClangClParser : : stdOutput ( const QString & line )
{
if ( handleNmakeJomMessage ( line , & m_lastTask ) ) {
m_linkedLines = 1 ;
doFlush ( ) ;
return ;
}
IOutputParser : : stdOutput ( line ) ;
}
// Check for a code marker '~~~~ ^ ~~~~~~~~~~~~' underlining above code.
static inline bool isClangCodeMarker ( const QString & trimmedLine )
{
return trimmedLine . constEnd ( ) = =
2017-04-03 09:02:42 +03:00
std : : find_if ( trimmedLine . constBegin ( ) , trimmedLine . constEnd ( ) ,
[ ] ( QChar c ) { return c ! = ' ' & & c ! = ' ^ ' & & c ! = ' ~ ' ; } ) ;
2016-02-03 13:10:33 +01:00
}
void ClangClParser : : stdError ( const QString & lineIn )
{
const QString line = IOutputParser : : rightTrimmed ( lineIn ) ; // Strip \r\n.
if ( handleNmakeJomMessage ( line , & m_lastTask ) ) {
m_linkedLines = 1 ;
doFlush ( ) ;
return ;
}
// Finish a sequence of warnings/errors: "2 warnings generated."
2017-04-03 09:02:42 +03:00
if ( ! line . isEmpty ( ) & & line . at ( 0 ) . isDigit ( ) & & line . endsWith ( " generated. " ) ) {
2016-02-03 13:10:33 +01:00
doFlush ( ) ;
return ;
}
// Start a new error message by a sequence of "In file included from " which is to be skipped.
2017-04-03 09:02:42 +03:00
if ( line . startsWith ( " In file included from " ) ) {
2016-02-03 13:10:33 +01:00
doFlush ( ) ;
return ;
}
QRegularExpressionMatch match = m_compileRegExp . match ( line ) ;
if ( match . hasMatch ( ) ) {
doFlush ( ) ;
2017-04-03 09:02:42 +03:00
const QPair < FileName , int > position = parseFileName ( match . captured ( 1 ) ) ;
2016-02-03 13:10:33 +01:00
m_lastTask = Task ( taskType ( match . captured ( 2 ) ) , match . captured ( 3 ) . trimmed ( ) ,
position . first , position . second ,
Constants : : TASK_CATEGORY_COMPILE ) ;
m_linkedLines = 1 ;
return ;
}
if ( ! m_lastTask . isNull ( ) ) {
const QString trimmed = line . trimmed ( ) ;
if ( isClangCodeMarker ( trimmed ) ) {
doFlush ( ) ;
return ;
}
2017-04-03 09:02:42 +03:00
m_lastTask . description . append ( ' \n ' ) ;
2016-02-03 13:10:33 +01:00
m_lastTask . description . append ( trimmed ) ;
+ + m_linkedLines ;
return ;
}
IOutputParser : : stdError ( lineIn ) ;
}
void ClangClParser : : doFlush ( )
{
if ( ! m_lastTask . isNull ( ) ) {
emit addTask ( m_lastTask , m_linkedLines , 1 ) ;
m_lastTask . clear ( ) ;
}
}
2010-08-12 16:29:58 +02:00
// Unit tests:
# ifdef WITH_TESTS
# include <QTest>
# include "projectexplorer.h"
# include "projectexplorer / outputparser_test.h"
2017-04-03 09:02:42 +03:00
namespace ProjectExplorer {
2010-08-12 16:29:58 +02:00
void ProjectExplorerPlugin : : testMsvcOutputParsers_data ( )
{
QTest : : addColumn < QString > ( " input " ) ;
QTest : : addColumn < OutputParserTester : : Channel > ( " inputChannel " ) ;
QTest : : addColumn < QString > ( " childStdOutLines " ) ;
QTest : : addColumn < QString > ( " childStdErrLines " ) ;
2013-08-19 15:51:26 +02:00
QTest : : addColumn < QList < Task > > ( " tasks " ) ;
2010-08-12 16:29:58 +02:00
QTest : : addColumn < QString > ( " outputLines " ) ;
QTest : : newRow ( " pass-through stdout " )
2017-04-03 09:02:42 +03:00
< < " Sometext " < < OutputParserTester : : STDOUT
< < " Sometext \n " < < " "
2013-08-19 15:51:26 +02:00
< < QList < Task > ( )
2017-04-03 09:02:42 +03:00
< < " " ;
2010-08-12 16:29:58 +02:00
QTest : : newRow ( " pass-through stderr " )
2017-04-03 09:02:42 +03:00
< < " Sometext " < < OutputParserTester : : STDERR
< < " " < < " Sometext \n "
2013-08-19 15:51:26 +02:00
< < QList < Task > ( )
2017-04-03 09:02:42 +03:00
< < " " ;
2010-08-12 16:29:58 +02:00
QTest : : newRow ( " labeled error " )
2017-04-03 09:02:42 +03:00
< < " qmlstandalone \\ main.cpp(54) : error C4716: 'findUnresolvedModule' : must return a value "
< < OutputParserTester : : STDOUT
< < " " < < " "
2013-08-19 15:51:26 +02:00
< < ( QList < Task > ( )
2012-11-21 22:40:31 +02:00
< < Task ( Task : : Error ,
2017-04-03 09:02:42 +03:00
" C4716: 'findUnresolvedModule' : must return a value " ,
FileName : : fromUserInput ( " qmlstandalone \\ main.cpp " ) , 54 ,
2013-08-19 15:51:26 +02:00
Constants : : TASK_CATEGORY_COMPILE ) )
2017-04-03 09:02:42 +03:00
< < " " ;
2010-08-12 16:29:58 +02:00
2015-05-22 15:13:18 +02:00
QTest : : newRow ( " labeled error-2015 " )
2017-04-03 09:02:42 +03:00
< < " qmlstandalone \\ main.cpp(54): error C4716: 'findUnresolvedModule' : must return a value "
< < OutputParserTester : : STDOUT
< < " " < < " "
2015-05-22 15:13:18 +02:00
< < ( QList < Task > ( )
< < Task ( Task : : Error ,
2017-04-03 09:02:42 +03:00
" C4716: 'findUnresolvedModule' : must return a value " ,
FileName : : fromUserInput ( " qmlstandalone \\ main.cpp " ) , 54 ,
2015-05-22 15:13:18 +02:00
Constants : : TASK_CATEGORY_COMPILE ) )
2017-04-03 09:02:42 +03:00
< < " " ;
2015-05-22 15:13:18 +02:00
2016-05-31 06:33:17 +02:00
QTest : : newRow ( " labeled error with number prefix " )
2017-04-03 09:02:42 +03:00
< < " 1>qmlstandalone \\ main.cpp(54) : error C4716: 'findUnresolvedModule' : must return a value "
< < OutputParserTester : : STDOUT
< < " " < < " "
2016-05-31 06:33:17 +02:00
< < ( QList < Task > ( )
< < Task ( Task : : Error ,
2017-04-03 09:02:42 +03:00
" C4716: 'findUnresolvedModule' : must return a value " ,
FileName : : fromUserInput ( " qmlstandalone \\ main.cpp " ) , 54 ,
2016-05-31 06:33:17 +02:00
Constants : : TASK_CATEGORY_COMPILE ) )
2017-04-03 09:02:42 +03:00
< < " " ;
2016-05-31 06:33:17 +02:00
2010-08-12 16:29:58 +02:00
QTest : : newRow ( " labeled warning " )
2017-04-03 09:02:42 +03:00
< < " x: \\ src \\ plugins \\ projectexplorer \\ msvcparser.cpp(69) : warning C4100: 'something' : unreferenced formal parameter "
< < OutputParserTester : : STDOUT
< < " " < < " "
2013-08-19 15:51:26 +02:00
< < ( QList < Task > ( )
2012-11-21 22:40:31 +02:00
< < Task ( Task : : Warning ,
2017-04-03 09:02:42 +03:00
" C4100: 'something' : unreferenced formal parameter " ,
FileName : : fromUserInput ( " x: \\ src \\ plugins \\ projectexplorer \\ msvcparser.cpp " ) , 69 ,
2013-08-19 15:51:26 +02:00
Constants : : TASK_CATEGORY_COMPILE ) )
2017-04-03 09:02:42 +03:00
< < " " ;
2010-08-12 16:29:58 +02:00
2016-05-31 06:33:17 +02:00
QTest : : newRow ( " labeled warning with number prefix " )
2017-04-03 09:02:42 +03:00
< < " 1>x: \\ src \\ plugins \\ projectexplorer \\ msvcparser.cpp(69) : warning C4100: 'something' : unreferenced formal parameter "
< < OutputParserTester : : STDOUT
< < " " < < " "
2016-05-31 06:33:17 +02:00
< < ( QList < Task > ( )
< < Task ( Task : : Warning ,
2017-04-03 09:02:42 +03:00
" C4100: 'something' : unreferenced formal parameter " ,
FileName : : fromUserInput ( " x: \\ src \\ plugins \\ projectexplorer \\ msvcparser.cpp " ) , 69 ,
2016-05-31 06:33:17 +02:00
Constants : : TASK_CATEGORY_COMPILE ) )
2017-04-03 09:02:42 +03:00
< < " " ;
2016-05-31 06:33:17 +02:00
2010-08-13 13:27:02 +02:00
QTest : : newRow ( " additional information " )
2017-04-03 09:02:42 +03:00
< < " x: \\ src \\ plugins \\ texteditor \\ icompletioncollector.h(50) : warning C4099: 'TextEditor::CompletionItem' : type name first seen using 'struct' now seen using 'class' \n "
" x: \\ src \\ plugins \\ texteditor \\ completionsupport.h(39) : see declaration of 'TextEditor::CompletionItem' "
2010-08-13 13:27:02 +02:00
< < OutputParserTester : : STDOUT
2017-04-03 09:02:42 +03:00
< < " " < < " "
2013-08-19 15:51:26 +02:00
< < ( QList < Task > ( )
2010-08-13 13:27:02 +02:00
< < Task ( Task : : Warning ,
2017-04-03 09:02:42 +03:00
" C4099: 'TextEditor::CompletionItem' : type name first seen using 'struct' now seen using 'class' " ,
FileName : : fromUserInput ( " x: \\ src \\ plugins \\ texteditor \\ icompletioncollector.h " ) , 50 ,
2013-08-19 15:51:26 +02:00
Constants : : TASK_CATEGORY_COMPILE )
2010-08-13 13:27:02 +02:00
< < Task ( Task : : Unknown ,
2017-04-03 09:02:42 +03:00
" see declaration of 'TextEditor::CompletionItem' " ,
FileName : : fromUserInput ( " x: \\ src \\ plugins \\ texteditor \\ completionsupport.h " ) , 39 ,
2016-05-31 06:33:17 +02:00
Constants : : TASK_CATEGORY_COMPILE ) )
2017-04-03 09:02:42 +03:00
< < " " ;
2016-05-31 06:33:17 +02:00
QTest : : newRow ( " additional information with prefix " )
2017-04-03 09:02:42 +03:00
< < " 2>x: \\ src \\ plugins \\ texteditor \\ icompletioncollector.h(50) : warning C4099: 'TextEditor::CompletionItem' : type name first seen using 'struct' now seen using 'class' \n "
" x: \\ src \\ plugins \\ texteditor \\ completionsupport.h(39) : see declaration of 'TextEditor::CompletionItem' "
2016-05-31 06:33:17 +02:00
< < OutputParserTester : : STDOUT
2017-04-03 09:02:42 +03:00
< < " " < < " "
2016-05-31 06:33:17 +02:00
< < ( QList < Task > ( )
< < Task ( Task : : Warning ,
2017-04-03 09:02:42 +03:00
" C4099: 'TextEditor::CompletionItem' : type name first seen using 'struct' now seen using 'class' " ,
FileName : : fromUserInput ( " x: \\ src \\ plugins \\ texteditor \\ icompletioncollector.h " ) , 50 ,
2016-05-31 06:33:17 +02:00
Constants : : TASK_CATEGORY_COMPILE )
< < Task ( Task : : Unknown ,
2017-04-03 09:02:42 +03:00
" see declaration of 'TextEditor::CompletionItem' " ,
FileName : : fromUserInput ( " x: \\ src \\ plugins \\ texteditor \\ completionsupport.h " ) , 39 ,
2013-08-19 15:51:26 +02:00
Constants : : TASK_CATEGORY_COMPILE ) )
2017-04-03 09:02:42 +03:00
< < " " ;
2010-08-13 13:27:02 +02:00
2010-09-01 12:55:03 +02:00
QTest : : newRow ( " fatal linker error " )
2017-04-03 09:02:42 +03:00
< < " LINK : fatal error LNK1146: no argument specified with option '/LIBPATH:' "
2010-09-01 12:55:03 +02:00
< < OutputParserTester : : STDOUT
2017-04-03 09:02:42 +03:00
< < " " < < " "
2013-08-19 15:51:26 +02:00
< < ( QList < Task > ( )
2010-09-01 12:55:03 +02:00
< < Task ( Task : : Error ,
2017-04-03 09:02:42 +03:00
" LNK1146: no argument specified with option '/LIBPATH:' " ,
FileName ( ) , - 1 ,
2013-08-19 15:51:26 +02:00
Constants : : TASK_CATEGORY_COMPILE ) )
2017-04-03 09:02:42 +03:00
< < " " ;
2010-09-01 12:55:03 +02:00
// This actually comes through stderr!
QTest : : newRow ( " command line warning " )
2017-04-03 09:02:42 +03:00
< < " cl : Command line warning D9002 : ignoring unknown option '-fopenmp' "
2010-09-01 12:55:03 +02:00
< < OutputParserTester : : STDERR
2017-04-03 09:02:42 +03:00
< < " " < < " "
2013-08-19 15:51:26 +02:00
< < ( QList < Task > ( )
2010-09-01 12:55:03 +02:00
< < Task ( Task : : Warning ,
2017-04-03 09:02:42 +03:00
" D9002 : ignoring unknown option '-fopenmp' " ,
FileName ( ) , - 1 ,
2013-08-19 15:51:26 +02:00
Constants : : TASK_CATEGORY_COMPILE ) )
2017-04-03 09:02:42 +03:00
< < " " ;
2010-09-02 16:43:22 +02:00
QTest : : newRow ( " complex error " )
2017-04-03 09:02:42 +03:00
< < " .. \\ untitled \\ main.cpp(19) : error C2440: 'initializing' : cannot convert from 'int' to 'std::_Tree<_Traits>::iterator' \n "
" with \n "
" [ \n "
" _Traits=std::_Tmap_traits<int,double,std::less<int>,std::allocator<std::pair<const int,double>>,false> \n "
" ] \n "
" No constructor could take the source type, or constructor overload resolution was ambiguous "
2010-09-02 16:43:22 +02:00
< < OutputParserTester : : STDOUT
2017-04-03 09:02:42 +03:00
< < " " < < " "
2013-08-19 15:51:26 +02:00
< < ( QList < Task > ( )
2010-09-02 16:43:22 +02:00
< < Task ( Task : : Error ,
2017-04-03 09:02:42 +03:00
" C2440: 'initializing' : cannot convert from 'int' to 'std::_Tree<_Traits>::iterator' \n "
" with \n "
" [ \n "
" _Traits=std::_Tmap_traits<int,double,std::less<int>,std::allocator<std::pair<const int,double>>,false> \n "
" ] \n "
" No constructor could take the source type, or constructor overload resolution was ambiguous " ,
FileName : : fromUserInput ( " .. \\ untitled \\ main.cpp " ) , 19 ,
2013-08-19 15:51:26 +02:00
Constants : : TASK_CATEGORY_COMPILE ) )
2017-04-03 09:02:42 +03:00
< < " " ;
2010-09-08 18:17:52 +02:00
QTest : : newRow ( " Linker error 1 " )
2017-04-03 09:02:42 +03:00
< < " main.obj : error LNK2019: unresolved external symbol \" public: void __thiscall Data::doit(void) \" (?doit@Data@@QAEXXZ) referenced in function _main "
2010-09-08 18:17:52 +02:00
< < OutputParserTester : : STDOUT
2017-04-03 09:02:42 +03:00
< < " " < < " "
2013-08-19 15:51:26 +02:00
< < ( QList < Task > ( )
2010-09-08 18:17:52 +02:00
< < Task ( Task : : Error ,
2017-04-03 09:02:42 +03:00
" LNK2019: unresolved external symbol \" public: void __thiscall Data::doit(void) \" (?doit@Data@@QAEXXZ) referenced in function _main " ,
FileName : : fromUserInput ( " main.obj " ) , - 1 ,
2013-08-19 15:51:26 +02:00
Constants : : TASK_CATEGORY_COMPILE ) )
2017-04-03 09:02:42 +03:00
< < " " ;
2010-09-08 18:17:52 +02:00
QTest : : newRow ( " Linker error 2 " )
2017-04-03 09:02:42 +03:00
< < " debug \\ Experimentation.exe : fatal error LNK1120: 1 unresolved externals "
2010-09-08 18:17:52 +02:00
< < OutputParserTester : : STDOUT
2017-04-03 09:02:42 +03:00
< < " " < < " "
2013-08-19 15:51:26 +02:00
< < ( QList < Task > ( )
2010-09-08 18:17:52 +02:00
< < Task ( Task : : Error ,
2017-04-03 09:02:42 +03:00
" LNK1120: 1 unresolved externals " ,
FileName : : fromUserInput ( " debug \\ Experimentation.exe " ) , - 1 ,
2013-08-19 15:51:26 +02:00
Constants : : TASK_CATEGORY_COMPILE ) )
2017-04-03 09:02:42 +03:00
< < " " ;
2013-09-27 00:51:39 +03:00
QTest : : newRow ( " nmake error " )
2017-04-03 09:02:42 +03:00
< < " Error: dependent '.. \\ .. \\ .. \\ .. \\ creator-2.5 \\ src \\ plugins \\ coreplugin \\ ifile.h' does not exist. "
2012-10-12 16:33:00 +02:00
< < OutputParserTester : : STDOUT
2017-04-03 09:02:42 +03:00
< < " " < < " "
2013-08-19 15:51:26 +02:00
< < ( QList < Task > ( )
2012-10-12 16:33:00 +02:00
< < Task ( Task : : Error ,
2017-04-03 09:02:42 +03:00
" dependent '.. \\ .. \\ .. \\ .. \\ creator-2.5 \\ src \\ plugins \\ coreplugin \\ ifile.h' does not exist. " ,
FileName ( ) , - 1 ,
2013-08-19 15:51:26 +02:00
Constants : : TASK_CATEGORY_COMPILE ) )
2017-04-03 09:02:42 +03:00
< < " " ;
2013-09-27 00:51:39 +03:00
QTest : : newRow ( " jom error " )
2017-04-03 09:02:42 +03:00
< < " Error: dependent 'main.cpp' does not exist. "
2013-09-27 00:51:39 +03:00
< < OutputParserTester : : STDERR
2017-04-03 09:02:42 +03:00
< < " " < < " "
2013-09-27 00:51:39 +03:00
< < ( QList < Task > ( )
< < Task ( Task : : Error ,
2017-04-03 09:02:42 +03:00
" dependent 'main.cpp' does not exist. " ,
FileName ( ) , - 1 ,
2013-09-27 00:51:39 +03:00
Constants : : TASK_CATEGORY_COMPILE ) )
2017-04-03 09:02:42 +03:00
< < " " ;
2012-10-12 16:33:00 +02:00
2011-05-19 16:11:59 +02:00
QTest : : newRow ( " Multiline error " )
2017-04-03 09:02:42 +03:00
< < " c: \\ Program Files (x86) \\ Microsoft Visual Studio 10.0 \\ VC \\ INCLUDE \\ xutility(2227) : warning C4996: 'std::_Copy_impl': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators' \n "
" c: \\ Program Files (x86) \\ Microsoft Visual Studio 10.0 \\ VC \\ INCLUDE \\ xutility(2212) : see declaration of 'std::_Copy_impl' \n "
" symbolgroupvalue.cpp(2314) : see reference to function template instantiation '_OutIt std::copy<const unsigned char*,unsigned short*>(_InIt,_InIt,_OutIt)' being compiled \n "
" with \n "
" [ \n "
" _OutIt=unsigned short *, \n "
" _InIt=const unsigned char * \n "
" ] "
2011-05-19 16:11:59 +02:00
< < OutputParserTester : : STDOUT
2017-04-03 09:02:42 +03:00
< < " " < < " "
2013-08-19 15:51:26 +02:00
< < ( QList < Task > ( )
2011-05-19 16:11:59 +02:00
< < Task ( Task : : Warning ,
2017-04-03 09:02:42 +03:00
" C4996: 'std::_Copy_impl': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators' " ,
FileName : : fromUserInput ( " c: \\ Program Files (x86) \\ Microsoft Visual Studio 10.0 \\ VC \\ INCLUDE \\ xutility " ) , 2227 ,
2013-08-19 15:51:26 +02:00
Constants : : TASK_CATEGORY_COMPILE )
2011-05-19 16:11:59 +02:00
< < Task ( Task : : Unknown ,
2017-04-03 09:02:42 +03:00
" see declaration of 'std::_Copy_impl' " ,
FileName : : fromUserInput ( " c: \\ Program Files (x86) \\ Microsoft Visual Studio 10.0 \\ VC \\ INCLUDE \\ xutility " ) , 2212 ,
2013-08-19 15:51:26 +02:00
Constants : : TASK_CATEGORY_COMPILE )
2011-05-19 16:11:59 +02:00
< < Task ( Task : : Unknown ,
2017-04-03 09:02:42 +03:00
" see reference to function template instantiation '_OutIt std::copy<const unsigned char*,unsigned short*>(_InIt,_InIt,_OutIt)' being compiled \n "
" with \n "
" [ \n "
" _OutIt=unsigned short *, \n "
" _InIt=const unsigned char * \n "
" ] " ,
FileName : : fromUserInput ( " symbolgroupvalue.cpp " ) , 2314 ,
2013-08-19 15:51:26 +02:00
Constants : : TASK_CATEGORY_COMPILE ) )
2017-04-03 09:02:42 +03:00
< < " " ;
2013-11-18 09:39:17 +02:00
QTest : : newRow ( " Ambiguous symbol " )
2017-04-03 09:02:42 +03:00
< < " D: \\ Project \\ file.h(98) : error C2872: 'UINT64' : ambiguous symbol \n "
" could be 'C: \\ Program Files (x86) \\ Microsoft SDKs \\ Windows \\ v7.0A \\ include \\ basetsd.h(83) : unsigned __int64 UINT64' \n "
" or 'D: \\ Project \\ types.h(71) : Types::UINT64' "
2013-11-18 09:39:17 +02:00
< < OutputParserTester : : STDOUT
2017-04-03 09:02:42 +03:00
< < " " < < " "
2013-11-18 09:39:17 +02:00
< < ( QList < Task > ( )
< < Task ( Task : : Error ,
2017-04-03 09:02:42 +03:00
" C2872: 'UINT64' : ambiguous symbol " ,
FileName : : fromUserInput ( " D: \\ Project \\ file.h " ) , 98 ,
Constants : : TASK_CATEGORY_COMPILE )
< < Task ( Task : : Unknown ,
" could be unsigned __int64 UINT64 " ,
FileName : : fromUserInput ( " C: \\ Program Files (x86) \\ Microsoft SDKs \\ Windows \\ v7.0A \\ include \\ basetsd.h " ) , 83 ,
2013-11-18 09:39:17 +02:00
Constants : : TASK_CATEGORY_COMPILE )
2017-04-03 09:02:42 +03:00
< < Task ( Task : : Unknown ,
" or Types::UINT64 " ,
FileName : : fromUserInput ( " D: \\ Project \\ types.h " ) , 71 ,
Constants : : TASK_CATEGORY_COMPILE ) )
< < " " ;
2016-02-11 11:55:00 +01:00
QTest : : newRow ( " ignore moc note " )
2017-04-03 09:02:42 +03:00
< < " /home/qtwebkithelpviewer.h:0: Note: No relevant classes found. No output generated. "
2016-02-11 11:55:00 +01:00
< < OutputParserTester : : STDERR
2017-04-03 09:02:42 +03:00
< < " " < < " /home/qtwebkithelpviewer.h:0: Note: No relevant classes found. No output generated. \n "
2016-02-11 11:55:00 +01:00
< < ( QList < ProjectExplorer : : Task > ( ) )
2017-04-03 09:02:42 +03:00
< < " " ;
2017-04-02 17:12:44 +03:00
QTest : : newRow ( " error with note " )
< < " main.cpp(7): error C2733: 'func': second C linkage of overloaded function not allowed \n "
" main.cpp(6): note: see declaration of 'func' "
< < OutputParserTester : : STDOUT
2017-04-03 09:02:42 +03:00
< < " " < < " "
2017-04-02 17:12:44 +03:00
< < ( QList < Task > ( )
< < Task ( Task : : Error ,
" C2733: 'func': second C linkage of overloaded function not allowed " ,
2017-04-03 09:02:42 +03:00
FileName : : fromUserInput ( " main.cpp " ) , 7 ,
2017-04-02 17:12:44 +03:00
Constants : : TASK_CATEGORY_COMPILE )
< < Task ( Task : : Unknown ,
" see declaration of 'func' " ,
2017-04-03 09:02:42 +03:00
FileName : : fromUserInput ( " main.cpp " ) , 6 ,
2017-04-02 17:12:44 +03:00
Constants : : TASK_CATEGORY_COMPILE ) )
2017-04-03 09:02:42 +03:00
< < " " ;
2018-04-24 09:58:48 +02:00
QTest : : newRow ( " cyrillic warning " ) // QTCREATORBUG-20297
< < QString : : fromUtf8 ( " cl: командная строка warning D9025: переопределение \" /MDd \" на \" /MTd \" " )
< < OutputParserTester : : STDERR
< < " " < < " "
< < ( QList < ProjectExplorer : : Task > ( )
< < Task ( Task : : Warning ,
QString : : fromUtf8 ( " D9025: переопределение \" /MDd \" на \" /MTd \" " ) ,
FileName ( ) , - 1 , Constants : : TASK_CATEGORY_COMPILE ) )
< < " " ;
2010-08-12 16:29:58 +02:00
}
void ProjectExplorerPlugin : : testMsvcOutputParsers ( )
{
OutputParserTester testbench ;
testbench . appendOutputParser ( new MsvcParser ) ;
QFETCH ( QString , input ) ;
QFETCH ( OutputParserTester : : Channel , inputChannel ) ;
QFETCH ( QList < Task > , tasks ) ;
QFETCH ( QString , childStdOutLines ) ;
QFETCH ( QString , childStdErrLines ) ;
QFETCH ( QString , outputLines ) ;
testbench . testParsing ( input , inputChannel ,
tasks , childStdOutLines , childStdErrLines ,
outputLines ) ;
}
2016-02-03 13:10:33 +01:00
void ProjectExplorerPlugin : : testClangClOutputParsers_data ( )
{
QTest : : addColumn < QString > ( " input " ) ;
QTest : : addColumn < OutputParserTester : : Channel > ( " inputChannel " ) ;
QTest : : addColumn < QString > ( " childStdOutLines " ) ;
QTest : : addColumn < QString > ( " childStdErrLines " ) ;
QTest : : addColumn < QList < Task > > ( " tasks " ) ;
QTest : : addColumn < QString > ( " outputLines " ) ;
2017-04-03 09:02:42 +03:00
const QString warning1 = " private field 'm_version' is not used [-Wunused-private-field] \n "
" const int m_version; //! majorVersion<<8 + minorVersion \n " ;
const QString warning2 = " unused variable 'formatTextPlainC' [-Wunused-const-variable] \n "
" static const char formatTextPlainC[] = \" text/plain \" ; \n " ;
const QString warning3 = " unused variable 'formatTextHtmlC' [-Wunused-const-variable] \n "
" static const char formatTextHtmlC[] = \" text/html \" ; \n " ;
const QString error1 = " unknown type name 'errr' \n "
" errr \n " ;
const QString expectedError1 = " unknown type name 'errr' \n "
" errr " ; // Line 2 trimmed.
const QString error2 =
" expected unqualified-id \n "
" void *QWindowsGdiNativeInterface::nativeResourceForBackingStore(const QByteArray &resource, QBackingStore *bs) \n " ;
const QString clangClCompilerLog =
" In file included from . \\ qwindowseglcontext.cpp:40: \n "
" ./qwindowseglcontext.h(282,15) : warning: " + warning1 +
" 5 warnings generated. \n "
" . \\ qwindowsclipboard.cpp(60,19) : warning: " + warning2 +
" ^ \n "
" . \\ qwindowsclipboard.cpp(61,19) : warning: " + warning3 +
" ^ \n "
" 2 warnings generated. \n "
" . \\ qwindowsgdinativeinterface.cpp(48,3) : error: " + error1 +
" ^ \n "
" . \\ qwindowsgdinativeinterface.cpp(51,1) : error: " + error2 +
" ^ \n "
" 2 errors generated. \n " ;
const QString ignoredStderr =
" NMAKE : fatal error U1077: 'D: \\ opt \\ LLVM64_390 \\ bin \\ clang-cl.EXE' : return code '0x1' \n "
" Stop. " ;
2016-02-03 13:10:33 +01:00
const QString input = clangClCompilerLog + ignoredStderr ;
2017-04-03 09:02:42 +03:00
const QString expectedStderr = ignoredStderr + ' \n ' ;
2016-02-03 13:10:33 +01:00
QTest : : newRow ( " error " )
< < input
< < OutputParserTester : : STDERR
2017-04-03 09:02:42 +03:00
< < " " < < expectedStderr
2016-02-03 13:10:33 +01:00
< < ( QList < Task > ( )
2017-04-03 09:02:42 +03:00
< < Task ( Task : : Warning , warning1 . trimmed ( ) ,
FileName : : fromUserInput ( " ./qwindowseglcontext.h " ) , 282 ,
2016-02-03 13:10:33 +01:00
Constants : : TASK_CATEGORY_COMPILE )
2017-04-03 09:02:42 +03:00
< < Task ( Task : : Warning , warning2 . trimmed ( ) ,
FileName : : fromUserInput ( " . \\ qwindowsclipboard.cpp " ) , 60 ,
2016-02-03 13:10:33 +01:00
Constants : : TASK_CATEGORY_COMPILE )
2017-04-03 09:02:42 +03:00
< < Task ( Task : : Warning , warning3 . trimmed ( ) ,
FileName : : fromUserInput ( " . \\ qwindowsclipboard.cpp " ) , 61 ,
2016-02-03 13:10:33 +01:00
Constants : : TASK_CATEGORY_COMPILE )
< < Task ( Task : : Error , expectedError1 ,
2017-04-03 09:02:42 +03:00
FileName : : fromUserInput ( " . \\ qwindowsgdinativeinterface.cpp " ) , 48 ,
2016-02-03 13:10:33 +01:00
Constants : : TASK_CATEGORY_COMPILE )
2017-04-03 09:02:42 +03:00
< < Task ( Task : : Error , error2 . trimmed ( ) ,
FileName : : fromUserInput ( " . \\ qwindowsgdinativeinterface.cpp " ) , 51 ,
2016-02-03 13:10:33 +01:00
Constants : : TASK_CATEGORY_COMPILE ) )
2017-04-03 09:02:42 +03:00
< < " " ;
2016-02-03 13:10:33 +01:00
}
void ProjectExplorerPlugin : : testClangClOutputParsers ( )
{
OutputParserTester testbench ;
testbench . appendOutputParser ( new ClangClParser ) ;
QFETCH ( QString , input ) ;
QFETCH ( OutputParserTester : : Channel , inputChannel ) ;
QFETCH ( QList < Task > , tasks ) ;
QFETCH ( QString , childStdOutLines ) ;
QFETCH ( QString , childStdErrLines ) ;
QFETCH ( QString , outputLines ) ;
testbench . testParsing ( input , inputChannel ,
tasks , childStdOutLines , childStdErrLines ,
outputLines ) ;
}
2017-04-03 09:02:42 +03:00
} // namespace ProjectExplorer
2011-11-24 16:11:37 +01:00
# endif // WITH_TEST