fix warning when generating VS 2013 project
[qt:qt.git] / qmake / generators / win32 / msvc_objectmodel.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the qmake application of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.  For licensing terms and
14 ** conditions see http://qt.digia.com/licensing.  For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file.  Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights.  These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file.  Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "msvc_objectmodel.h"
43 #include "msvc_vcproj.h"
44 #include "msvc_vcxproj.h"
45 #include <qstringlist.h>
46 #include <qfileinfo.h>
47
48 QT_BEGIN_NAMESPACE
49
50 // XML Tags ---------------------------------------------------------
51 const char _Configuration[]                     = "Configuration";
52 const char _Configurations[]                    = "Configurations";
53 const char q_File[]                              = "File";
54 const char _FileConfiguration[]                 = "FileConfiguration";
55 const char q_Files[]                             = "Files";
56 const char _Filter[]                            = "Filter";
57 const char _Globals[]                           = "Globals";
58 const char _Platform[]                          = "Platform";
59 const char _Platforms[]                         = "Platforms";
60 const char _Tool[]                              = "Tool";
61 const char _VisualStudioProject[]               = "VisualStudioProject";
62
63 // XML Properties ---------------------------------------------------
64 const char _AddModuleNamesToAssembly[]          = "AddModuleNamesToAssembly";
65 const char _AdditionalDependencies[]            = "AdditionalDependencies";
66 const char _AdditionalFiles[]                   = "AdditionalFiles";
67 const char _AdditionalIncludeDirectories[]      = "AdditionalIncludeDirectories";
68 const char _AdditionalLibraryDirectories[]      = "AdditionalLibraryDirectories";
69 const char _AdditionalOptions[]                 = "AdditionalOptions";
70 const char _AdditionalUsingDirectories[]        = "AdditionalUsingDirectories";
71 const char _AssemblerListingLocation[]          = "AssemblerListingLocation";
72 const char _AssemblerOutput[]                   = "AssemblerOutput";
73 const char _ATLMinimizesCRunTimeLibraryUsage[]  = "ATLMinimizesCRunTimeLibraryUsage";
74 const char _BaseAddress[]                       = "BaseAddress";
75 const char _BasicRuntimeChecks[]                = "BasicRuntimeChecks";
76 const char _BrowseInformation[]                 = "BrowseInformation";
77 const char _BrowseInformationFile[]             = "BrowseInformationFile";
78 const char _BufferSecurityCheck[]               = "BufferSecurityCheck";
79 const char _BuildBrowserInformation[]           = "BuildBrowserInformation";
80 const char _CPreprocessOptions[]                = "CPreprocessOptions";
81 const char _CallingConvention[]                 = "CallingConvention";
82 const char _CharacterSet[]                      = "CharacterSet";
83 const char _CommandLine[]                       = "CommandLine";
84 const char _CompileAs[]                         = "CompileAs";
85 const char _CompileAsManaged[]                  = "CompileAsManaged";
86 const char _CompileOnly[]                       = "CompileOnly";
87 const char _ConfigurationType[]                 = "ConfigurationType";
88 const char _Culture[]                           = "Culture";
89 const char _DLLDataFileName[]                   = "DLLDataFileName";
90 const char _DebugInformationFormat[]            = "DebugInformationFormat";
91 const char _DefaultCharIsUnsigned[]             = "DefaultCharIsUnsigned";
92 const char _DefaultCharType[]                   = "DefaultCharType";
93 const char _DelayLoadDLLs[]                     = "DelayLoadDLLs";
94 const char _DeleteExtensionsOnClean[]           = "DeleteExtensionsOnClean";
95 const char _Description[]                       = "Description";
96 const char _Detect64BitPortabilityProblems[]    = "Detect64BitPortabilityProblems";
97 const char _DisableLanguageExtensions[]         = "DisableLanguageExtensions";
98 const char _DisableSpecificWarnings[]           = "DisableSpecificWarnings";
99 const char _EnableCOMDATFolding[]               = "EnableCOMDATFolding";
100 const char _EnableErrorChecks[]                 = "EnableErrorChecks";
101 const char _EnableEnhancedInstructionSet[]      = "EnableEnhancedInstructionSet";
102 const char _EnableFiberSafeOptimizations[]      = "EnableFiberSafeOptimizations";
103 const char _EnableFunctionLevelLinking[]        = "EnableFunctionLevelLinking";
104 const char _EnableIntrinsicFunctions[]          = "EnableIntrinsicFunctions";
105 const char _EntryPointSymbol[]                  = "EntryPointSymbol";
106 const char _ErrorCheckAllocations[]             = "ErrorCheckAllocations";
107 const char _ErrorCheckBounds[]                  = "ErrorCheckBounds";
108 const char _ErrorCheckEnumRange[]               = "ErrorCheckEnumRange";
109 const char _ErrorCheckRefPointers[]             = "ErrorCheckRefPointers";
110 const char _ErrorCheckStubData[]                = "ErrorCheckStubData";
111 const char _ExceptionHandling[]                 = "ExceptionHandling";
112 const char _ExcludedFromBuild[]                 = "ExcludedFromBuild";
113 const char _ExpandAttributedSource[]            = "ExpandAttributedSource";
114 const char _ExportNamedFunctions[]              = "ExportNamedFunctions";
115 const char _FavorSizeOrSpeed[]                  = "FavorSizeOrSpeed";
116 const char _FloatingPointModel[]                = "FloatingPointModel";
117 const char _FloatingPointExceptions[]           = "FloatingPointExceptions";
118 const char _ForceConformanceInForLoopScope[]    = "ForceConformanceInForLoopScope";
119 const char _ForceSymbolReferences[]             = "ForceSymbolReferences";
120 const char _ForcedIncludeFiles[]                = "ForcedIncludeFiles";
121 const char _ForcedUsingFiles[]                  = "ForcedUsingFiles";
122 const char _FullIncludePath[]                   = "FullIncludePath";
123 const char _FunctionOrder[]                     = "FunctionOrder";
124 const char _GenerateDebugInformation[]          = "GenerateDebugInformation";
125 const char _GenerateMapFile[]                   = "GenerateMapFile";
126 const char _GeneratePreprocessedFile[]          = "GeneratePreprocessedFile";
127 const char _GenerateStublessProxies[]           = "GenerateStublessProxies";
128 const char _GenerateTypeLibrary[]               = "GenerateTypeLibrary";
129 const char _GlobalOptimizations[]               = "GlobalOptimizations";
130 const char _HeaderFileName[]                    = "HeaderFileName";
131 const char _HeapCommitSize[]                    = "HeapCommitSize";
132 const char _HeapReserveSize[]                   = "HeapReserveSize";
133 const char _IgnoreAllDefaultLibraries[]         = "IgnoreAllDefaultLibraries";
134 const char _IgnoreDefaultLibraryNames[]         = "IgnoreDefaultLibraryNames";
135 const char _IgnoreEmbeddedIDL[]                 = "IgnoreEmbeddedIDL";
136 const char _IgnoreImportLibrary[]               = "IgnoreImportLibrary";
137 const char _IgnoreStandardIncludePath[]         = "IgnoreStandardIncludePath";
138 const char _ImportLibrary[]                     = "ImportLibrary";
139 const char _ImproveFloatingPointConsistency[]   = "ImproveFloatingPointConsistency";
140 const char _InlineFunctionExpansion[]           = "InlineFunctionExpansion";
141 const char _InterfaceIdentifierFileName[]       = "InterfaceIdentifierFileName";
142 const char _IntermediateDirectory[]             = "IntermediateDirectory";
143 const char _KeepComments[]                      = "KeepComments";
144 const char _LargeAddressAware[]                 = "LargeAddressAware";
145 const char _LinkDLL[]                           = "LinkDLL";
146 const char _LinkIncremental[]                   = "LinkIncremental";
147 const char _LinkTimeCodeGeneration[]            = "LinkTimeCodeGeneration";
148 const char _LinkToManagedResourceFile[]         = "LinkToManagedResourceFile";
149 const char _MapExports[]                        = "MapExports";
150 const char _MapFileName[]                       = "MapFileName";
151 const char _MapLines[]                          = "MapLines ";
152 const char _MergeSections[]                     = "MergeSections";
153 const char _MergedIDLBaseFileName[]             = "MergedIDLBaseFileName";
154 const char _MidlCommandFile[]                   = "MidlCommandFile";
155 const char _MinimalRebuild[]                    = "MinimalRebuild";
156 const char _MkTypLibCompatible[]                = "MkTypLibCompatible";
157 const char _ModuleDefinitionFile[]              = "ModuleDefinitionFile";
158 const char _Name[]                              = "Name";
159 const char _ObjectFile[]                        = "ObjectFile";
160 const char _OmitFramePointers[]                 = "OmitFramePointers";
161 const char _OpenMP[]                            = "OpenMP";
162 const char _Optimization[]                      = "Optimization ";
163 const char _OptimizeForProcessor[]              = "OptimizeForProcessor";
164 const char _OptimizeForWindows98[]              = "OptimizeForWindows98";
165 const char _OptimizeForWindowsApplication[]     = "OptimizeForWindowsApplication";
166 const char _OptimizeReferences[]                = "OptimizeReferences";
167 const char _OutputDirectory[]                   = "OutputDirectory";
168 const char _OutputFile[]                        = "OutputFile";
169 const char _Outputs[]                           = "Outputs";
170 const char _ParseFiles[]                        = "ParseFiles";
171 const char _PrecompiledHeaderFile[]             = "PrecompiledHeaderFile";
172 const char _PrecompiledHeaderThrough[]          = "PrecompiledHeaderThrough";
173 const char _PreprocessorDefinitions[]           = "PreprocessorDefinitions";
174 const char _PrimaryOutput[]                     = "PrimaryOutput";
175 const char _ProjectGUID[]                       = "ProjectGUID";
176 const char _Keyword[]                           = "Keyword";
177 const char _ProjectType[]                       = "ProjectType";
178 const char _ProgramDatabase[]                   = "ProgramDatabase";
179 const char _ProgramDataBaseFileName[]           = "ProgramDataBaseFileName";
180 const char _ProgramDatabaseFile[]               = "ProgramDatabaseFile";
181 const char _ProxyFileName[]                     = "ProxyFileName";
182 const char _RedirectOutputAndErrors[]           = "RedirectOutputAndErrors";
183 const char _RegisterOutput[]                    = "RegisterOutput";
184 const char _RelativePath[]                      = "RelativePath";
185 const char _RemoteDirectory[]                   = "RemoteDirectory";
186 const char _ResourceOnlyDLL[]                   = "ResourceOnlyDLL";
187 const char _ResourceOutputFileName[]            = "ResourceOutputFileName";
188 const char _RuntimeLibrary[]                    = "RuntimeLibrary";
189 const char _RuntimeTypeInfo[]                   = "RuntimeTypeInfo";
190 const char _SccProjectName[]                    = "SccProjectName";
191 const char _SccLocalPath[]                      = "SccLocalPath";
192 const char _SetChecksum[]                       = "SetChecksum";
193 const char _ShowIncludes[]                      = "ShowIncludes";
194 const char _ShowProgress[]                      = "ShowProgress";
195 const char _SmallerTypeCheck[]                  = "SmallerTypeCheck";
196 const char _StackCommitSize[]                   = "StackCommitSize";
197 const char _StackReserveSize[]                  = "StackReserveSize";
198 const char _StringPooling[]                     = "StringPooling";
199 const char _StripPrivateSymbols[]               = "StripPrivateSymbols";
200 const char _StructMemberAlignment[]             = "StructMemberAlignment";
201 const char _SubSystem[]                         = "SubSystem";
202 const char _SupportUnloadOfDelayLoadedDLL[]     = "SupportUnloadOfDelayLoadedDLL";
203 const char _SuppressStartupBanner[]             = "SuppressStartupBanner";
204 const char _SwapRunFromCD[]                     = "SwapRunFromCD";
205 const char _SwapRunFromNet[]                    = "SwapRunFromNet";
206 const char _TargetEnvironment[]                 = "TargetEnvironment";
207 const char _TargetMachine[]                     = "TargetMachine";
208 const char _TerminalServerAware[]               = "TerminalServerAware";
209 const char _Path[]                              = "Path";
210 const char _TreatWChar_tAsBuiltInType[]         = "TreatWChar_tAsBuiltInType";
211 const char _TurnOffAssemblyGeneration[]         = "TurnOffAssemblyGeneration";
212 const char _TypeLibraryFile[]                   = "TypeLibraryFile";
213 const char _TypeLibraryName[]                   = "TypeLibraryName";
214 const char _TypeLibraryResourceID[]             = "TypeLibraryResourceID";
215 const char _UndefineAllPreprocessorDefinitions[]= "UndefineAllPreprocessorDefinitions";
216 const char _UndefinePreprocessorDefinitions[]   = "UndefinePreprocessorDefinitions";
217 const char _UniqueIdentifier[]                  = "UniqueIdentifier";
218 const char _UseOfATL[]                          = "UseOfATL";
219 const char _UseOfMfc[]                          = "UseOfMfc";
220 const char _UsePrecompiledHeader[]              = "UsePrecompiledHeader";
221 const char _ValidateParameters[]                = "ValidateParameters";
222 const char _VCCLCompilerTool[]                  = "VCCLCompilerTool";
223 const char _VCLibrarianTool[]                   = "VCLibrarianTool";
224 const char _VCLinkerTool[]                      = "VCLinkerTool";
225 const char _VCCustomBuildTool[]                 = "VCCustomBuildTool";
226 const char _VCResourceCompilerTool[]            = "VCResourceCompilerTool";
227 const char _VCMIDLTool[]                        = "VCMIDLTool";
228 const char _Version[]                           = "Version";
229 const char _WarnAsError[]                       = "WarnAsError";
230 const char _WarningLevel[]                      = "WarningLevel";
231 const char _WholeProgramOptimization[]          = "WholeProgramOptimization";
232 const char _CompileForArchitecture[]            = "CompileForArchitecture";
233 const char _InterworkCalls[]                    = "InterworkCalls";
234
235 // XmlOutput stream functions ------------------------------
236 inline XmlOutput::xml_output attrT(const char *name, const triState v)
237 {
238     if(v == unset)
239         return noxml();
240     return attr(name, (v == _True ? "true" : "false"));
241 }
242
243 inline XmlOutput::xml_output attrE(const char *name, int v)
244 {
245     return attr(name, QString::number(v));
246 }
247
248 /*ifNot version*/
249 inline XmlOutput::xml_output attrE(const char *name, int v, int ifn)
250 {
251     if (v == ifn)
252         return noxml();
253     return attr(name, QString::number(v));
254 }
255
256 inline XmlOutput::xml_output attrL(const char *name, qint64 v)
257 {
258     return attr(name, QString::number(v));
259 }
260
261 /*ifNot version*/
262 inline XmlOutput::xml_output attrL(const char *name, qint64 v, qint64 ifn)
263 {
264     if (v == ifn)
265         return noxml();
266     return attr(name, QString::number(v));
267 }
268
269 inline XmlOutput::xml_output attrS(const char *name, const QString &v)
270 {
271     if(v.isEmpty())
272         return noxml();
273     return attr(name, v);
274 }
275
276 inline XmlOutput::xml_output attrX(const char *name, const QStringList &v, const char *s = ",")
277 {
278     if(v.isEmpty())
279         return noxml();
280     return attr(name, v.join(s));
281 }
282
283 triState operator!(const triState &rhs)
284 {
285     if (rhs == unset)
286         return rhs;
287     triState lhs = (rhs == _True ? _False : _True);
288     return lhs;
289 }
290
291 // VCToolBase -------------------------------------------------
292 QStringList VCToolBase::fixCommandLine(const QString &input)
293 {
294     // The splitting regexp is a bit bizarre for backwards compat reasons (why else ...).
295     return input.split(QRegExp(QLatin1String("\n\t|\r\\\\h|\r\n")));
296 }
297
298 static QString vcCommandSeparator()
299 {
300     // MSVC transforms the build tree into a single batch file, simply pasting the contents
301     // of the custom commands into it, and putting an "if errorlevel goto" statement behind it.
302     // As we want every sub-command to be error-checked (as is done by makefile-based
303     // backends), we insert the checks ourselves, using the undocumented jump target.
304     static QString cmdSep =
305     QLatin1String("&#x000D;&#x000A;if errorlevel 1 goto VCReportError&#x000D;&#x000A;");
306     return cmdSep;
307 }
308
309 // VCCLCompilerTool -------------------------------------------------
310 VCCLCompilerTool::VCCLCompilerTool()
311     :        AssemblerOutput(asmListingNone),
312         BasicRuntimeChecks(runtimeBasicCheckNone),
313         BrowseInformation(brInfoNone),
314         BufferSecurityCheck(unset),
315         CallingConvention(callConventionDefault),
316         CompileAs(compileAsDefault),
317         CompileAsManaged(managedDefault),
318         CompileOnly(unset),
319         DebugInformationFormat(debugDisabled),
320         DefaultCharIsUnsigned(unset),
321         Detect64BitPortabilityProblems(unset),
322         DisableLanguageExtensions(unset),
323         EnableEnhancedInstructionSet(archNotSet),
324         EnableFiberSafeOptimizations(unset),
325         EnableFunctionLevelLinking(unset),
326         EnableIntrinsicFunctions(unset),
327         ExceptionHandling(ehDefault),
328         ExpandAttributedSource(unset),
329         FavorSizeOrSpeed(favorNone),
330         FloatingPointModel(floatingPointNotSet),
331         FloatingPointExceptions(unset),
332         ForceConformanceInForLoopScope(unset),
333         GeneratePreprocessedFile(preprocessNo),
334         PreprocessSuppressLineNumbers(unset),
335         GlobalOptimizations(unset),
336         IgnoreStandardIncludePath(unset),
337         ImproveFloatingPointConsistency(unset),
338         InlineFunctionExpansion(expandDefault),
339         KeepComments(unset),
340         MinimalRebuild(unset),
341         OmitDefaultLibName(unset),
342         OmitFramePointers(unset),
343         OpenMP(unset),
344         Optimization(optimizeCustom),
345         OptimizeForProcessor(procOptimizeBlended),
346         OptimizeForWindowsApplication(unset),
347         ProgramDataBaseFileName(""),
348         RuntimeLibrary(rtMultiThreaded),
349         RuntimeTypeInfo(unset),
350         ShowIncludes(unset),
351         SmallerTypeCheck(unset),
352         StringPooling(unset),
353         StructMemberAlignment(alignNotSet),
354         SuppressStartupBanner(unset),
355         TreatWChar_tAsBuiltInType(unset),
356         TurnOffAssemblyGeneration(unset),
357         UndefineAllPreprocessorDefinitions(unset),
358         UsePrecompiledHeader(pchUnset),
359         UseUnicodeForAssemblerListing(unset),
360         WarnAsError(unset),
361         WarningLevel(warningLevel_0),
362         WholeProgramOptimization(unset),
363         CompileForArchitecture(archUnknown),
364         InterworkCalls(unset),
365         EnablePREfast(unset),
366         DisplayFullPaths(unset),
367         MultiProcessorCompilation(unset),
368         GenerateXMLDocumentationFiles(unset),
369         CreateHotpatchableImage(unset)
370 {
371 }
372
373 /*
374  * Some values for the attribute UsePrecompiledHeader have changed from VS 2003 to VS 2005,
375  * see the following chart, so we need a function that transforms those values if we are
376  * using NET2005:
377  *
378  * Meaning                      2003    2005
379  * -----------------------------------------
380  * Don't use PCH                0       0
381  * Create PCH (/Yc)             1       1
382  * Automatically generate (/YX) 2       (seems that it was removed)
383  * Use specific PCH (/Yu)       3       2
384  *
385  */
386 inline XmlOutput::xml_output xformUsePrecompiledHeaderForNET2005(pchOption whatPch, DotNET compilerVersion)
387 {
388     if (compilerVersion >= NET2005) {
389         if (whatPch ==  pchGenerateAuto) whatPch = (pchOption)0;
390         if (whatPch ==  pchUseUsingSpecific) whatPch = (pchOption)2;
391     }
392     return attrE(_UsePrecompiledHeader, whatPch, /*ifNot*/ pchUnset);
393 }
394
395 inline XmlOutput::xml_output xformExceptionHandlingNET2005(exceptionHandling eh, DotNET compilerVersion)
396 {
397     if (eh == ehDefault)
398         return noxml();
399
400     if (compilerVersion >= NET2005)
401         return attrE(_ExceptionHandling, eh);
402
403     return attrS(_ExceptionHandling, (eh == ehNoSEH ? "true" : "false"));
404 }
405
406 bool VCCLCompilerTool::parseOption(const char* option)
407 {
408     // skip index 0 ('/' or '-')
409     char first  = option[1];
410     char second = option[2];
411     char third  = option[3];
412     char fourth = option[4];
413     bool found = true;
414
415     switch (first) {
416     case '?':
417     case 'h':
418         if(second == 'o' && third == 't' && fourth == 'p') {
419             CreateHotpatchableImage = _True;
420             break;
421         }
422         qWarning("Generator: Option '/?', '/help': MSVC.NET projects do not support outputting help info");
423         found = false;
424         break;
425     case '@':
426         qWarning("Generator: Option '/@': MSVC.NET projects do not support the use of a response file");
427         found = false;
428         break;
429     case 'l':
430         qWarning("Generator: Option '/link': qmake generator does not support passing link options through the compiler tool");
431         found = false;
432         break;
433     case 'A':
434         if(second != 'I') {
435             found = false; break;
436         }
437         AdditionalUsingDirectories += option+3;
438         break;
439     case 'C':
440         KeepComments = _True;
441         break;
442     case 'D':
443         PreprocessorDefinitions += option+2;
444         break;
445     case 'E':
446         if(second == 'H') {
447             QByteArray opt(option + 2);
448             if (opt.contains('a') && !opt.contains('s') && !opt.contains('c'))
449                 ExceptionHandling = ehSEH;
450             else if (!opt.contains('a') && opt.contains("s-") && opt.contains("c-"))
451                 ExceptionHandling = ehNone;
452             else if (!opt.contains('a') && opt.contains('s') && opt.contains('c'))
453                 ExceptionHandling = ehNoSEH;
454             else {
455                 // ExceptionHandling must be false, or it will override
456                 // with an /EHsc option
457                 ExceptionHandling = ehNone;
458                 AdditionalOptions += option;
459             }
460             if (config->CompilerVersion < NET2005
461                 && ExceptionHandling == ehSEH) {
462                 ExceptionHandling = ehNone;
463                 AdditionalOptions += option;
464             }
465             break;
466         } else if (second == 'P') {
467             PreprocessSuppressLineNumbers = _True;
468         }
469         GeneratePreprocessedFile = preprocessYes;
470         break;
471     case 'F':
472         if(second <= '9' && second >= '0') {
473             AdditionalOptions += option;
474             break;
475         } else {
476             switch (second) {
477             case 'A':
478                 if(third == 'c') {
479                     AssemblerOutput = asmListingAsmMachine;
480                     if(fourth == 's')
481                         AssemblerOutput = asmListingAsmMachineSrc;
482                 } else if(third == 's') {
483                     AssemblerOutput = asmListingAsmSrc;
484                 } else if (third == 'u') {
485                     UseUnicodeForAssemblerListing = _True;
486                 } else {
487                     AssemblerOutput = asmListingAssemblyOnly;
488                 }
489                 break;
490             case 'C':
491                 DisplayFullPaths = _True;
492                 break;
493             case 'a':
494                 AssemblerListingLocation = option+3;
495                 break;
496             case 'I':
497                 ForcedIncludeFiles += option+3;
498                 break;
499             case 'i':
500                 PreprocessOutputPath += option+3;
501                 break;
502             case 'R':
503                 BrowseInformation = brAllInfo;
504                 BrowseInformationFile = option+3;
505                 break;
506             case 'S':
507                 if (config->CompilerVersion < NET2013)
508                     found = false;
509                 // Ignore this flag. Visual Studio 2013 takes care of this setting.
510                 break;
511             case 'r':
512                 BrowseInformation = brNoLocalSymbols;
513                 BrowseInformationFile = option+3;
514                 break;
515             case 'U':
516                 ForcedUsingFiles += option+3;
517                 break;
518             case 'd':
519                 ProgramDataBaseFileName = option+3;
520                 break;
521             case 'e':
522                 OutputFile = option+3;
523                 break;
524             case 'm':
525                 AdditionalOptions += option;
526                 break;
527             case 'o':
528                 ObjectFile = option+3;
529                 break;
530             case 'p':
531                 PrecompiledHeaderFile = option+3;
532                 break;
533             case 'x':
534                 ExpandAttributedSource = _True;
535                 break;
536             default:
537                 found = false; break;
538             }
539         }
540         break;
541     case 'G':
542         switch (second) {
543         case '3':
544         case '4':
545             qWarning("Option '/G3' and '/G4' were phased out in Visual C++ 5.0");
546             found = false; break;
547         case '5':
548             OptimizeForProcessor = procOptimizePentium;
549             break;
550         case '6':
551         case 'B':
552             OptimizeForProcessor = procOptimizePentiumProAndAbove;
553             break;
554         case '7':
555             OptimizeForProcessor = procOptimizePentium4AndAbove;
556             break;
557         case 'A':
558             OptimizeForWindowsApplication = _True;
559             break;
560         case 'F':
561             StringPooling = _True;
562             break;
563         case 'H':
564             AdditionalOptions += option;
565             break;
566         case 'L':
567             WholeProgramOptimization = _True;
568             if(third == '-')
569                 WholeProgramOptimization = _False;
570             break;
571         case 'R':
572             RuntimeTypeInfo = _True;
573             if(third == '-')
574                 RuntimeTypeInfo = _False;
575             break;
576         case 'S':
577             BufferSecurityCheck = _True;
578             if(third == '-')
579                 BufferSecurityCheck = _False;
580             break;
581         case 'T':
582             EnableFiberSafeOptimizations = _True;
583             break;
584         case 'X':
585             // Same as the /EHsc option, which is Exception Handling without SEH
586             ExceptionHandling = ehNoSEH;
587             if (third == '-')
588                 ExceptionHandling = ehNone;
589             break;
590         case 'Z':
591         case 'e':
592         case 'h':
593             AdditionalOptions += option;
594             break;
595         case 'd':
596             CallingConvention = callConventionCDecl;
597             break;
598         case 'f':
599             StringPooling = _True;
600             AdditionalOptions += option;
601             break;
602         case 'm':
603             MinimalRebuild = _True;
604             if(third == '-')
605                 MinimalRebuild = _False;
606             break;
607         case 'r':
608             CallingConvention = callConventionFastCall;
609             break;
610         case 's':
611             AdditionalOptions += option;
612             break;
613         case 'y':
614             EnableFunctionLevelLinking = _True;
615             break;
616         case 'z':
617             CallingConvention = callConventionStdCall;
618             break;
619         default:
620             found = false; break;
621         }
622         break;
623     case 'H':
624         AdditionalOptions += option;
625         break;
626     case 'I':
627         AdditionalIncludeDirectories += option+2;
628         break;
629     case 'J':
630         DefaultCharIsUnsigned = _True;
631         break;
632     case 'L':
633         if(second == 'D') {
634             AdditionalOptions += option;
635             break;
636         }
637         found = false; break;
638     case 'M':
639         if(second == 'D') {
640             RuntimeLibrary = rtMultiThreadedDLL;
641             if(third == 'd')
642                 RuntimeLibrary = rtMultiThreadedDebugDLL;
643             break;
644         } else if(second == 'L') {
645             RuntimeLibrary = rtSingleThreaded;
646             if(third == 'd')
647                 RuntimeLibrary = rtSingleThreadedDebug;
648             break;
649         } else if(second == 'T') {
650             RuntimeLibrary = rtMultiThreaded;
651             if(third == 'd')
652                 RuntimeLibrary = rtMultiThreadedDebug;
653             break;
654         } else if (second == 'P') {
655             if (config->CompilerVersion >= NET2010) {
656                 MultiProcessorCompilation = _True;
657                 MultiProcessorCompilationProcessorCount = option+3;
658             } else if (config->CompilerVersion >= NET2005) {
659                 AdditionalOptions += option;
660             } else {
661                 warn_msg(WarnLogic, "/MP option is not supported in Visual C++ < 2005, ignoring.");
662             }
663             break;
664         }
665         found = false; break;
666     case 'O':
667         switch (second) {
668         case '1':
669             Optimization = optimizeMinSpace;
670             break;
671         case '2':
672             Optimization = optimizeMaxSpeed;
673             break;
674         case 'a':
675             AdditionalOptions += option;
676             break;
677         case 'b':
678             if(third == '0')
679                 InlineFunctionExpansion = expandDisable;
680             else if(third == '1')
681                 InlineFunctionExpansion = expandOnlyInline;
682             else if(third == '2')
683                 InlineFunctionExpansion = expandAnySuitable;
684             else
685                 found = false;
686             break;
687         case 'd':
688             Optimization = optimizeDisabled;
689             break;
690         case 'g':
691             GlobalOptimizations = _True;
692             break;
693         case 'i':
694             EnableIntrinsicFunctions = _True;
695             break;
696         case 'p':
697             ImproveFloatingPointConsistency = _True;
698             if(third == '-')
699                 ImproveFloatingPointConsistency = _False;
700             break;
701         case 's':
702             FavorSizeOrSpeed = favorSize;
703             break;
704         case 't':
705             FavorSizeOrSpeed = favorSpeed;
706             break;
707         case 'w':
708             AdditionalOptions += option;
709             break;
710         case 'x':
711             Optimization = optimizeFull;
712             break;
713         case 'y':
714             OmitFramePointers = _True;
715             if(third == '-')
716                 OmitFramePointers = _False;
717             break;
718         default:
719             found = false; break;
720         }
721         break;
722     case 'P':
723         GeneratePreprocessedFile = preprocessYes;
724         break;
725     case 'Q':
726         if(second == 'I') {
727             AdditionalOptions += option;
728             break;
729         } else if (second == 'R') {
730             QString opt = option + 3;
731             if (opt == "interwork-return") {
732                 InterworkCalls = _True;
733                 break;
734             } else if (opt == "arch4") {
735                 CompileForArchitecture = archArmv4;
736                 break;
737             } else if (opt == "arch5") {
738                 CompileForArchitecture = archArmv5;
739                 break;
740             } else if (opt == "arch4T") {
741                 CompileForArchitecture = archArmv4T;
742                 break;
743             } else if (opt == "arch5T") {
744                 CompileForArchitecture = archArmv5T;
745                 break;
746             }
747         } else if (second == 'M') {
748             QString opt = option + 3;
749             if (opt == "mips1") {
750                 CompileForArchitecture = archMips1;
751                 break;
752             }
753             else if (opt == "mips2") {
754                 CompileForArchitecture = archMips2;
755                 break;
756             }
757             else if (opt == "mips3") {
758                 CompileForArchitecture = archMips3;
759                 break;
760             }
761             else if (opt == "mips4") {
762                 CompileForArchitecture = archMips4;
763                 break;
764             }
765             else if (opt == "mips5") {
766                 CompileForArchitecture = archMips5;
767                 break;
768             }
769             else if (opt == "mips16") {
770                 CompileForArchitecture = archMips16;
771                 break;
772             }
773             else if (opt == "mips32") {
774                 CompileForArchitecture = archMips32;
775                 break;
776             }
777             else if (opt == "mips64") {
778                 CompileForArchitecture = archMips64;
779                 break;
780             }
781         }
782         found = false; break;
783     case 'R':
784         if(second == 'T' && third == 'C') {
785             int rtc = BasicRuntimeChecks;
786             for (size_t i = 4; option[i]; ++i) {
787                 if (!parseRuntimeCheckOption(option[i], &rtc)) {
788                     found = false;
789                     break;
790                 }
791             }
792             BasicRuntimeChecks = static_cast<basicRuntimeCheckOption>(rtc);
793         }
794         break;
795     case 'T':
796         if(second == 'C') {
797             CompileAs = compileAsC;
798         } else if(second == 'P') {
799             CompileAs = compileAsCPlusPlus;
800         } else {
801             qWarning("Generator: Options '/Tp<filename>' and '/Tc<filename>' are not supported by qmake");
802             found = false; break;
803         }
804         break;
805     case 'U':
806         UndefinePreprocessorDefinitions += option+2;
807         break;
808     case 'V':
809         AdditionalOptions += option;
810         break;
811     case 'W':
812         switch (second) {
813         case 'a':
814         case '4':
815             WarningLevel = warningLevel_4;
816             break;
817         case '3':
818             WarningLevel = warningLevel_3;
819             break;
820         case '2':
821             WarningLevel = warningLevel_2;
822             break;
823         case '1':
824             WarningLevel = warningLevel_1;
825             break;
826         case '0':
827             WarningLevel = warningLevel_0;
828             break;
829         case 'L':
830             AdditionalOptions += option;
831             break;
832         case 'X':
833             WarnAsError = _True;
834             break;
835         case 'p':
836             if(third == '6' && fourth == '4') {
837                 if (config->CompilerVersion >= NET2010) {
838                      // Deprecated for VS2010 but can be used under Additional Options.
839                     AdditionalOptions += option;
840                 } else {
841                    Detect64BitPortabilityProblems = _True;
842                 }
843                 break;
844             }
845             // Fallthrough
846         default:
847             found = false; break;
848         }
849         break;
850     case 'X':
851         IgnoreStandardIncludePath = _True;
852         break;
853     case 'Y':
854         switch (second) {
855         case '\0':
856         case '-':
857             AdditionalOptions += option;
858             break;
859         case 'X':
860             UsePrecompiledHeader = pchGenerateAuto;
861             PrecompiledHeaderThrough = option+3;
862             break;
863         case 'c':
864             UsePrecompiledHeader = pchCreateUsingSpecific;
865             PrecompiledHeaderThrough = option+3;
866             break;
867         case 'd':
868         case 'l':
869             AdditionalOptions += option;
870             break;
871         case 'u':
872             UsePrecompiledHeader = pchUseUsingSpecific;
873             PrecompiledHeaderThrough = option+3;
874             break;
875         default:
876             found = false; break;
877         }
878         break;
879     case 'Z':
880         switch (second) {
881         case '7':
882             DebugInformationFormat = debugOldStyleInfo;
883             break;
884         case 'I':
885             DebugInformationFormat = debugEditAndContinue;
886             break;
887         case 'd':
888             DebugInformationFormat = debugLineInfoOnly;
889             break;
890         case 'i':
891             DebugInformationFormat = debugEnabled;
892             break;
893         case 'l':
894             OmitDefaultLibName = _True;
895             break;
896         case 'a':
897             DisableLanguageExtensions = _True;
898             break;
899         case 'e':
900             DisableLanguageExtensions = _False;
901             break;
902         case 'c':
903             if(third == ':') {
904                 const char *c = option + 4;
905                 // Go to the end of the option
906                 while ( *c != '\0' && *c != ' ' && *c != '-')
907                     ++c;
908                 if(fourth == 'f')
909                     ForceConformanceInForLoopScope = ((*c) == '-' ? _False : _True);
910                 else if(fourth == 'w')
911                     TreatWChar_tAsBuiltInType = ((*c) == '-' ? _False : _True);
912                 else
913                     found = false;
914             } else {
915                 found = false; break;
916             }
917             break;
918         case 'g':
919         case 'm':
920         case 's':
921             AdditionalOptions += option;
922             break;
923         case 'p':
924             switch (third)
925             {
926             case '\0':
927             case '1':
928                 StructMemberAlignment = alignSingleByte;
929                 if(fourth == '6')
930                     StructMemberAlignment = alignSixteenBytes;
931                 break;
932             case '2':
933                 StructMemberAlignment = alignTwoBytes;
934                 break;
935             case '4':
936                 StructMemberAlignment = alignFourBytes;
937                 break;
938             case '8':
939                 StructMemberAlignment = alignEightBytes;
940                 break;
941             default:
942                 found = false; break;
943             }
944             break;
945         default:
946             found = false; break;
947         }
948         break;
949     case 'a':
950         if (second == 'r' && third == 'c' && fourth == 'h') {
951             if (option[5] == ':') {
952                 const char *o = option;
953                 if (o[6] == 'S' && o[7] == 'S' && o[8] == 'E') {
954                     EnableEnhancedInstructionSet = o[9] == '2' ? archSSE2 : archSSE;
955                     break;
956                 }
957             }
958         } else if (second == 'n' && third == 'a' && fourth == 'l') {
959             EnablePREfast = _True;
960             break;
961         }
962         found = false;
963         break;
964     case 'b':   // see http://msdn2.microsoft.com/en-us/library/ms173499.aspx
965         if (second == 'i' && third == 'g' && fourth == 'o') {
966             const char *o = option;
967             if (o[5] == 'b' && o[6] == 'j') {
968                 AdditionalOptions += option;
969                 break;
970             }
971         }
972         found = false;
973         break;
974     case 'c':
975         if(second == '\0') {
976             CompileOnly = _True;
977         } else if(second == 'l') {
978             if (config->CompilerVersion < NET2005) {
979                 if(*(option+5) == 'n') {
980                     CompileAsManaged = managedAssemblyPure;
981                     TurnOffAssemblyGeneration = _True;
982                 } else if(*(option+5) == 'p') {
983                     CompileAsManaged = managedAssemblyPure;
984                     warn_msg(WarnLogic, "/clr:pure option only for .NET >= 2005, using /clr");
985                 } else if(*(option+5) == 's') {
986                     CompileAsManaged = managedAssemblyPure;
987                     warn_msg(WarnLogic, "/clr:safe option only for .NET >= 2005, using /clr");
988                 } else if(*(option+5) == 'o') {
989                     CompileAsManaged = managedAssemblyPure;
990                     warn_msg(WarnLogic, "/clr:oldSyntax option only for .NET >= 2005, using /clr");
991                 } else if(*(option+5) == 'i') {
992                     CompileAsManaged = managedAssemblyPure;
993                     warn_msg(WarnLogic, "initialAppDomain enum value unknown, using /crl");
994                 } else {
995                     CompileAsManaged = managedAssemblyPure;
996                 }
997             } else {
998                 if(*(option+5) == 'n') {
999                     CompileAsManaged = managedAssembly;
1000                     TurnOffAssemblyGeneration = _True;
1001                 } else if(*(option+5) == 'p') {
1002                     CompileAsManaged = managedAssemblyPure;
1003                 } else if(*(option+5) == 's') {
1004                     CompileAsManaged = managedAssemblySafe;
1005                 } else if(*(option+5) == 'o') {
1006                     CompileAsManaged = managedAssemblyOldSyntax;
1007                 } else if(*(option+5) == 'i') {
1008                     CompileAsManaged = managedAssembly;
1009                     warn_msg(WarnLogic, "initialAppDomain enum value unknown, using /crl default");
1010                 } else {
1011                     CompileAsManaged = managedAssembly;
1012                 }
1013             }
1014         } else {
1015             found = false; break;
1016         }
1017         break;
1018     case 'd':
1019         if (second == 'r') {
1020             CompileAsManaged = managedAssembly;
1021             break;
1022         } else if (second != 'o' && third == 'c') {
1023             GenerateXMLDocumentationFiles = _True;
1024             XMLDocumentationFileName += option+4;
1025             break;
1026         }
1027         found = false;
1028         break;
1029     case 'e':
1030         if (second == 'r' && third == 'r' && fourth == 'o') {
1031             if (option[12] == ':') {
1032                 if ( option[13] == 'n') {
1033                     ErrorReporting = "None";
1034                 } else if (option[13] == 'p') {
1035                     ErrorReporting = "Prompt";
1036                 } else if (option[13] == 'q') {
1037                     ErrorReporting = "Queue";
1038                 } else if (option[13] == 's') {
1039                     ErrorReporting = "Send";
1040                 } else {
1041                     found = false;
1042                 }
1043                 break;
1044             }
1045         }
1046         found = false;
1047         break;
1048     case 'f':
1049         if(second == 'p' && third == ':') {
1050             // Go to the end of the option
1051             const char *c = option + 4;
1052             while (*c != '\0' && *c != ' ' && *c != '-')
1053                 ++c;
1054             switch (fourth) {
1055             case 'e':
1056                 FloatingPointExceptions = ((*c) == '-' ? _False : _True);
1057                 break;
1058             case 'f':
1059                 FloatingPointModel = floatingPointFast;
1060                 break;
1061             case 'p':
1062                 FloatingPointModel = floatingPointPrecise;
1063                 break;
1064             case 's':
1065                 FloatingPointModel = floatingPointStrict;
1066                 break;
1067             default:
1068                 found = false;
1069                 break;
1070             }
1071         }
1072         break;
1073     case 'n':
1074         if(second == 'o' && third == 'B' && fourth == 'o') {
1075             AdditionalOptions += "/noBool";
1076             break;
1077         }
1078         if(second == 'o' && third == 'l' && fourth == 'o') {
1079             SuppressStartupBanner = _True;
1080             break;
1081         }
1082         found = false; break;
1083     case 'o':
1084     {
1085         const char *str = option + 2;
1086         const size_t len = strlen(str);
1087         if (len >= 5 && len <= 6 && strncmp(str, "penmp", 5) == 0) {
1088             if (len == 5) {
1089                 OpenMP = _True;
1090                 break;
1091             } else if (str[5] == '-') {
1092                 OpenMP = _False;
1093                 break;
1094             }
1095         }
1096         found = false; break;
1097     }
1098     case 's':
1099         if(second == 'h' && third == 'o' && fourth == 'w') {
1100             ShowIncludes = _True;
1101             break;
1102         }
1103         found = false; break;
1104     case 'u':
1105         UndefineAllPreprocessorDefinitions = _True;
1106         break;
1107     case 'v':
1108         if(second == 'd' || second == 'm') {
1109             AdditionalOptions += option;
1110             break;
1111         }
1112         found = false; break;
1113     case 'w':
1114         switch (second) {
1115         case '\0':
1116             WarningLevel = warningLevel_0;
1117             break;
1118         case 'd':
1119             DisableSpecificWarnings += option+3;
1120             break;
1121         case 'e':
1122             if (config->CompilerVersion <= NET2008)
1123                 AdditionalOptions += option;
1124             else
1125                 TreatSpecificWarningsAsErrors += option + 3;
1126             break;
1127         default:
1128             AdditionalOptions += option;
1129         }
1130         break;
1131     default:
1132         AdditionalOptions += option;
1133         break;
1134     }
1135     if(!found) {
1136         warn_msg(WarnLogic, "Could not parse Compiler option: %s, added as AdditionalOption", option);
1137         AdditionalOptions += option;
1138     }
1139     return true;
1140 }
1141
1142 bool VCCLCompilerTool::parseRuntimeCheckOption(char c, int *rtc)
1143 {
1144     if (c == '1')
1145         *rtc = runtimeBasicCheckAll;
1146     else if (c == 'c')
1147         SmallerTypeCheck = _True;
1148     else if (c == 's')
1149         *rtc |= runtimeCheckStackFrame;
1150     else if (c == 'u')
1151         *rtc |= runtimeCheckUninitVariables;
1152     else
1153         return false;
1154     return true;
1155 }
1156
1157 // VCLinkerTool -----------------------------------------------------
1158 VCLinkerTool::VCLinkerTool()
1159     :   DataExecutionPrevention(unset),
1160         EnableCOMDATFolding(optFoldingDefault),
1161         GenerateDebugInformation(unset),
1162         GenerateMapFile(unset),
1163         HeapCommitSize(-1),
1164         HeapReserveSize(-1),
1165         IgnoreAllDefaultLibraries(unset),
1166         IgnoreEmbeddedIDL(unset),
1167         IgnoreImportLibrary(_True),
1168         LargeAddressAware(addrAwareDefault),
1169         LinkDLL(unset),
1170         LinkIncremental(linkIncrementalDefault),
1171         LinkTimeCodeGeneration(optLTCGDefault),
1172         MapExports(unset),
1173         MapLines(unset),
1174         OptimizeForWindows98(optWin98Default),
1175         OptimizeReferences(optReferencesDefault),
1176         RandomizedBaseAddress(unset),
1177         RegisterOutput(unset),
1178         ResourceOnlyDLL(unset),
1179         SetChecksum(unset),
1180         ShowProgress(linkProgressNotSet),
1181         StackCommitSize(-1),
1182         StackReserveSize(-1),
1183         SubSystem(subSystemNotSet),
1184         SupportUnloadOfDelayLoadedDLL(unset),
1185         SuppressStartupBanner(unset),
1186         SwapRunFromCD(unset),
1187         SwapRunFromNet(unset),
1188         TargetMachine(machineNotSet),
1189         TerminalServerAware(termSvrAwareDefault),
1190         TreatWarningsAsErrors(unset),
1191         TurnOffAssemblyGeneration(unset),
1192         TypeLibraryResourceID(0),
1193         GenerateManifest(unset),
1194         EnableUAC(unset),
1195         UACUIAccess(unset),
1196         SectionAlignment(-1),
1197         PreventDllBinding(unset),
1198         AllowIsolation(unset),
1199         AssemblyDebug(unset),
1200         CLRUnmanagedCodeCheck(unset),
1201         DelaySign(unset)
1202 {
1203 }
1204
1205 // Hashing routine to do fast option lookups ----
1206 // Slightly rewritten to stop on ':' ',' and '\0'
1207 // Original routine in qtranslator.cpp ----------
1208 static uint elfHash(const char* name)
1209 {
1210     const uchar *k;
1211     uint h = 0;
1212     uint g;
1213
1214     if(name) {
1215         k = (const uchar *) name;
1216         while((*k) &&
1217                 (*k)!= ':' &&
1218                 (*k)!=',' &&
1219                 (*k)!=' ') {
1220             h = (h << 4) + *k++;
1221             if((g = (h & 0xf0000000)) != 0)
1222                 h ^= g >> 24;
1223             h &= ~g;
1224         }
1225     }
1226     if(!h)
1227         h = 1;
1228     return h;
1229 }
1230
1231 //#define USE_DISPLAY_HASH
1232 #ifdef USE_DISPLAY_HASH
1233 static void displayHash(const char* str)
1234 {
1235     printf("case 0x%07x: // %s\n    break;\n", elfHash(str), str);
1236 }
1237 #endif
1238
1239 bool VCLinkerTool::parseOption(const char* option)
1240 {
1241 #ifdef USE_DISPLAY_HASH
1242     // Main options
1243     displayHash("/ALIGN"); displayHash("/ALLOWBIND"); displayHash("/ASSEMBLYMODULE");
1244     displayHash("/ASSEMBLYRESOURCE"); displayHash("/BASE"); displayHash("/DEBUG");
1245     displayHash("/DEF"); displayHash("/DEFAULTLIB"); displayHash("/DELAY");
1246     displayHash("/DELAYLOAD"); displayHash("/DLL"); displayHash("/DRIVER");
1247     displayHash("/ENTRY"); displayHash("/EXETYPE"); displayHash("/EXPORT");
1248     displayHash("/FIXED"); displayHash("/FORCE"); displayHash("/HEAP");
1249     displayHash("/IDLOUT"); displayHash("/IGNORE"); displayHash("/IGNOREIDL"); displayHash("/IMPLIB");
1250     displayHash("/INCLUDE"); displayHash("/INCREMENTAL"); displayHash("/LARGEADDRESSAWARE");
1251     displayHash("/LIBPATH"); displayHash("/LTCG"); displayHash("/MACHINE");
1252     displayHash("/MAP"); displayHash("/MAPINFO"); displayHash("/MERGE");
1253     displayHash("/MIDL"); displayHash("/NOASSEMBLY"); displayHash("/NODEFAULTLIB");
1254     displayHash("/NOENTRY"); displayHash("/NOLOGO"); displayHash("/OPT");
1255     displayHash("/ORDER"); displayHash("/OUT"); displayHash("/PDB");
1256     displayHash("/PDBSTRIPPED"); displayHash("/RELEASE"); displayHash("/SECTION");
1257     displayHash("/STACK"); displayHash("/STUB"); displayHash("/SUBSYSTEM");
1258     displayHash("/SWAPRUN"); displayHash("/TLBID"); displayHash("/TLBOUT");
1259     displayHash("/TSAWARE"); displayHash("/VERBOSE"); displayHash("/VERSION");
1260     displayHash("/VXD"); displayHash("/WS "); displayHash("/libpath");
1261
1262 #endif
1263 #ifdef USE_DISPLAY_HASH
1264     // Sub options
1265     displayHash("UNLOAD"); displayHash("NOBIND"); displayHash("no"); displayHash("NOSTATUS"); displayHash("STATUS");
1266     displayHash("AM33"); displayHash("ARM"); displayHash("CEE"); displayHash("EBC"); displayHash("IA64"); displayHash("X86"); displayHash("X64"); displayHash("M32R");
1267     displayHash("MIPS"); displayHash("MIPS16"); displayHash("MIPSFPU"); displayHash("MIPSFPU16"); displayHash("MIPSR41XX"); displayHash("PPC");
1268     displayHash("SH3"); displayHash("SH3DSP"); displayHash("SH4"); displayHash("SH5"); displayHash("THUMB"); displayHash("TRICORE"); displayHash("EXPORTS");
1269     displayHash("LINES"); displayHash("REF"); displayHash("NOREF"); displayHash("ICF"); displayHash("WIN98"); displayHash("NOWIN98");
1270     displayHash("CONSOLE"); displayHash("EFI_APPLICATION"); displayHash("EFI_BOOT_SERVICE_DRIVER"); displayHash("EFI_ROM"); displayHash("EFI_RUNTIME_DRIVER"); displayHash("NATIVE");
1271     displayHash("POSIX"); displayHash("WINDOWS"); displayHash("WINDOWSCE"); displayHash("NET"); displayHash("CD"); displayHash("NO");
1272 #endif
1273     bool found = true;
1274     const uint optionHash = elfHash(option);
1275     if (config->CompilerVersion < NET2010) {
1276         switch (optionHash) {
1277         case 0x3360dbe: // /ALIGN[:number]
1278         case 0x1485c34: // /ALLOWBIND[:NO]
1279         case 0x33aec94: // /FIXED[:NO]
1280         case 0x7988f7e: // /SECTION:name,[E][R][W][S][D][K][L][P][X][,ALIGN=#]
1281         case 0x0348992: // /STUB:filename
1282             AdditionalOptions += option;
1283             return true;
1284         }
1285     }
1286
1287     switch (optionHash) {
1288     case 0x6b21972: // /DEFAULTLIB:library
1289     case 0x396ea92: // /DRIVER[:UPONLY | :WDM]
1290     case 0xaca9d75: // /EXETYPE[:DYNAMIC | :DEV386]
1291     case 0x3ad5444: // /EXPORT:entryname[,@ordinal[,NONAME]][,DATA]
1292     case 0x33b4675: // /FORCE:[MULTIPLE|UNRESOLVED]
1293     case 0x3dc3455: // /IGNORE:number,number,number,number  ### NOTE: This one is undocumented, but it is even used by Microsoft.
1294                     //                                      In recent versions of the Microsoft linker they have disabled this undocumented feature.
1295     case 0x0034bc4: // /VXD
1296         AdditionalOptions += option;
1297         break;
1298     case 0x3360dbe: // /ALIGN[:number]
1299         SectionAlignment = QString(option+7).toLongLong();
1300         break;
1301     case 0x1485c34: // /ALLOWBIND[:NO]
1302         if(*(option+10) == ':' && (*(option+11) == 'n' || *(option+11) == 'N'))
1303             PreventDllBinding = _False;
1304         else
1305             PreventDllBinding = _True;
1306         break;
1307     case 0x312011e: // /ALLOWISOLATION[:NO]
1308         if(*(option+15) == ':' && (*(option+16) == 'n' || *(option+16) == 'N'))
1309             AllowIsolation = _False;
1310         else
1311             AllowIsolation = _True;
1312         break;
1313     case 0x679c075: // /ASSEMBLYMODULE:filename
1314         AddModuleNamesToAssembly += option+15;
1315         break;
1316     case 0x75f35f7: // /ASSEMBLYDEBUG[:DISABLE]
1317         if(*(option+14) == ':' && (*(option+15) == 'D'))
1318             AssemblyDebug = _False;
1319         else
1320             AssemblyDebug = _True;
1321         break;
1322     case 0x43294a5: // /ASSEMBLYLINKRESOURCE:filename
1323             AssemblyLinkResource += option+22;
1324         break;
1325     case 0x062d065: // /ASSEMBLYRESOURCE:filename
1326         LinkToManagedResourceFile = option+18;
1327         break;
1328     case 0x0336675: // /BASE:{address | @filename,key}
1329         // Do we need to do a manual lookup when '@filename,key'?
1330         // Seems BaseAddress only can contain the location...
1331         // We don't use it in Qt, so keep it simple for now
1332         BaseAddress = option+6;
1333         break;
1334     case 0x63bf065: // /CLRIMAGETYPE:{IJW|PURE|SAFE}
1335         if(*(option+14) == 'I')
1336             CLRImageType = "ForceIJWImage";
1337         else if(*(option+14) == 'P')
1338             CLRImageType = "ForcePureILImage";
1339         else if(*(option+14) == 'S')
1340             CLRImageType = "ForceSafeILImage";
1341         break;
1342     case 0x5f2a6a2: // /CLRSUPPORTLASTERROR{:NO | SYSTEMDLL}
1343         if(*(option+20) == ':') {
1344             if(*(option+21) == 'N') {
1345                 CLRSupportLastError = "Disabled";
1346             } else if(*(option+21) == 'S') {
1347                 CLRSupportLastError = "SystemDlls";
1348             }
1349         } else {
1350             CLRSupportLastError = "Enabled";
1351         }
1352         break;
1353     case 0xc7984f5: // /CLRTHREADATTRIBUTE:{STA|MTA|NONE}
1354         if(*(option+20) == 'N')
1355             CLRThreadAttribute = "DefaultThreadingAttribute";
1356         else if(*(option+20) == 'M')
1357             CLRThreadAttribute = "MTAThreadingAttribute";
1358         else if(*(option+20) == 'S')
1359             CLRThreadAttribute = "STAThreadingAttribute";
1360         break;
1361     case 0xa8c637b: // /CLRUNMANAGEDCODECHECK[:NO]
1362         if(*(option+23) == 'N')
1363             CLRUnmanagedCodeCheck = _False;
1364         else
1365             CLRUnmanagedCodeCheck = _True;
1366         break;
1367     case 0x62d9e94: // /MANIFEST[:NO]
1368         if ((*(option+9) == ':' && (*(option+10) == 'N' || *(option+10) == 'n')))
1369             GenerateManifest = _False;
1370         else
1371             GenerateManifest = _True;
1372         break;
1373     case 0x8b64559: // /MANIFESTDEPENDENCY:manifest_dependency
1374         AdditionalManifestDependencies += option+20;
1375         break;
1376     case 0xe9e8195: // /MANIFESTFILE:filename
1377         ManifestFile = option+14;
1378         break;
1379     case 0x9e9fb83: // /MANIFESTUAC http://msdn.microsoft.com/en-us/library/bb384691%28VS.100%29.aspx
1380         if ((*(option+12) == ':' && (*(option+13) == 'N' || *(option+13) == 'n')))
1381             EnableUAC = _False;
1382         else if((*(option+12) == ':' && (*(option+13) == 'l' || *(option+14) == 'e'))) { // level
1383             if(*(option+20) == 'a')
1384                 UACExecutionLevel = "AsInvoker";
1385             else if(*(option+20) == 'h')
1386                 UACExecutionLevel = "HighestAvailable";
1387             else if(*(option+20) == 'r')
1388                 UACExecutionLevel = "RequireAdministrator";
1389         } else if((*(option+12) == ':' && (*(option+13) == 'u' || *(option+14) == 'i'))) { // uiAccess
1390             if(*(option+22) == 't')
1391                 UACUIAccess = _True;
1392             else
1393                 UACUIAccess = _False;
1394         } else if((*(option+12) == ':' && (*(option+13) == 'f' || *(option+14) == 'r'))) { // fragment
1395             AdditionalOptions += option;
1396         }else
1397             EnableUAC = _True;
1398         break;
1399     case 0x3389797: // /DEBUG
1400         GenerateDebugInformation = _True;
1401         break;
1402     case 0x0033896: // /DEF:filename
1403         ModuleDefinitionFile = option+5;
1404         break;
1405     case 0x338a069: // /DELAY:{UNLOAD | NOBIND}
1406         // MS documentation does not specify what to do with
1407         // this option, so we'll put it in AdditionalOptions
1408         AdditionalOptions += option;
1409         break;
1410     case 0x06f4bf4: // /DELAYLOAD:dllname
1411         DelayLoadDLLs += option+11;
1412         break;
1413     case 0x06d451e: // /DELAYSIGN[:NO]
1414         if(*(option+10) == ':' && (*(option+11) == 'n' || *(option+11) == 'N'))
1415             DelaySign = _False;
1416         else
1417             DelaySign = _True;
1418         break;
1419     case 0x003390c: // /DLL
1420         // This option is not used for vcproj files
1421         break;
1422     case 0x2ee8415: // /DYNAMICBASE[:NO]
1423         if(*(option+12) == ':' && (*(option+13) == 'n' || *(option+13) == 'N'))
1424             RandomizedBaseAddress = _False;
1425         else
1426             RandomizedBaseAddress = _True;
1427         break;
1428     case 0x33a3979: // /ENTRY:function
1429         EntryPointSymbol = option+7;
1430         break;
1431     case 0x4504334: // /ERRORREPORT:[ NONE | PROMPT | QUEUE | SEND ]
1432         if(*(option+12) == ':' ) {
1433             if(*(option+13) == 'N')
1434                 LinkErrorReporting = "NoErrorReport";
1435             else if(*(option+13) == 'P')
1436                 LinkErrorReporting = "PromptImmediately";
1437             else if(*(option+13) == 'Q')
1438                 LinkErrorReporting = "QueueForNextLogin";
1439             else if(*(option+13) == 'S')
1440                 LinkErrorReporting = "SendErrorReport";
1441         }
1442         break;
1443     case 0x033c960: // /HEAP:reserve[,commit]
1444         {
1445             QStringList both = QString(option+6).split(",");
1446             HeapReserveSize = both[0].toLongLong();
1447             if(both.count() == 2)
1448                 HeapCommitSize = both[1].toLongLong();
1449         }
1450         break;
1451     case 0x3d91494: // /IDLOUT:[path\]filename
1452         MergedIDLBaseFileName = option+8;
1453         break;
1454     case 0x345a04c: // /IGNOREIDL
1455         IgnoreEmbeddedIDL = _True;
1456         break;
1457     case 0x3e250e2: // /IMPLIB:filename
1458         ImportLibrary = option+8;
1459         break;
1460     case 0xe281ab5: // /INCLUDE:symbol
1461         ForceSymbolReferences += option+9;
1462         break;
1463     case 0xb28103c: // /INCREMENTAL[:no]
1464         if(*(option+12) == ':' &&
1465              (*(option+13) == 'n' || *(option+13) == 'N'))
1466             LinkIncremental = linkIncrementalNo;
1467         else
1468             LinkIncremental = linkIncrementalYes;
1469         break;
1470     case 0x07f1ab2: // /KEYCONTAINER:name
1471         KeyContainer = option+14;
1472         break;
1473     case 0xfadaf35: // /KEYFILE:filename
1474         KeyFile = option+9;
1475         break;
1476     case 0x26e4675: // /LARGEADDRESSAWARE[:no]
1477         if(*(option+18) == ':' &&
1478              *(option+19) == 'n')
1479             LargeAddressAware = addrAwareNoLarge;
1480         else
1481             LargeAddressAware = addrAwareLarge;
1482         break;
1483     case 0x2f96bc8: // /libpath:dir
1484     case 0x0d745c8: // /LIBPATH:dir
1485         AdditionalLibraryDirectories += option+9;
1486         break;
1487     case 0x0341877: // /LTCG[:NOSTATUS|:STATUS]
1488         config->WholeProgramOptimization = _True;
1489         if (config->CompilerVersion >= NET2005) {
1490             LinkTimeCodeGeneration = optLTCGEnabled;
1491             if(*(option+5) == ':') {
1492                 const char* str = option+6;
1493                 if (*str == 'S')
1494                     ShowProgress = linkProgressAll;
1495 #ifndef Q_OS_WIN
1496                 else if (strncasecmp(str, "pginstrument", 12))
1497                     LinkTimeCodeGeneration = optLTCGInstrument;
1498                 else if (strncasecmp(str, "pgoptimize", 10))
1499                     LinkTimeCodeGeneration = optLTCGOptimize;
1500                 else if (strncasecmp(str, "pgupdate", 8 ))
1501                     LinkTimeCodeGeneration = optLTCGUpdate;
1502 #else
1503                 else if (_stricmp(str, "pginstrument"))
1504                     LinkTimeCodeGeneration = optLTCGInstrument;
1505                 else if (_stricmp(str, "pgoptimize"))
1506                     LinkTimeCodeGeneration = optLTCGOptimize;
1507                 else if (_stricmp(str, "pgupdate"))
1508                     LinkTimeCodeGeneration = optLTCGUpdate;
1509 #endif
1510             }
1511         } else {
1512             AdditionalOptions.append(option);
1513         }
1514         break;
1515         case 0x379ED25:
1516     case 0x157cf65: // /MACHINE:{AM33|ARM|CEE|IA64|X86|M32R|MIPS|MIPS16|MIPSFPU|MIPSFPU16|MIPSR41XX|PPC|SH3|SH4|SH5|THUMB|TRICORE}
1517         switch (elfHash(option+9)) {
1518         // Very limited documentation on all options but X86,
1519         case 0x0005bb6: // X86
1520             TargetMachine = machineX86;
1521             break;
1522         case 0x0005b94: // X64
1523             TargetMachine = machineX64;
1524             break;
1525         // so we put the others in AdditionalOptions...
1526         case 0x0046063: // AM33
1527         case 0x000466d: // ARM
1528         case 0x0004795: // CEE
1529         case 0x0004963: // EBC
1530         case 0x004d494: // IA64
1531         case 0x0050672: // M32R
1532         case 0x0051e53: // MIPS
1533         case 0x51e5646: // MIPS16
1534         case 0x1e57b05: // MIPSFPU
1535         case 0x57b09a6: // MIPSFPU16
1536         case 0x5852738: // MIPSR41XX
1537         case 0x0005543: // PPC
1538         case 0x00057b3: // SH3
1539         case 0x57b7980: // SH3DSP
1540         case 0x00057b4: // SH4
1541         case 0x00057b5: // SH5
1542         case 0x058da12: // THUMB
1543         case 0x96d8435: // TRICORE
1544         default:
1545             AdditionalOptions += option;
1546             break;
1547         }
1548         break;
1549     case 0x0034160: // /MAP[:filename]
1550         GenerateMapFile = _True;
1551         if (option[4] == ':')
1552             MapFileName = option+5;
1553         break;
1554     case 0x164e1ef: // /MAPINFO:{EXPORTS|LINES}
1555         if(*(option+9) == 'E')
1556             MapExports = _True;
1557         else if(*(option+9) == 'L')
1558             MapLines = _True;
1559         break;
1560     case 0x341a6b5: // /MERGE:from=to
1561         MergeSections = option+7;
1562         break;
1563     case 0x0341d8c: // /MIDL:@file
1564         MidlCommandFile = option+7;
1565         break;
1566     case 0x84e2679: // /NOASSEMBLY
1567         TurnOffAssemblyGeneration = _True;
1568         break;
1569     case 0x2b21942: // /NODEFAULTLIB[:library]
1570         if(*(option+13) == '\0')
1571             IgnoreAllDefaultLibraries = _True;
1572         else
1573             IgnoreDefaultLibraryNames += option+14;
1574         break;
1575     case 0x33a3a39: // /NOENTRY
1576         ResourceOnlyDLL = _True;
1577         break;
1578     case 0x434138f: // /NOLOGO
1579         SuppressStartupBanner = _True;
1580         break;
1581     case 0xc841054: // /NXCOMPAT[:NO]
1582         if ((*(option+9) == ':' && (*(option+10) == 'N' || *(option+10) == 'n')))
1583             DataExecutionPrevention = _False;
1584         else
1585             DataExecutionPrevention = _True;
1586         break;
1587     case 0x0034454: // /OPT:{REF | NOREF | ICF[=iterations] | NOICF | WIN98 | NOWIN98}
1588         {
1589             char third = *(option+7);
1590             switch (third) {
1591             case 'F': // REF
1592                 if(*(option+5) == 'R') {
1593                     OptimizeReferences = optReferences;
1594                 } else { // ICF[=iterations]
1595                     EnableCOMDATFolding = optFolding;
1596                     // [=iterations] case is not documented
1597                 }
1598                 break;
1599             case 'R': // NOREF
1600                 OptimizeReferences = optNoReferences;
1601                 break;
1602             case 'I': // NOICF
1603                 EnableCOMDATFolding = optNoFolding;
1604                 break;
1605             case 'N': // WIN98
1606                 OptimizeForWindows98 = optWin98Yes;
1607                 break;
1608             case 'W': // NOWIN98
1609                 OptimizeForWindows98 = optWin98No;
1610                 break;
1611             default:
1612                 found = false;
1613             }
1614         }
1615         break;
1616     case 0x34468a2: // /ORDER:@filename
1617         FunctionOrder = option+8;
1618         break;
1619     case 0x00344a4: // /OUT:filename
1620         OutputFile = option+5;
1621         break;
1622     case 0x0034482: // /PDB:filename
1623         ProgramDatabaseFile = option+5;
1624         break;
1625     case 0xa2ad314: // /PDBSTRIPPED:pdb_file_name
1626         StripPrivateSymbols = option+13;
1627         break;
1628     case 0x6a09535: // /RELEASE
1629         SetChecksum = _True;
1630         break;
1631     case 0x348857b: // /STACK:reserve[,commit]
1632         {
1633             QStringList both = QString(option+7).split(",");
1634             StackReserveSize = both[0].toLongLong();
1635             if(both.count() == 2)
1636                 StackCommitSize = both[1].toLongLong();
1637         }
1638         break;
1639     case 0x75AA4D8: // /SAFESH:{NO}
1640         {
1641             AdditionalOptions += option;
1642             break;
1643         }
1644         case 0x9B3C00D:
1645     case 0x78dc00d: // /SUBSYSTEM:{CONSOLE|EFI_APPLICATION|EFI_BOOT_SERVICE_DRIVER|EFI_ROM|EFI_RUNTIME_DRIVER|NATIVE|POSIX|WINDOWS|WINDOWSCE}[,major[.minor]]
1646         {
1647             // Split up in subsystem, and version number
1648             QStringList both = QString(option+11).split(",");
1649             switch (elfHash(both[0].toLatin1())) {
1650             case 0x8438445: // CONSOLE
1651                 SubSystem = subSystemConsole;
1652                 break;
1653             case 0xbe29493: // WINDOWS
1654                 SubSystem = subSystemWindows;
1655                 break;
1656             // The following are undocumented, so add them to AdditionalOptions
1657             case 0x240949e: // EFI_APPLICATION
1658             case 0xe617652: // EFI_BOOT_SERVICE_DRIVER
1659             case 0x9af477d: // EFI_ROM
1660             case 0xd34df42: // EFI_RUNTIME_DRIVER
1661             case 0x5268ea5: // NATIVE
1662             case 0x05547e8: // POSIX
1663             case 0x2949c95: // WINDOWSCE
1664             case 0x4B69795: // windowsce
1665                 AdditionalOptions += option;
1666                 break;
1667             default:
1668                 found = false;
1669             }
1670         }
1671         break;
1672     case 0x8b654de: // /SWAPRUN:{NET | CD}
1673         if(*(option+9) == 'N')
1674             SwapRunFromNet = _True;
1675         else if(*(option+9) == 'C')
1676             SwapRunFromCD = _True;
1677         else
1678             found = false;
1679         break;
1680     case 0x34906d4: // /TLBID:id
1681         TypeLibraryResourceID = QString(option+7).toLongLong();
1682         break;
1683     case 0x4907494: // /TLBOUT:[path\]filename
1684         TypeLibraryFile = option+8;
1685         break;
1686     case 0x976b525: // /TSAWARE[:NO]
1687         if(*(option+8) == ':')
1688             TerminalServerAware = termSvrAwareNo;
1689         else
1690             TerminalServerAware = termSvrAwareYes;
1691         break;
1692     case 0xaa67735: // /VERBOSE[:lib]
1693         if(*(option+9) == ':') {
1694             ShowProgress = linkProgressLibs;
1695             AdditionalOptions += option;
1696         } else {
1697             ShowProgress = linkProgressAll;
1698         }
1699         break;
1700     case 0xaa77f7e: // /VERSION:major[.minor]
1701         Version = option+9;
1702         break;
1703     case 0x0034c50: // /WS[:NO]
1704         if (config->CompilerVersion >= NET2010) {
1705             if(*(option+3) == ':')
1706                 TreatWarningsAsErrors = _False;
1707             else
1708                 TreatWarningsAsErrors = _True;
1709         } else {
1710             AdditionalOptions += option;
1711         }
1712         break;
1713     default:
1714         AdditionalOptions += option;
1715         break;
1716     }
1717     if(!found) {
1718         warn_msg(WarnLogic, "Could not parse Linker options: %s, added as AdditionalOption", option);
1719         AdditionalOptions += option;
1720     }
1721     return found;
1722 }
1723
1724 // VCMIDLTool -------------------------------------------------------
1725 VCMIDLTool::VCMIDLTool()
1726     :        DefaultCharType(midlCharUnsigned),
1727         EnableErrorChecks(midlDisableAll),
1728         ErrorCheckAllocations(unset),
1729         ErrorCheckBounds(unset),
1730         ErrorCheckEnumRange(unset),
1731         ErrorCheckRefPointers(unset),
1732         ErrorCheckStubData(unset),
1733         GenerateStublessProxies(unset),
1734         GenerateTypeLibrary(unset),
1735         IgnoreStandardIncludePath(unset),
1736         MkTypLibCompatible(unset),
1737         StructMemberAlignment(midlAlignNotSet),
1738         SuppressStartupBanner(unset),
1739         TargetEnvironment(midlTargetNotSet),
1740         ValidateParameters(unset),
1741         WarnAsError(unset),
1742         WarningLevel(midlWarningLevel_0),
1743         ApplicationConfigurationMode(unset),
1744         ValidateAllParameters(unset),
1745         SuppressCompilerWarnings(unset),
1746         LocaleID(-1)
1747 {
1748 }
1749
1750 bool VCMIDLTool::parseOption(const char* option)
1751 {
1752 #ifdef USE_DISPLAY_HASH
1753     displayHash("/D name[=def]"); displayHash("/I directory-list"); displayHash("/Oi");
1754     displayHash("/Oic"); displayHash("/Oicf"); displayHash("/Oif"); displayHash("/Os");
1755     displayHash("/U name"); displayHash("/WX"); displayHash("/W{0|1|2|3|4}");
1756     displayHash("/Zp {N}"); displayHash("/Zs"); displayHash("/acf filename");
1757     displayHash("/align {N}"); displayHash("/app_config"); displayHash("/c_ext");
1758     displayHash("/char ascii7"); displayHash("/char signed"); displayHash("/char unsigned");
1759     displayHash("/client none"); displayHash("/client stub"); displayHash("/confirm");
1760     displayHash("/cpp_cmd cmd_line"); displayHash("/cpp_opt options");
1761     displayHash("/cstub filename"); displayHash("/dlldata filename"); displayHash("/env win32");
1762     displayHash("/env win64"); displayHash("/error all"); displayHash("/error allocation");
1763     displayHash("/error bounds_check"); displayHash("/error enum"); displayHash("/error none");
1764     displayHash("/error ref"); displayHash("/error stub_data"); displayHash("/h filename");
1765     displayHash("/header filename"); displayHash("/iid filename"); displayHash("/lcid");
1766     displayHash("/mktyplib203"); displayHash("/ms_ext"); displayHash("/ms_union");
1767     displayHash("/msc_ver <nnnn>"); displayHash("/newtlb"); displayHash("/no_cpp");
1768     displayHash("/no_def_idir"); displayHash("/no_default_epv"); displayHash("/no_format_opt");
1769     displayHash("/no_warn"); displayHash("/nocpp"); displayHash("/nologo"); displayHash("/notlb");
1770     displayHash("/o filename"); displayHash("/oldnames"); displayHash("/oldtlb");
1771     displayHash("/osf"); displayHash("/out directory"); displayHash("/pack {N}");
1772     displayHash("/prefix all"); displayHash("/prefix client"); displayHash("/prefix server");
1773     displayHash("/prefix switch"); displayHash("/protocol all"); displayHash("/protocol dce");
1774     displayHash("/protocol ndr64"); displayHash("/proxy filename"); displayHash("/robust");
1775     displayHash("/rpcss"); displayHash("/savePP"); displayHash("/server none");
1776     displayHash("/server stub"); displayHash("/sstub filename"); displayHash("/syntax_check");
1777     displayHash("/target {system}"); displayHash("/tlb filename"); displayHash("/use_epv");
1778     displayHash("/win32"); displayHash("/win64");
1779 #endif
1780     bool found = true;
1781     int offset = 0;
1782
1783     const uint optionHash = elfHash(option);
1784
1785     if (config->CompilerVersion < NET2010) {
1786         switch (optionHash) {
1787         case 0x5b1cb97: // /app_config
1788         case 0x5a2fc64: // /client {none|stub}
1789         case 0x35aabb2: // /cstub filename
1790         case 0x64ceb12: // /newtlb
1791         case 0x556dbee: // /no_warn
1792         case 0x662bb12: // /oldtlb
1793         case 0x69c9cf2: // /server {none|stub}
1794         case 0x36aabb2: // /sstub filename
1795             AdditionalOptions += option;
1796             return true;
1797         }
1798     }
1799
1800     switch(optionHash) {
1801     case 0x0000334: // /D name[=def]
1802         PreprocessorDefinitions += option+3;
1803         break;
1804     case 0x0000339: // /I directory-list
1805         AdditionalIncludeDirectories += option+3;
1806         break;
1807     case 0x0345f96: // /Oicf
1808     case 0x00345f6: // /Oif
1809         GenerateStublessProxies = _True;
1810         break;
1811     case 0x0000345: // /U name
1812         UndefinePreprocessorDefinitions += option+3;
1813         break;
1814     case 0x00034c8: // /WX
1815         WarnAsError = _True;
1816         break;
1817     case 0x3582fde: // /align {N}
1818         offset = 3;  // Fallthrough
1819     case 0x0003510: // /Zp {N}
1820         switch (*(option+offset+4)) {
1821         case '1':
1822             StructMemberAlignment = (*(option+offset+5) == '\0') ? midlAlignSingleByte : midlAlignSixteenBytes;
1823             break;
1824         case '2':
1825             StructMemberAlignment = midlAlignTwoBytes;
1826             break;
1827         case '4':
1828             StructMemberAlignment = midlAlignFourBytes;
1829             break;
1830         case '8':
1831             StructMemberAlignment = midlAlignEightBytes;
1832             break;
1833         default:
1834             found = false;
1835         }
1836         break;
1837     case 0x5b1cb97: // /app_config
1838         ApplicationConfigurationMode = _True;
1839         break;
1840     case 0x0359e82: // /char {ascii7|signed|unsigned}
1841         switch(*(option+6)) {
1842         case 'a':
1843             DefaultCharType = midlCharAscii7;
1844             break;
1845         case 's':
1846             DefaultCharType = midlCharSigned;
1847             break;
1848         case 'u':
1849             DefaultCharType = midlCharUnsigned;
1850             break;
1851         default:
1852             found = false;
1853         }
1854         break;
1855     case 0x5a2fc64: // /client {none|stub}
1856         if(*(option+8) == 's')
1857             GenerateClientFiles = "Stub";
1858         else
1859             GenerateClientFiles = "None";
1860         break;
1861     case 0xa766524: // /cpp_opt options
1862         CPreprocessOptions += option+9;
1863         break;
1864     case 0x35aabb2: // /cstub filename
1865         ClientStubFile = option+7;
1866         break;
1867     case 0xb32abf1: // /dlldata filename
1868         DLLDataFileName = option + 9;
1869         break;
1870     case 0x0035c56: // /env {win32|win64}
1871         TargetEnvironment = (*(option+8) == '6') ? midlTargetWin64 : midlTargetWin32;
1872         break;
1873     case 0x35c9962: // /error {all|allocation|bounds_check|enum|none|ref|stub_data}
1874         EnableErrorChecks = midlEnableCustom;
1875         switch (*(option+7)) {
1876         case 'a':
1877             if(*(option+10) == '\0')
1878                 EnableErrorChecks = midlEnableAll;
1879             else
1880                 ErrorCheckAllocations = _True;
1881             break;
1882         case 'b':
1883             ErrorCheckBounds = _True;
1884             break;
1885         case 'e':
1886             ErrorCheckEnumRange = _True;
1887             break;
1888         case 'n':
1889             EnableErrorChecks = midlDisableAll;
1890             break;
1891         case 'r':
1892             ErrorCheckRefPointers = _True;
1893             break;
1894         case 's':
1895             ErrorCheckStubData = _True;
1896             break;
1897         default:
1898             found = false;
1899         }
1900         break;
1901     case 0x5eb7af2: // /header filename
1902         offset = 5;
1903     case 0x0000358: // /h filename
1904         HeaderFileName = option + offset + 3;
1905         break;
1906     case 0x0035ff4: // /iid filename
1907         InterfaceIdentifierFileName = option+5;
1908         break;
1909     case 0x64b7933: // /mktyplib203
1910         MkTypLibCompatible = _True;
1911         break;
1912     case 0x64ceb12: // /newtlb
1913         TypeLibFormat = "NewFormat";
1914         break;
1915     case 0x8e0b0a2: // /no_def_idir
1916         IgnoreStandardIncludePath = _True;
1917         break;
1918     case 0x65635ef: // /nologo
1919         SuppressStartupBanner = _True;
1920         break;
1921     case 0x695e9f4: // /no_robust
1922         ValidateAllParameters = _False;
1923         break;
1924     case 0x3656b22: // /notlb
1925         GenerateTypeLibrary = _True;
1926         break;
1927     case 0x556dbee: // /no_warn
1928         SuppressCompilerWarnings = _True;
1929         break;
1930     case 0x000035f: // /o filename
1931         RedirectOutputAndErrors = option+3;
1932         break;
1933     case 0x662bb12: // /oldtlb
1934         TypeLibFormat = "OldFormat";
1935         break;
1936     case 0x00366c4: // /out directory
1937         OutputDirectory = option+5;
1938         break;
1939     case 0x36796f9: // /proxy filename
1940         ProxyFileName = option+7;
1941         break;
1942     case 0x6959c94: // /robust
1943         ValidateParameters = _True;
1944         break;
1945     case 0x6a88df4: // /target {system}
1946         if(*(option+11) == '6')
1947             TargetEnvironment = midlTargetWin64;
1948         else
1949             TargetEnvironment = midlTargetWin32;
1950         break;
1951     case 0x69c9cf2: // /server {none|stub}
1952         if(*(option+8) == 's')
1953             GenerateServerFiles = "Stub";
1954         else
1955             GenerateServerFiles = "None";
1956         break;
1957     case 0x36aabb2: // /sstub filename
1958         ServerStubFile = option+7;
1959         break;
1960     case 0x0036b22: // /tlb filename
1961         TypeLibraryName = option+5;
1962         break;
1963     case 0x36e0162: // /win32
1964         TargetEnvironment = midlTargetWin32;
1965         break;
1966     case 0x36e0194: // /win64
1967         TargetEnvironment = midlTargetWin64;
1968         break;
1969     case 0x0003459: // /Oi
1970     case 0x00345f3: // /Oic
1971     case 0x0003463: // /Os
1972     case 0x0003513: // /Zs
1973     case 0x0035796: // /acf filename
1974     case 0x3595cf4: // /c_ext
1975     case 0xa64d3dd: // /confirm
1976     case 0xa765b64: // /cpp_cmd cmd_line
1977     case 0x03629f4: // /lcid
1978     case 0x6495cc4: // /ms_ext
1979     case 0x96c7a1e: // /ms_union
1980     case 0x4996fa2: // /msc_ver <nnnn>
1981     case 0x6555a40: // /no_cpp
1982     case 0xf64d6a6: // /no_default_epv
1983     case 0x6dd9384: // /no_format_opt
1984     case 0x3655a70: // /nocpp
1985     case 0x2b455a3: // /oldnames
1986     case 0x0036696: // /osf
1987     case 0x036679b: // /pack {N}
1988     case 0x678bd38: // /prefix {all|client|server|switch}
1989     case 0x96b702c: // /protocol {all|dce|ndr64}
1990     case 0x3696aa3: // /rpcss
1991     case 0x698ca60: // /savePP
1992     case 0xce9b12b: // /syntax_check
1993     case 0xc9b5f16: // /use_epv
1994         AdditionalOptions += option;
1995         break;
1996     default:
1997         // /W{0|1|2|3|4} case
1998         if(*(option+1) == 'W') {
1999             switch (*(option+2)) {
2000             case '0':
2001                 WarningLevel = midlWarningLevel_0;
2002                 break;
2003             case '1':
2004                 WarningLevel = midlWarningLevel_1;
2005                 break;
2006             case '2':
2007                 WarningLevel = midlWarningLevel_2;
2008                 break;
2009             case '3':
2010                 WarningLevel = midlWarningLevel_3;
2011                 break;
2012             case '4':
2013                 WarningLevel = midlWarningLevel_4;
2014                 break;
2015             default:
2016                 found = false;
2017             }
2018         }
2019         break;
2020     }
2021     if(!found)
2022         warn_msg(WarnLogic, "Could not parse MIDL option: %s", option);
2023     return true;
2024 }
2025
2026 // VCLibrarianTool --------------------------------------------------
2027 VCLibrarianTool::VCLibrarianTool()
2028     :        IgnoreAllDefaultLibraries(unset),
2029         SuppressStartupBanner(_True)
2030 {
2031 }
2032
2033 // VCCustomBuildTool ------------------------------------------------
2034 VCCustomBuildTool::VCCustomBuildTool()
2035 {
2036     ToolName = "VCCustomBuildTool";
2037 }
2038
2039 // VCResourceCompilerTool -------------------------------------------
2040 VCResourceCompilerTool::VCResourceCompilerTool()
2041     :   Culture(rcUseDefault),
2042         IgnoreStandardIncludePath(unset),
2043         ShowProgress(linkProgressNotSet),
2044         SuppressStartupBanner(unset)
2045 {
2046     PreprocessorDefinitions = QStringList("NDEBUG");
2047 }
2048
2049 // VCDeploymentTool --------------------------------------------
2050 VCDeploymentTool::VCDeploymentTool()
2051     :   RegisterOutput(registerNo)
2052 {
2053     DeploymentTag = "DeploymentTool";
2054     RemoteDirectory = "";
2055 }
2056
2057 VCEventTool::VCEventTool(const QString &eventName)
2058     : ExcludedFromBuild(unset)
2059 {
2060     EventName = eventName;
2061     ToolName = "VC";
2062     ToolName += eventName;
2063     ToolName += "Tool";
2064 }
2065
2066 // VCPostBuildEventTool ---------------------------------------------
2067 VCPostBuildEventTool::VCPostBuildEventTool()
2068     : VCEventTool("PostBuildEvent")
2069 {
2070 }
2071
2072 // VCPreBuildEventTool ----------------------------------------------
2073 VCPreBuildEventTool::VCPreBuildEventTool()
2074     : VCEventTool("PreBuildEvent")
2075 {
2076 }
2077
2078 // VCPreLinkEventTool -----------------------------------------------
2079 VCPreLinkEventTool::VCPreLinkEventTool()
2080     : VCEventTool("PreLinkEvent")
2081 {
2082 }
2083
2084 // VCConfiguration --------------------------------------------------
2085
2086 VCConfiguration::VCConfiguration()
2087     :        ATLMinimizesCRunTimeLibraryUsage(unset),
2088         BuildBrowserInformation(unset),
2089         CharacterSet(charSetNotSet),
2090         ConfigurationType(typeApplication),
2091         RegisterOutput(unset),
2092         UseOfATL(useATLNotSet),
2093         UseOfMfc(useMfcStdWin),
2094         WholeProgramOptimization(unset)
2095 {
2096     compiler.config = this;
2097     linker.config = this;
2098     idl.config = this;
2099     custom.config = this;
2100 }
2101
2102 // VCFilter ---------------------------------------------------------
2103 VCFilter::VCFilter()
2104     :   ParseFiles(unset),
2105         Config(0)
2106 {
2107     useCustomBuildTool = false;
2108     useCompilerTool = false;
2109 }
2110
2111 void VCFilter::addFile(const QString& filename)
2112 {
2113     Files += VCFilterFile(filename);
2114 }
2115
2116 void VCFilter::addFile(const VCFilterFile& fileInfo)
2117 {
2118     Files += VCFilterFile(fileInfo);
2119 }
2120
2121 void VCFilter::addFiles(const QStringList& fileList)
2122 {
2123     for (int i = 0; i < fileList.count(); ++i)
2124         addFile(fileList.at(i));
2125 }
2126
2127 void VCFilter::modifyPCHstage(QString str)
2128 {
2129     bool autogenSourceFile = Project->autogenPrecompCPP;
2130     bool pchThroughSourceFile = !Project->precompCPP.isEmpty();
2131     bool isCFile = false;
2132     for (QStringList::Iterator it = Option::c_ext.begin(); it != Option::c_ext.end(); ++it) {
2133         if (str.endsWith(*it)) {
2134             isCFile = true;
2135             break;
2136         }
2137     }
2138     bool isHFile = Option::hasFileExtension(str, Option::h_ext) && (str == Project->precompH);
2139     bool isCPPFile = pchThroughSourceFile && (str == Project->precompCPP);
2140
2141     if(!isCFile && !isHFile && !isCPPFile)
2142         return;
2143
2144     if(isHFile && pchThroughSourceFile) {
2145         if (autogenSourceFile) {
2146             useCustomBuildTool = true;
2147             QString toFile(Project->precompCPP);
2148             CustomBuildTool.Description = "Generating precompiled header source file '" + toFile + "' ...";
2149             CustomBuildTool.Outputs += toFile;
2150
2151             QStringList lines;
2152             CustomBuildTool.CommandLine +=
2153                 "echo /*-------------------------------------------------------------------- >" + toFile;
2154             lines << "* Precompiled header source file used by Visual Studio.NET to generate";
2155             lines << "* the .pch file.";
2156             lines << "*";
2157             lines << "* Due to issues with the dependencies checker within the IDE, it";
2158             lines << "* sometimes fails to recompile the PCH file, if we force the IDE to";
2159             lines << "* create the PCH file directly from the header file.";
2160             lines << "*";
2161             lines << "* This file is auto-generated by qmake since no PRECOMPILED_SOURCE was";
2162             lines << "* specified, and is used as the common stdafx.cpp. The file is only";
2163             lines << QLatin1String("* generated when creating ")
2164                      + (Config->CompilerVersion < NET2010 ? ".vcproj" : ".vcxproj")
2165                      + " project files, and is not used for";
2166             lines << "* command line compilations by nmake.";
2167             lines << "*";
2168             lines << "* WARNING: All changes made in this file will be lost.";
2169             lines << "--------------------------------------------------------------------*/";
2170             lines << "#include \"" + Project->precompHFilename + "\"";
2171             foreach(QString line, lines)
2172                 CustomBuildTool.CommandLine += "echo " + line + ">>" + toFile;
2173         }
2174         return;
2175     }
2176
2177     useCompilerTool = true;
2178     // Setup PCH options
2179     CompilerTool.UsePrecompiledHeader     = (isCFile ? pchNone : pchCreateUsingSpecific);
2180     CompilerTool.PrecompiledHeaderThrough = (isCPPFile ? Project->precompHFilename : QString("$(NOINHERIT)"));
2181     CompilerTool.ForcedIncludeFiles       = QStringList("$(NOINHERIT)");
2182 }
2183
2184 bool VCFilter::addExtraCompiler(const VCFilterFile &info)
2185 {
2186     const QStringList &extraCompilers = Project->extraCompilerSources.value(info.file);
2187     if (extraCompilers.isEmpty())
2188         return false;
2189
2190     QString inFile = info.file;
2191
2192     // is the extracompiler rule on a file with a built in compiler?
2193     const QStringList &objectMappedFile = Project->extraCompilerOutputs[inFile];
2194     bool hasBuiltIn = false;
2195     if (!objectMappedFile.isEmpty()) {
2196         hasBuiltIn = Project->hasBuiltinCompiler(objectMappedFile.at(0));
2197 //        qDebug("*** Extra compiler file has object mapped file '%s' => '%s'", qPrintable(inFile), qPrintable(objectMappedFile.join(" ")));
2198     }
2199
2200     CustomBuildTool.AdditionalDependencies.clear();
2201     CustomBuildTool.CommandLine.clear();
2202     CustomBuildTool.Description.clear();
2203     CustomBuildTool.Outputs.clear();
2204     CustomBuildTool.ToolPath.clear();
2205         CustomBuildTool.ToolName = QLatin1String(_VCCustomBuildTool);
2206
2207     for (int x = 0; x < extraCompilers.count(); ++x) {
2208         const QString &extraCompilerName = extraCompilers.at(x);
2209
2210         if (!Project->verifyExtraCompiler(extraCompilerName, inFile) && !hasBuiltIn)
2211             continue;
2212
2213         // All information about the extra compiler
2214         QString tmp_out = Project->project->first(extraCompilerName + ".output");
2215         QString tmp_cmd = Project->project->variables()[extraCompilerName + ".commands"].join(" ");
2216         QString tmp_cmd_name = Project->project->variables()[extraCompilerName + ".name"].join(" ");
2217         QStringList tmp_dep = Project->project->variables()[extraCompilerName + ".depends"];
2218         QString tmp_dep_cmd = Project->project->variables()[extraCompilerName + ".depend_command"].join(" ");
2219         QStringList configs = Project->project->variables()[extraCompilerName + ".CONFIG"];
2220         bool combined = configs.indexOf("combine") != -1;
2221
2222         QString cmd, cmd_name, out;
2223         QStringList deps, inputs;
2224         // Variabel replacement of output name
2225         out = Option::fixPathToTargetOS(
2226                     Project->replaceExtraCompilerVariables(tmp_out, inFile, QString()),
2227                     false);
2228
2229         // If file has built-in compiler, we've swapped the input and output of
2230         // the command, as we in Visual Studio cannot have a Custom Buildstep on
2231         // a file which uses a built-in compiler. We would in this case only get
2232         // the result from the extra compiler. If 'hasBuiltIn' is true, we know
2233         // that we're actually on the _output_file_ of the result, and we
2234         // therefore swap inFile and out below, since the extra-compiler still
2235         // must see it as the original way. If the result also has a built-in
2236         // compiler, too bad..
2237         if (hasBuiltIn) {
2238             out = inFile;
2239             inFile = objectMappedFile.at(0);
2240         }
2241
2242         // Dependency for the output
2243         if(!tmp_dep.isEmpty())
2244             deps = tmp_dep;
2245         if(!tmp_dep_cmd.isEmpty()) {
2246             // Execute dependency command, and add every line as a dep
2247             char buff[256];
2248             QString dep_cmd = Project->replaceExtraCompilerVariables(tmp_dep_cmd,
2249                                                                      Option::fixPathToLocalOS(inFile, true, false),
2250                                                                      out);
2251             if(Project->canExecute(dep_cmd)) {
2252                 dep_cmd.prepend(QLatin1String("cd ")
2253                                 + Project->escapeFilePath(Option::fixPathToLocalOS(Option::output_dir, false))
2254                                 + QLatin1String(" && "));
2255                 if(FILE *proc = QT_POPEN(dep_cmd.toLatin1().constData(), "r")) {
2256                     QString indeps;
2257                     while(!feof(proc)) {
2258                         int read_in = (int)fread(buff, 1, 255, proc);
2259                         if(!read_in)
2260                             break;
2261                         indeps += QByteArray(buff, read_in);
2262                     }
2263                     QT_PCLOSE(proc);
2264                     if(!indeps.isEmpty()) {
2265                         QStringList extradeps = indeps.split(QLatin1Char('\n'));
2266                         for (int i = 0; i < extradeps.count(); ++i) {
2267                             QString dd = extradeps.at(i).simplified();
2268                             if (!dd.isEmpty())
2269                                 deps += Project->fileFixify(dd, QString(), Option::output_dir);
2270                         }
2271                     }
2272                 }
2273             }
2274         }
2275         for (int i = 0; i < deps.count(); ++i)
2276             deps[i] = Option::fixPathToTargetOS(
2277                         Project->replaceExtraCompilerVariables(deps.at(i), inFile, out),
2278                         false).trimmed();
2279         // Command for file
2280         if (combined) {
2281             // Add dependencies for each file
2282             QStringList tmp_in = Project->project->variables()[extraCompilerName + ".input"];
2283             for (int a = 0; a < tmp_in.count(); ++a) {
2284                 const QStringList &files = Project->project->variables()[tmp_in.at(a)];
2285                 for (int b = 0; b < files.count(); ++b) {
2286                     deps += Project->findDependencies(files.at(b));
2287                     inputs += Option::fixPathToTargetOS(files.at(b), false);
2288                 }
2289             }
2290             deps += inputs; // input files themselves too..
2291
2292             // Replace variables for command w/all input files
2293             // ### join gives path issues with directories containing spaces!
2294             cmd = Project->replaceExtraCompilerVariables(tmp_cmd,
2295                                                          inputs.join(" "),
2296                                                          out);
2297         } else {
2298             deps += inFile; // input file itself too..
2299             cmd = Project->replaceExtraCompilerVariables(tmp_cmd,
2300                                                          inFile,
2301                                                          out);
2302         }
2303         // Name for command
2304         if(!tmp_cmd_name.isEmpty()) {
2305             cmd_name = Project->replaceExtraCompilerVariables(tmp_cmd_name, inFile, out);
2306         } else {
2307             int space = cmd.indexOf(' ');
2308             if(space != -1)
2309                 cmd_name = cmd.left(space);
2310             else
2311                 cmd_name = cmd;
2312             if((cmd_name[0] == '\'' || cmd_name[0] == '"') &&
2313                 cmd_name[0] == cmd_name[cmd_name.length()-1])
2314                 cmd_name = cmd_name.mid(1,cmd_name.length()-2);
2315         }
2316
2317         // Fixify paths
2318         for (int i = 0; i < deps.count(); ++i)
2319             deps[i] = Option::fixPathToTargetOS(deps[i], false);
2320
2321
2322         // Output in info.additionalFile -----------
2323         if (!CustomBuildTool.Description.isEmpty())
2324             CustomBuildTool.Description += ", ";
2325         CustomBuildTool.Description += cmd_name;
2326         CustomBuildTool.CommandLine += VCToolBase::fixCommandLine(cmd.trimmed());
2327         int space = cmd.indexOf(' ');
2328         QFileInfo finf(cmd.left(space));
2329         if (CustomBuildTool.ToolPath.isEmpty())
2330             CustomBuildTool.ToolPath += Option::fixPathToTargetOS(finf.path());
2331         CustomBuildTool.Outputs += out;
2332
2333         deps += CustomBuildTool.AdditionalDependencies;
2334         deps += cmd.left(cmd.indexOf(' '));
2335         // Make sure that all deps are only once
2336         QMap<QString, bool> uniqDeps;
2337         for (int c = 0; c < deps.count(); ++c) {
2338             QString aDep = deps.at(c).trimmed();
2339             if (!aDep.isEmpty())
2340                 uniqDeps[aDep] = false;
2341         }
2342         CustomBuildTool.AdditionalDependencies = uniqDeps.keys();
2343     }
2344
2345     // Ensure that none of the output files are also dependencies. Or else, the custom buildstep
2346     // will be rebuild every time, even if nothing has changed.
2347     foreach(QString output, CustomBuildTool.Outputs) {
2348         CustomBuildTool.AdditionalDependencies.removeAll(output);
2349     }
2350
2351     useCustomBuildTool = !CustomBuildTool.CommandLine.isEmpty();
2352     return useCustomBuildTool;
2353 }
2354
2355 // VCProjectSingleConfig --------------------------------------------
2356 VCFilter& VCProjectSingleConfig::filterForExtraCompiler(const QString &compilerName)
2357 {
2358     for (int i = 0; i < ExtraCompilersFiles.count(); ++i)
2359         if (ExtraCompilersFiles.at(i).Name == compilerName)
2360             return ExtraCompilersFiles[i];
2361
2362     static VCFilter nullFilter;
2363     return nullFilter;
2364 }
2365
2366 // Tree file generation ---------------------------------------------
2367 void TreeNode::generateXML(XmlOutput &xml, const QString &tagName, VCProject &tool, const QString &filter) {
2368     if (children.size()) {
2369         // Filter
2370         ChildrenMap::ConstIterator it, end = children.constEnd();
2371         if (!tagName.isEmpty()) {
2372             xml << tag("Filter")
2373                 << attr("Name", tagName)
2374                 << attr("Filter", "");
2375         }
2376         // First round, do nested filters
2377         for (it = children.constBegin(); it != end; ++it)
2378             if ((*it)->children.size())
2379                 (*it)->generateXML(xml, it.key(), tool, filter);
2380         // Second round, do leafs
2381         for (it = children.constBegin(); it != end; ++it)
2382             if (!(*it)->children.size())
2383                 (*it)->generateXML(xml, it.key(), tool, filter);
2384
2385         if (!tagName.isEmpty())
2386             xml << closetag("Filter");
2387     } else {
2388         // Leaf
2389         VCProjectWriter::outputFileConfigs(tool, xml, info, filter);
2390     }
2391 }
2392
2393 // Flat file generation ---------------------------------------------
2394 void FlatNode::generateXML(XmlOutput &xml, const QString &/*tagName*/, VCProject &tool, const QString &filter) {
2395     if (children.size()) {
2396         ChildrenMapFlat::ConstIterator it = children.constBegin();
2397         ChildrenMapFlat::ConstIterator end = children.constEnd();
2398         for (; it != end; ++it) {
2399             VCProjectWriter::outputFileConfigs(tool, xml, (*it), filter);
2400         }
2401     }
2402 }
2403
2404 void VCProjectWriter::write(XmlOutput &xml, VCProjectSingleConfig &tool)
2405 {
2406     xml << decl("1.0", "Windows-1252")
2407         << tag(_VisualStudioProject)
2408         << attrS(_ProjectType, "Visual C++")
2409         << attrS(_Version, tool.Version)
2410         << attrS(_Name, tool.Name)
2411         << attrS(_ProjectGUID, tool.ProjectGUID)
2412         << attrS(_Keyword, tool.Keyword)
2413         << attrS(_SccProjectName, tool.SccProjectName)
2414         << attrS(_SccLocalPath, tool.SccLocalPath)
2415         << tag(_Platforms)
2416         << tag(_Platform)
2417         << attrS(_Name, tool.PlatformName)
2418         << closetag(_Platforms)
2419         << tag(_Configurations);
2420     write(xml, tool.Configuration);
2421     xml << closetag(_Configurations)
2422         << tag(q_Files);
2423     // Add this configuration into a multi-config project, since that's where we have the flat/tree
2424     // XML output functionality
2425     VCProject tempProj;
2426     tempProj.SingleProjects += tool;
2427     outputFilter(tempProj, xml, "Sources");
2428     outputFilter(tempProj, xml, "Headers");
2429     outputFilter(tempProj, xml, "GeneratedFiles");
2430     outputFilter(tempProj, xml, "LexYaccFiles");
2431     outputFilter(tempProj, xml, "TranslationFiles");
2432     outputFilter(tempProj, xml, "FormFiles");
2433     outputFilter(tempProj, xml, "ResourceFiles");
2434     for (int x = 0; x < tempProj.ExtraCompilers.count(); ++x) {
2435         outputFilter(tempProj, xml, tempProj.ExtraCompilers.at(x));
2436     }
2437     outputFilter(tempProj, xml, "RootFiles");
2438     xml     << closetag(q_Files)
2439             << tag(_Globals)
2440                 << data(); // No "/>" end tag
2441 }
2442
2443 void VCProjectWriter::write(XmlOutput &xml, VCProject &tool)
2444 {
2445     if (tool.SingleProjects.count() == 0) {
2446         warn_msg(WarnLogic, "Generator: .NET: no single project in merge project, no output");
2447         return;
2448     }
2449
2450     xml << decl("1.0", "Windows-1252")
2451         << tag(_VisualStudioProject)
2452             << attrS(_ProjectType, "Visual C++")
2453             << attrS(_Version, tool.Version)
2454             << attrS(_Name, tool.Name)
2455             << attrS(_ProjectGUID, tool.ProjectGUID)
2456             << attrS(_Keyword, tool.Keyword)
2457             << attrS(_SccProjectName, tool.SccProjectName)
2458             << attrS(_SccLocalPath, tool.SccLocalPath)
2459             << tag(_Platforms)
2460                 << tag(_Platform)
2461                     << attrS(_Name, tool.PlatformName)
2462             << closetag(_Platforms)
2463             << tag(_Configurations);
2464     // Output each configuration
2465     for (int i = 0; i < tool.SingleProjects.count(); ++i)
2466         write(xml, tool.SingleProjects.at(i).Configuration);
2467     xml     << closetag(_Configurations)
2468             << tag(q_Files);
2469     outputFilter(tool, xml, "Sources");
2470     outputFilter(tool, xml, "Headers");
2471     outputFilter(tool, xml, "GeneratedFiles");
2472     outputFilter(tool, xml, "LexYaccFiles");
2473     outputFilter(tool, xml, "TranslationFiles");
2474     outputFilter(tool, xml, "FormFiles");
2475     outputFilter(tool, xml, "ResourceFiles");
2476     for (int x = 0; x < tool.ExtraCompilers.count(); ++x) {
2477         outputFilter(tool, xml, tool.ExtraCompilers.at(x));
2478     }
2479     outputFilter(tool, xml, "RootFiles");
2480     xml     << closetag(q_Files)
2481             << tag(_Globals)
2482             << data(); // No "/>" end tag
2483 }
2484
2485 void VCProjectWriter::write(XmlOutput &xml, const VCCLCompilerTool &tool)
2486 {
2487     xml << tag(_Tool)
2488         << attrS(_Name, _VCCLCompilerTool)
2489         << attrX(_AdditionalIncludeDirectories, tool.AdditionalIncludeDirectories)
2490         << attrX(_AdditionalOptions, tool.AdditionalOptions, " ")
2491         << attrX(_AdditionalUsingDirectories, tool.AdditionalUsingDirectories)
2492         << attrS(_AssemblerListingLocation, tool.AssemblerListingLocation)
2493         << attrE(_AssemblerOutput, tool.AssemblerOutput, /*ifNot*/ asmListingNone)
2494         << attrE(_BasicRuntimeChecks, tool.BasicRuntimeChecks, /*ifNot*/ runtimeBasicCheckNone)
2495         << attrE(_BrowseInformation, tool.BrowseInformation, /*ifNot*/ brInfoNone)
2496         << attrS(_BrowseInformationFile, tool.BrowseInformationFile)
2497         << attrT(_BufferSecurityCheck, tool.BufferSecurityCheck)
2498         << attrE(_CallingConvention, tool.CallingConvention, /*ifNot*/ callConventionDefault)
2499         << attrE(_CompileAs, tool.CompileAs, compileAsDefault)
2500         << attrE(_CompileAsManaged, tool.CompileAsManaged, /*ifNot*/ managedDefault)
2501         << attrT(_CompileOnly, tool.CompileOnly)
2502         << attrE(_DebugInformationFormat, tool.DebugInformationFormat, /*ifNot*/ debugUnknown)
2503         << attrT(_DefaultCharIsUnsigned, tool.DefaultCharIsUnsigned)
2504         << attrT(_Detect64BitPortabilityProblems, tool.Detect64BitPortabilityProblems)
2505         << attrT(_DisableLanguageExtensions, tool.DisableLanguageExtensions)
2506         << attrX(_DisableSpecificWarnings, tool.DisableSpecificWarnings)
2507         << attrE(_EnableEnhancedInstructionSet, tool.EnableEnhancedInstructionSet, /*ifnot*/ archNotSet)
2508         << attrT(_EnableFiberSafeOptimizations, tool.EnableFiberSafeOptimizations)
2509         << attrT(_EnableFunctionLevelLinking, tool.EnableFunctionLevelLinking)
2510         << attrT(_EnableIntrinsicFunctions, tool.EnableIntrinsicFunctions)
2511         << xformExceptionHandlingNET2005(tool.ExceptionHandling, tool.config->CompilerVersion)
2512         << attrT(_ExpandAttributedSource, tool.ExpandAttributedSource)
2513         << attrE(_FavorSizeOrSpeed, tool.FavorSizeOrSpeed, /*ifNot*/ favorNone)
2514
2515         << attrE(_FloatingPointModel, tool.FloatingPointModel, /*ifNot*/ floatingPointNotSet)
2516         << attrT(_FloatingPointExceptions, tool.FloatingPointExceptions)
2517
2518         << attrT(_ForceConformanceInForLoopScope, tool.ForceConformanceInForLoopScope)
2519         << attrX(_ForcedIncludeFiles, tool.ForcedIncludeFiles)
2520         << attrX(_ForcedUsingFiles, tool.ForcedUsingFiles)
2521         << attrE(_GeneratePreprocessedFile, tool.GeneratePreprocessedFile, /*ifNot*/ preprocessUnknown)
2522         << attrT(_GlobalOptimizations, tool.GlobalOptimizations)
2523         << attrT(_IgnoreStandardIncludePath, tool.IgnoreStandardIncludePath)
2524         << attrT(_ImproveFloatingPointConsistency, tool.ImproveFloatingPointConsistency)
2525         << attrE(_InlineFunctionExpansion, tool.InlineFunctionExpansion, /*ifNot*/ expandDefault)
2526         << attrT(_KeepComments, tool.KeepComments)
2527         << attrT(_MinimalRebuild, tool.MinimalRebuild)
2528         << attrS(_ObjectFile, tool.ObjectFile)
2529         << attrT(_OmitFramePointers, tool.OmitFramePointers)
2530         << attrT(_OpenMP, tool.OpenMP)
2531         << attrE(_Optimization, tool.Optimization, /*ifNot*/ optimizeDefault)
2532         << attrE(_OptimizeForProcessor, tool.OptimizeForProcessor, /*ifNot*/ procOptimizeBlended)
2533         << attrT(_OptimizeForWindowsApplication, tool.OptimizeForWindowsApplication)
2534         << attrS(_OutputFile, tool.OutputFile)
2535         << attrS(_PrecompiledHeaderFile, tool.PrecompiledHeaderFile)
2536         << attrS(_PrecompiledHeaderThrough, tool.PrecompiledHeaderThrough)
2537         << attrX(_PreprocessorDefinitions, tool.PreprocessorDefinitions)
2538         << (tool.ProgramDataBaseFileName.isNull() ? noxml() : attr(_ProgramDataBaseFileName, tool.ProgramDataBaseFileName))
2539         << attrE(_RuntimeLibrary, tool.RuntimeLibrary, /*ifNot*/ rtUnknown)
2540         << attrT(_RuntimeTypeInfo, tool.RuntimeTypeInfo)
2541         << attrT(_ShowIncludes, tool.ShowIncludes)
2542         << attrT(_SmallerTypeCheck, tool.SmallerTypeCheck)
2543         << attrT(_StringPooling, tool.StringPooling)
2544         << attrE(_StructMemberAlignment, tool.StructMemberAlignment, /*ifNot*/ alignNotSet)
2545         << attrT(_SuppressStartupBanner, tool.SuppressStartupBanner)
2546         << attrT(_TreatWChar_tAsBuiltInType, tool.TreatWChar_tAsBuiltInType)
2547         << attrT(_TurnOffAssemblyGeneration, tool.TurnOffAssemblyGeneration)
2548         << attrT(_UndefineAllPreprocessorDefinitions, tool.UndefineAllPreprocessorDefinitions)
2549         << attrX(_UndefinePreprocessorDefinitions, tool.UndefinePreprocessorDefinitions)
2550         << xformUsePrecompiledHeaderForNET2005(tool.UsePrecompiledHeader, tool.config->CompilerVersion)
2551         << attrT(_WarnAsError, tool.WarnAsError)
2552         << attrE(_WarningLevel, tool.WarningLevel, /*ifNot*/ warningLevelUnknown)
2553         << attrT(_WholeProgramOptimization, tool.WholeProgramOptimization)
2554         << attrE(_CompileForArchitecture, tool.CompileForArchitecture, /*ifNot*/ archUnknown)
2555         << attrT(_InterworkCalls, tool.InterworkCalls)
2556
2557         << closetag(_Tool);
2558 }
2559
2560 void VCProjectWriter::write(XmlOutput &xml, const VCLinkerTool &tool)
2561 {
2562     xml << tag(_Tool)
2563         << attrS(_Name, _VCLinkerTool)
2564         << attrX(_AdditionalDependencies, tool.AdditionalDependencies, " ")
2565         << attrX(_AdditionalLibraryDirectories, tool.AdditionalLibraryDirectories)
2566         << attrX(_AdditionalOptions, tool.AdditionalOptions, " ")
2567         << attrX(_AddModuleNamesToAssembly, tool.AddModuleNamesToAssembly)
2568         << attrS(_BaseAddress, tool.BaseAddress)
2569         << attrX(_DelayLoadDLLs, tool.DelayLoadDLLs)
2570         << attrE(_EnableCOMDATFolding, tool.EnableCOMDATFolding, /*ifNot*/ optFoldingDefault)
2571         << attrS(_EntryPointSymbol, tool.EntryPointSymbol)
2572         << attrX(_ForceSymbolReferences, tool.ForceSymbolReferences)
2573         << attrS(_FunctionOrder, tool.FunctionOrder)
2574         << attrT(_GenerateDebugInformation, tool.GenerateDebugInformation)
2575         << attrT(_GenerateMapFile, tool.GenerateMapFile)
2576         << attrL(_HeapCommitSize, tool.HeapCommitSize, /*ifNot*/ -1)
2577         << attrL(_HeapReserveSize, tool.HeapReserveSize, /*ifNot*/ -1)
2578         << attrT(_IgnoreAllDefaultLibraries, tool.IgnoreAllDefaultLibraries)
2579         << attrX(_IgnoreDefaultLibraryNames, tool.IgnoreDefaultLibraryNames)
2580         << attrT(_IgnoreEmbeddedIDL, tool.IgnoreEmbeddedIDL)
2581         << attrT(_IgnoreImportLibrary, tool.IgnoreImportLibrary)
2582         << attrS(_ImportLibrary, tool.ImportLibrary)
2583         << attrE(_LargeAddressAware, tool.LargeAddressAware, /*ifNot*/ addrAwareDefault)
2584         << attrT(_LinkDLL, tool.LinkDLL)
2585         << attrE(_LinkIncremental, tool.LinkIncremental, /*ifNot*/ linkIncrementalDefault)
2586         << attrE(_LinkTimeCodeGeneration, tool.LinkTimeCodeGeneration)
2587         << attrS(_LinkToManagedResourceFile, tool.LinkToManagedResourceFile)
2588         << attrT(_MapExports, tool.MapExports)
2589         << attrS(_MapFileName, tool.MapFileName)
2590         << attrT(_MapLines, tool.MapLines)
2591         << attrS(_MergedIDLBaseFileName, tool.MergedIDLBaseFileName)
2592         << attrS(_MergeSections, tool.MergeSections)
2593         << attrS(_MidlCommandFile, tool.MidlCommandFile)
2594         << attrS(_ModuleDefinitionFile, tool.ModuleDefinitionFile)
2595         << attrE(_OptimizeForWindows98, tool.OptimizeForWindows98, /*ifNot*/ optWin98Default)
2596         << attrE(_OptimizeReferences, tool.OptimizeReferences, /*ifNot*/ optReferencesDefault)
2597         << attrS(_OutputFile, tool.OutputFile)
2598         << attr(_ProgramDatabaseFile, tool.ProgramDatabaseFile)
2599         << attrT(_RegisterOutput, tool.RegisterOutput)
2600         << attrT(_ResourceOnlyDLL, tool.ResourceOnlyDLL)
2601         << attrT(_SetChecksum, tool.SetChecksum)
2602         << attrE(_ShowProgress, tool.ShowProgress, /*ifNot*/ linkProgressNotSet)
2603         << attrL(_StackCommitSize, tool.StackCommitSize, /*ifNot*/ -1)
2604         << attrL(_StackReserveSize, tool.StackReserveSize, /*ifNot*/ -1)
2605         << attrS(_StripPrivateSymbols, tool.StripPrivateSymbols)
2606         << attrE(_SubSystem, tool.SubSystem)
2607         << attrT(_SupportUnloadOfDelayLoadedDLL, tool.SupportUnloadOfDelayLoadedDLL)
2608         << attrT(_SuppressStartupBanner, tool.SuppressStartupBanner)
2609         << attrT(_SwapRunFromCD, tool.SwapRunFromCD)
2610         << attrT(_SwapRunFromNet, tool.SwapRunFromNet)
2611         << attrE(_TargetMachine, tool.TargetMachine, /*ifNot*/ machineNotSet)
2612         << attrE(_TerminalServerAware, tool.TerminalServerAware, /*ifNot*/ termSvrAwareDefault)
2613         << attrT(_TurnOffAssemblyGeneration, tool.TurnOffAssemblyGeneration)
2614         << attrS(_TypeLibraryFile, tool.TypeLibraryFile)
2615         << attrL(_TypeLibraryResourceID, tool.TypeLibraryResourceID, /*ifNot*/ rcUseDefault)
2616         << attrS(_Version, tool.Version)
2617         << closetag(_Tool);
2618 }
2619
2620 void VCProjectWriter::write(XmlOutput &xml, const VCMIDLTool &tool)
2621 {
2622     xml << tag(_Tool)
2623         << attrS(_Name, _VCMIDLTool)
2624         << attrX(_AdditionalIncludeDirectories, tool.AdditionalIncludeDirectories)
2625         << attrX(_AdditionalOptions, tool.AdditionalOptions, " ")
2626         << attrX(_CPreprocessOptions, tool.CPreprocessOptions)
2627         << attrE(_DefaultCharType, tool.DefaultCharType)
2628         << attrS(_DLLDataFileName, tool.DLLDataFileName)
2629         << attrE(_EnableErrorChecks, tool.EnableErrorChecks)
2630         << attrT(_ErrorCheckAllocations, tool.ErrorCheckAllocations)
2631         << attrT(_ErrorCheckBounds, tool.ErrorCheckBounds)
2632         << attrT(_ErrorCheckEnumRange, tool.ErrorCheckEnumRange)
2633         << attrT(_ErrorCheckRefPointers, tool.ErrorCheckRefPointers)
2634         << attrT(_ErrorCheckStubData, tool.ErrorCheckStubData)
2635         << attrX(_FullIncludePath, tool.FullIncludePath)
2636         << attrT(_GenerateStublessProxies, tool.GenerateStublessProxies)
2637         << attrT(_GenerateTypeLibrary, tool.GenerateTypeLibrary)
2638         << attrS(_HeaderFileName, tool.HeaderFileName)
2639         << attrT(_IgnoreStandardIncludePath, tool.IgnoreStandardIncludePath)
2640         << attrS(_InterfaceIdentifierFileName, tool.InterfaceIdentifierFileName)
2641         << attrT(_MkTypLibCompatible, tool.MkTypLibCompatible)
2642         << attrS(_OutputDirectory, tool.OutputDirectory)
2643         << attrX(_PreprocessorDefinitions, tool.PreprocessorDefinitions)
2644         << attrS(_ProxyFileName, tool.ProxyFileName)
2645         << attrS(_RedirectOutputAndErrors, tool.RedirectOutputAndErrors)
2646         << attrE(_StructMemberAlignment, tool.StructMemberAlignment, /*ifNot*/ midlAlignNotSet)
2647         << attrT(_SuppressStartupBanner, tool.SuppressStartupBanner)
2648         << attrE(_TargetEnvironment, tool.TargetEnvironment, /*ifNot*/ midlTargetNotSet)
2649         << attrS(_TypeLibraryName, tool.TypeLibraryName)
2650         << attrX(_UndefinePreprocessorDefinitions, tool.UndefinePreprocessorDefinitions)
2651         << attrT(_ValidateParameters, tool.ValidateParameters)
2652         << attrT(_WarnAsError, tool.WarnAsError)
2653         << attrE(_WarningLevel, tool.WarningLevel)
2654         << closetag(_Tool);
2655 }
2656
2657 void VCProjectWriter::write(XmlOutput &xml, const VCCustomBuildTool &tool)
2658 {
2659     xml << tag(_Tool)
2660             << attrS(_Name, tool.ToolName)
2661             << attrX(_AdditionalDependencies, tool.AdditionalDependencies, ";")
2662             << attrS(_CommandLine, tool.CommandLine.join(vcCommandSeparator()))
2663             << attrS(_Description, tool.Description)
2664             << attrX(_Outputs, tool.Outputs, ";")
2665             << attrS(_Path, tool.ToolPath)
2666         << closetag(_Tool);
2667 }
2668
2669 void VCProjectWriter::write(XmlOutput &xml, const VCLibrarianTool &tool)
2670 {
2671     xml
2672         << tag(_Tool)
2673             << attrS(_Name, _VCLibrarianTool)
2674             << attrX(_AdditionalDependencies, tool.AdditionalDependencies)
2675             << attrX(_AdditionalLibraryDirectories, tool.AdditionalLibraryDirectories)
2676             << attrX(_AdditionalOptions, tool.AdditionalOptions, " ")
2677             << attrX(_ExportNamedFunctions, tool.ExportNamedFunctions)
2678             << attrX(_ForceSymbolReferences, tool.ForceSymbolReferences)
2679             << attrT(_IgnoreAllDefaultLibraries, tool.IgnoreAllDefaultLibraries)
2680             << attrX(_IgnoreDefaultLibraryNames, tool.IgnoreDefaultLibraryNames)
2681             << attrS(_ModuleDefinitionFile, tool.ModuleDefinitionFile)
2682             << attrS(_OutputFile, tool.OutputFile)
2683             << attrT(_SuppressStartupBanner, tool.SuppressStartupBanner)
2684         << closetag(_Tool);
2685 }
2686
2687 void VCProjectWriter::write(XmlOutput &xml, const VCResourceCompilerTool &tool)
2688 {
2689     xml
2690         << tag(_Tool)
2691             << attrS(_Name, _VCResourceCompilerTool)
2692             << attrS(_Path, tool.ToolPath)
2693             << attrX(_AdditionalIncludeDirectories, tool.AdditionalIncludeDirectories)
2694             << attrX(_AdditionalOptions, tool.AdditionalOptions, " ")
2695             << attrE(_Culture, tool.Culture, /*ifNot*/ rcUseDefault)
2696             << attrX(_FullIncludePath, tool.FullIncludePath)
2697             << attrT(_IgnoreStandardIncludePath, tool.IgnoreStandardIncludePath)
2698             << attrX(_PreprocessorDefinitions, tool.PreprocessorDefinitions)
2699             << attrS(_ResourceOutputFileName, tool.ResourceOutputFileName)
2700             << attrE(_ShowProgress, tool.ShowProgress, /*ifNot*/ linkProgressNotSet)
2701         << closetag(_Tool);
2702 }
2703
2704 void VCProjectWriter::write(XmlOutput &xml, const VCEventTool &tool)
2705 {
2706     xml
2707         << tag(_Tool)
2708             << attrS(_Name, tool.ToolName)
2709             << attrS(_Path, tool.ToolPath)
2710             << attrS(_CommandLine, tool.CommandLine.join(vcCommandSeparator()))
2711             << attrS(_Description, tool.Description)
2712             << attrT(_ExcludedFromBuild, tool.ExcludedFromBuild)
2713         << closetag(_Tool);
2714 }
2715
2716 void VCProjectWriter::write(XmlOutput &xml, const VCDeploymentTool &tool)
2717 {
2718     if (tool.AdditionalFiles.isEmpty())
2719         return;
2720     xml << tag(tool.DeploymentTag)
2721         << attrS(_RemoteDirectory, tool.RemoteDirectory)
2722         << attrE(_RegisterOutput, tool.RegisterOutput)
2723         << attrS(_AdditionalFiles, tool.AdditionalFiles)
2724         << closetag(tool.DeploymentTag);
2725 }
2726
2727 void VCProjectWriter::write(XmlOutput &xml, const VCConfiguration &tool)
2728 {
2729     xml << tag(_Configuration)
2730             << attrS(_Name, tool.Name)
2731             << attrS(_OutputDirectory, tool.OutputDirectory)
2732             << attrT(_ATLMinimizesCRunTimeLibraryUsage, tool.ATLMinimizesCRunTimeLibraryUsage)
2733             << attrT(_BuildBrowserInformation, tool.BuildBrowserInformation)
2734             << attrE(_CharacterSet, tool.CharacterSet, /*ifNot*/ charSetNotSet)
2735             << attrE(_ConfigurationType, tool.ConfigurationType)
2736             << attrS(_DeleteExtensionsOnClean, tool.DeleteExtensionsOnClean)
2737             << attrS(_ImportLibrary, tool.ImportLibrary)
2738             << attrS(_IntermediateDirectory, tool.IntermediateDirectory)
2739             << attrS(_PrimaryOutput, tool.PrimaryOutput)
2740             << attrS(_ProgramDatabase, tool.ProgramDatabase)
2741             << attrT(_RegisterOutput, tool.RegisterOutput)
2742             << attrE(_UseOfATL, tool.UseOfATL, /*ifNot*/ useATLNotSet)
2743             << attrE(_UseOfMfc, tool.UseOfMfc)
2744             << attrT(_WholeProgramOptimization, tool.WholeProgramOptimization);
2745     write(xml, tool.compiler);
2746     write(xml, tool.custom);
2747     if (tool.ConfigurationType == typeStaticLibrary)
2748         write(xml, tool.librarian);
2749     else
2750         write(xml, tool.linker);
2751     write(xml, tool.idl);
2752     write(xml, tool.postBuild);
2753     write(xml, tool.preBuild);
2754     write(xml, tool.preLink);
2755     write(xml, tool.resource);
2756     write(xml, tool.deployment);
2757     xml << closetag(_Configuration);
2758 }
2759
2760 void VCProjectWriter::write(XmlOutput &xml, VCFilter &tool)
2761 {
2762     if(!tool.Files.count())
2763         return;
2764
2765     if (!tool.Name.isEmpty()) {
2766         xml << tag(_Filter)
2767                 << attrS(_Name, tool.Name)
2768                 << attrS(_Filter, tool.Filter)
2769                 << attrS(_UniqueIdentifier, tool.Guid)
2770                 << attrT(_ParseFiles, tool.ParseFiles);
2771     }
2772     for (int i = 0; i < tool.Files.count(); ++i) {
2773         const VCFilterFile &info = tool.Files.at(i);
2774         xml << tag(q_File)
2775                 << attrS(_RelativePath, Option::fixPathToLocalOS(info.file))
2776             << data(); // In case no custom builds, to avoid "/>" endings
2777         outputFileConfig(tool, xml, tool.Files.at(i).file);
2778         xml << closetag(q_File);
2779     }
2780     if (!tool.Name.isEmpty())
2781         xml << closetag(_Filter);
2782 }
2783
2784 // outputs a given filter for all existing configurations of a project
2785 void VCProjectWriter::outputFilter(VCProject &project, XmlOutput &xml, const QString &filtername)
2786 {
2787     Node *root;
2788     if (project.SingleProjects.at(0).flat_files)
2789         root = new FlatNode;
2790     else
2791         root = new TreeNode;
2792
2793     QString name, extfilter, guid;
2794     triState parse;
2795
2796     for (int i = 0; i < project.SingleProjects.count(); ++i) {
2797         VCFilter filter;
2798         const VCProjectSingleConfig &projectSingleConfig = project.SingleProjects.at(i);
2799         if (filtername == "RootFiles") {
2800             filter = projectSingleConfig.RootFiles;
2801         } else if (filtername == "Sources") {
2802             filter = projectSingleConfig.SourceFiles;
2803         } else if (filtername == "Headers") {
2804             filter = projectSingleConfig.HeaderFiles;
2805         } else if (filtername == "GeneratedFiles") {
2806             filter = projectSingleConfig.GeneratedFiles;
2807         } else if (filtername == "LexYaccFiles") {
2808             filter = projectSingleConfig.LexYaccFiles;
2809         } else if (filtername == "TranslationFiles") {
2810             filter = projectSingleConfig.TranslationFiles;
2811         } else if (filtername == "FormFiles") {
2812             filter = projectSingleConfig.FormFiles;
2813         } else if (filtername == "ResourceFiles") {
2814             filter = projectSingleConfig.ResourceFiles;
2815         } else {
2816             // ExtraCompilers
2817             filter = project.SingleProjects[i].filterForExtraCompiler(filtername);
2818         }
2819
2820         // Merge all files in this filter to root tree
2821         for (int x = 0; x < filter.Files.count(); ++x)
2822             root->addElement(filter.Files.at(x));
2823
2824         // Save filter setting from first filter. Next filters
2825         // may differ but we cannot handle that. (ex. extfilter)
2826         if (name.isEmpty()) {
2827             name = filter.Name;
2828             extfilter = filter.Filter;
2829             parse = filter.ParseFiles;
2830             guid = filter.Guid;
2831         }
2832     }
2833
2834     if (!root->hasElements())
2835         return;
2836
2837     // Actual XML output ----------------------------------
2838     if (!name.isEmpty()) {
2839         xml << tag(_Filter)
2840                 << attrS(_Name, name)
2841                 << attrS(_Filter, extfilter)
2842                 << attrS(_UniqueIdentifier, guid)
2843                 << attrT(_ParseFiles, parse);
2844     }
2845     root->generateXML(xml, "", project, filtername); // output root tree
2846     if (!name.isEmpty())
2847         xml << closetag(_Filter);
2848 }
2849
2850 // Output all configurations (by filtername) for a file (by info)
2851 // A filters config output is in VCFilter.outputFileConfig()
2852 void VCProjectWriter::outputFileConfigs(VCProject &project, XmlOutput &xml, const VCFilterFile &info, const QString &filtername)
2853 {
2854     xml << tag(q_File)
2855             << attrS(_RelativePath, Option::fixPathToLocalOS(info.file));
2856     for (int i = 0; i < project.SingleProjects.count(); ++i) {
2857         VCFilter filter;
2858         const VCProjectSingleConfig &projectSingleConfig = project.SingleProjects.at(i);
2859         if (filtername == "RootFiles") {
2860             filter = projectSingleConfig.RootFiles;
2861         } else if (filtername == "Sources") {
2862             filter = projectSingleConfig.SourceFiles;
2863         } else if (filtername == "Headers") {
2864             filter = projectSingleConfig.HeaderFiles;
2865         } else if (filtername == "GeneratedFiles") {
2866             filter = projectSingleConfig.GeneratedFiles;
2867         } else if (filtername == "LexYaccFiles") {
2868             filter = projectSingleConfig.LexYaccFiles;
2869         } else if (filtername == "TranslationFiles") {
2870             filter = projectSingleConfig.TranslationFiles;
2871         } else if (filtername == "FormFiles") {
2872             filter = projectSingleConfig.FormFiles;
2873         } else if (filtername == "ResourceFiles") {
2874             filter = projectSingleConfig.ResourceFiles;
2875         } else {
2876             // ExtraCompilers
2877             filter = project.SingleProjects[i].filterForExtraCompiler(filtername);
2878         }
2879
2880         if (filter.Config) // only if the filter is not empty
2881             outputFileConfig(filter, xml, info.file);
2882     }
2883     xml << closetag(q_File);
2884 }
2885
2886 void VCProjectWriter::outputFileConfig(VCFilter &filter, XmlOutput &xml, const QString &filename)
2887 {
2888     // Clearing each filter tool
2889     filter.useCustomBuildTool = false;
2890     filter.useCompilerTool = false;
2891     filter.CustomBuildTool = VCCustomBuildTool();
2892     filter.CompilerTool = VCCLCompilerTool();
2893
2894     // Unset some default options
2895     filter.CustomBuildTool.config = filter.Config;
2896     filter.CompilerTool.BufferSecurityCheck = unset;
2897     filter.CompilerTool.DebugInformationFormat = debugUnknown;
2898     filter.CompilerTool.ExceptionHandling = ehDefault;
2899     filter.CompilerTool.GeneratePreprocessedFile = preprocessUnknown;
2900     filter.CompilerTool.Optimization = optimizeDefault;
2901     filter.CompilerTool.ProgramDataBaseFileName.clear();
2902     filter.CompilerTool.RuntimeLibrary = rtUnknown;
2903     filter.CompilerTool.WarningLevel = warningLevelUnknown;
2904     filter.CompilerTool.config = filter.Config;
2905
2906     bool inBuild = false;
2907     VCFilterFile info;
2908     for (int i = 0; i < filter.Files.count(); ++i) {
2909         if (filter.Files.at(i).file == filename) {
2910             info = filter.Files.at(i);
2911             inBuild = true;
2912         }
2913     }
2914     inBuild &= !info.excludeFromBuild;
2915
2916     if (inBuild) {
2917         filter.addExtraCompiler(info);
2918         if(filter.Project->usePCH)
2919             filter.modifyPCHstage(info.file);
2920     } else {
2921         // Excluded files uses an empty compiler stage
2922         if(info.excludeFromBuild)
2923             filter.useCompilerTool = true;
2924     }
2925
2926     // Actual XML output ----------------------------------
2927     if (filter.useCustomBuildTool || filter.useCompilerTool || !inBuild) {
2928         xml << tag(_FileConfiguration)
2929                 << attr(_Name, filter.Config->Name)
2930                 << (!inBuild ? attrS(_ExcludedFromBuild, "true") : noxml());
2931         if (filter.useCustomBuildTool)
2932             filter.Project->projectWriter->write(xml, filter.CustomBuildTool);
2933         if (filter.useCompilerTool)
2934             filter.Project->projectWriter->write(xml, filter.CompilerTool);
2935         xml << closetag(_FileConfiguration);
2936     }
2937 }
2938
2939 QT_END_NAMESPACE