Skip to content

Commit f630252

Browse files
author
Zachary Turner
committedMar 15, 2017
Update clang-cl driver for MSVC 2017.
2017 changes the way you find an installed copy of Visual Studio as well as its internal directory layout. As a result, clang-cl was unable to find VS2017 even when you had run vcvarsall to set up a toolchain environment. This patch updates everything for 2017 and cleans up the way we handle a tiered search a la environment -> installation -> PATH for which copy of Visual Studio to bind to. Patch originally by Hamza Sood, with some fixups for landing. Differential Revision: https://reviews.llvm.org/D30758 llvm-svn: 297851
1 parent 20055d4 commit f630252

File tree

5 files changed

+893
-250
lines changed

5 files changed

+893
-250
lines changed
 

Diff for: ‎clang/include/clang/Basic/DiagnosticDriverKinds.td

+4
Original file line numberDiff line numberDiff line change
@@ -283,4 +283,8 @@ def warn_drv_ps4_sdk_dir : Warning<
283283
def err_drv_unsupported_linker : Error<"unsupported value '%0' for -linker option">;
284284
def err_drv_defsym_invalid_format : Error<"defsym must be of the form: sym=value: %0">;
285285
def err_drv_defsym_invalid_symval : Error<"Value is not an integer: %0">;
286+
def warn_drv_msvc_not_found : Warning<
287+
"unable to find a Visual Studio installation; "
288+
"try running Clang from a developer command prompt">,
289+
InGroup<InvalidOrNonExistentDirectory>;
286290
}

Diff for: ‎clang/lib/Driver/ToolChains/MSVC.cpp

+356-238
Large diffs are not rendered by default.

Diff for: ‎clang/lib/Driver/ToolChains/MSVC.h

+19-11
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,22 @@ class LLVM_LIBRARY_VISIBILITY MSVCToolChain : public ToolChain {
7878
bool isPIEDefault() const override;
7979
bool isPICDefaultForced() const override;
8080

81+
enum class SubDirectoryType {
82+
Bin,
83+
Include,
84+
Lib,
85+
};
86+
std::string getSubDirectoryPath(SubDirectoryType Type,
87+
llvm::Triple::ArchType TargetArch) const;
88+
89+
// Convenience overload.
90+
// Uses the current target arch.
91+
std::string getSubDirectoryPath(SubDirectoryType Type) const {
92+
return getSubDirectoryPath(Type, getArch());
93+
}
94+
95+
bool getIsVS2017OrNewer() const { return IsVS2017OrNewer; }
96+
8197
void
8298
AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
8399
llvm::opt::ArgStringList &CC1Args) const override;
@@ -88,17 +104,10 @@ class LLVM_LIBRARY_VISIBILITY MSVCToolChain : public ToolChain {
88104
void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs,
89105
llvm::opt::ArgStringList &CC1Args) const override;
90106

91-
bool getWindowsSDKDir(std::string &path, int &major,
92-
std::string &windowsSDKIncludeVersion,
93-
std::string &windowsSDKLibVersion) const;
94107
bool getWindowsSDKLibraryPath(std::string &path) const;
95108
/// \brief Check if Universal CRT should be used if available
96-
bool useUniversalCRT(std::string &visualStudioDir) const;
97-
bool getUniversalCRTSdkDir(std::string &path, std::string &ucrtVersion) const;
98109
bool getUniversalCRTLibraryPath(std::string &path) const;
99-
bool getVisualStudioInstallDir(std::string &path) const;
100-
bool getVisualStudioBinariesFolder(const char *clangProgramPath,
101-
std::string &path) const;
110+
bool useUniversalCRT() const;
102111
VersionTuple
103112
computeMSVCVersion(const Driver *D,
104113
const llvm::opt::ArgList &Args) const override;
@@ -120,9 +129,8 @@ class LLVM_LIBRARY_VISIBILITY MSVCToolChain : public ToolChain {
120129
Tool *buildLinker() const override;
121130
Tool *buildAssembler() const override;
122131
private:
123-
VersionTuple getMSVCVersionFromTriple() const;
124-
VersionTuple getMSVCVersionFromExe() const;
125-
132+
std::string VCToolChainPath;
133+
bool IsVS2017OrNewer;
126134
CudaInstallationDetector CudaInstallation;
127135
};
128136

Diff for: ‎clang/lib/Driver/ToolChains/MSVCSetupApi.h

+514
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,514 @@
1+
// <copyright file="Program.cpp" company="Microsoft Corporation">
2+
// Copyright (C) Microsoft Corporation. All rights reserved.
3+
// Licensed under the MIT license.
4+
// </copyright>
5+
// <license>
6+
// The MIT License (MIT)
7+
//
8+
// Copyright (C) Microsoft Corporation. All rights reserved.
9+
//
10+
// Permission is hereby granted, free of charge, to any person obtaining
11+
// a copy of this software and associated documentation files (the "Software"),
12+
// to deal in the Software without restriction, including without limitation the
13+
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
14+
// sell copies of the Software, and to permit persons to whom the Software is
15+
// furnished to do so, subject to the following conditions:
16+
//
17+
// The above copyright notice and this permission notice shall be included in
18+
// all copies or substantial portions of the Software.
19+
//
20+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26+
// SOFTWARE.
27+
// </license>
28+
29+
#pragma once
30+
31+
// Constants
32+
//
33+
#ifndef E_NOTFOUND
34+
#define E_NOTFOUND HRESULT_FROM_WIN32(ERROR_NOT_FOUND)
35+
#endif
36+
37+
#ifndef E_FILENOTFOUND
38+
#define E_FILENOTFOUND HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)
39+
#endif
40+
41+
// Enumerations
42+
//
43+
/// <summary>
44+
/// The state of an instance.
45+
/// </summary>
46+
enum InstanceState : unsigned {
47+
/// <summary>
48+
/// The instance state has not been determined.
49+
/// </summary>
50+
eNone = 0,
51+
52+
/// <summary>
53+
/// The instance installation path exists.
54+
/// </summary>
55+
eLocal = 1,
56+
57+
/// <summary>
58+
/// A product is registered to the instance.
59+
/// </summary>
60+
eRegistered = 2,
61+
62+
/// <summary>
63+
/// No reboot is required for the instance.
64+
/// </summary>
65+
eNoRebootRequired = 4,
66+
67+
/// <summary>
68+
/// The instance represents a complete install.
69+
/// </summary>
70+
eComplete = MAXUINT,
71+
};
72+
73+
// Forward interface declarations
74+
//
75+
#ifndef __ISetupInstance_FWD_DEFINED__
76+
#define __ISetupInstance_FWD_DEFINED__
77+
typedef struct ISetupInstance ISetupInstance;
78+
#endif
79+
80+
#ifndef __ISetupInstance2_FWD_DEFINED__
81+
#define __ISetupInstance2_FWD_DEFINED__
82+
typedef struct ISetupInstance2 ISetupInstance2;
83+
#endif
84+
85+
#ifndef __IEnumSetupInstances_FWD_DEFINED__
86+
#define __IEnumSetupInstances_FWD_DEFINED__
87+
typedef struct IEnumSetupInstances IEnumSetupInstances;
88+
#endif
89+
90+
#ifndef __ISetupConfiguration_FWD_DEFINED__
91+
#define __ISetupConfiguration_FWD_DEFINED__
92+
typedef struct ISetupConfiguration ISetupConfiguration;
93+
#endif
94+
95+
#ifndef __ISetupConfiguration2_FWD_DEFINED__
96+
#define __ISetupConfiguration2_FWD_DEFINED__
97+
typedef struct ISetupConfiguration2 ISetupConfiguration2;
98+
#endif
99+
100+
#ifndef __ISetupPackageReference_FWD_DEFINED__
101+
#define __ISetupPackageReference_FWD_DEFINED__
102+
typedef struct ISetupPackageReference ISetupPackageReference;
103+
#endif
104+
105+
#ifndef __ISetupHelper_FWD_DEFINED__
106+
#define __ISetupHelper_FWD_DEFINED__
107+
typedef struct ISetupHelper ISetupHelper;
108+
#endif
109+
110+
// Forward class declarations
111+
//
112+
#ifndef __SetupConfiguration_FWD_DEFINED__
113+
#define __SetupConfiguration_FWD_DEFINED__
114+
115+
#ifdef __cplusplus
116+
typedef class SetupConfiguration SetupConfiguration;
117+
#endif
118+
119+
#endif
120+
121+
#ifdef __cplusplus
122+
extern "C" {
123+
#endif
124+
125+
// Interface definitions
126+
//
127+
EXTERN_C const IID IID_ISetupInstance;
128+
129+
#if defined(__cplusplus) && !defined(CINTERFACE)
130+
/// <summary>
131+
/// Information about an instance of a product.
132+
/// </summary>
133+
struct DECLSPEC_UUID("B41463C3-8866-43B5-BC33-2B0676F7F42E")
134+
DECLSPEC_NOVTABLE ISetupInstance : public IUnknown {
135+
/// <summary>
136+
/// Gets the instance identifier (should match the name of the parent instance
137+
/// directory).
138+
/// </summary>
139+
/// <param name="pbstrInstanceId">The instance identifier.</param>
140+
/// <returns>Standard HRESULT indicating success or failure, including
141+
/// E_FILENOTFOUND if the instance state does not exist.</returns>
142+
STDMETHOD(GetInstanceId)(_Out_ BSTR *pbstrInstanceId) = 0;
143+
144+
/// <summary>
145+
/// Gets the local date and time when the installation was originally
146+
/// installed.
147+
/// </summary>
148+
/// <param name="pInstallDate">The local date and time when the installation
149+
/// was originally installed.</param>
150+
/// <returns>Standard HRESULT indicating success or failure, including
151+
/// E_FILENOTFOUND if the instance state does not exist and E_NOTFOUND if the
152+
/// property is not defined.</returns>
153+
STDMETHOD(GetInstallDate)(_Out_ LPFILETIME pInstallDate) = 0;
154+
155+
/// <summary>
156+
/// Gets the unique name of the installation, often indicating the branch and
157+
/// other information used for telemetry.
158+
/// </summary>
159+
/// <param name="pbstrInstallationName">The unique name of the installation,
160+
/// often indicating the branch and other information used for
161+
/// telemetry.</param>
162+
/// <returns>Standard HRESULT indicating success or failure, including
163+
/// E_FILENOTFOUND if the instance state does not exist and E_NOTFOUND if the
164+
/// property is not defined.</returns>
165+
STDMETHOD(GetInstallationName)(_Out_ BSTR *pbstrInstallationName) = 0;
166+
167+
/// <summary>
168+
/// Gets the path to the installation root of the product.
169+
/// </summary>
170+
/// <param name="pbstrInstallationPath">The path to the installation root of
171+
/// the product.</param>
172+
/// <returns>Standard HRESULT indicating success or failure, including
173+
/// E_FILENOTFOUND if the instance state does not exist and E_NOTFOUND if the
174+
/// property is not defined.</returns>
175+
STDMETHOD(GetInstallationPath)(_Out_ BSTR *pbstrInstallationPath) = 0;
176+
177+
/// <summary>
178+
/// Gets the version of the product installed in this instance.
179+
/// </summary>
180+
/// <param name="pbstrInstallationVersion">The version of the product
181+
/// installed in this instance.</param>
182+
/// <returns>Standard HRESULT indicating success or failure, including
183+
/// E_FILENOTFOUND if the instance state does not exist and E_NOTFOUND if the
184+
/// property is not defined.</returns>
185+
STDMETHOD(GetInstallationVersion)(_Out_ BSTR *pbstrInstallationVersion) = 0;
186+
187+
/// <summary>
188+
/// Gets the display name (title) of the product installed in this instance.
189+
/// </summary>
190+
/// <param name="lcid">The LCID for the display name.</param>
191+
/// <param name="pbstrDisplayName">The display name (title) of the product
192+
/// installed in this instance.</param>
193+
/// <returns>Standard HRESULT indicating success or failure, including
194+
/// E_FILENOTFOUND if the instance state does not exist and E_NOTFOUND if the
195+
/// property is not defined.</returns>
196+
STDMETHOD(GetDisplayName)(_In_ LCID lcid, _Out_ BSTR *pbstrDisplayName) = 0;
197+
198+
/// <summary>
199+
/// Gets the description of the product installed in this instance.
200+
/// </summary>
201+
/// <param name="lcid">The LCID for the description.</param>
202+
/// <param name="pbstrDescription">The description of the product installed in
203+
/// this instance.</param>
204+
/// <returns>Standard HRESULT indicating success or failure, including
205+
/// E_FILENOTFOUND if the instance state does not exist and E_NOTFOUND if the
206+
/// property is not defined.</returns>
207+
STDMETHOD(GetDescription)(_In_ LCID lcid, _Out_ BSTR *pbstrDescription) = 0;
208+
209+
/// <summary>
210+
/// Resolves the optional relative path to the root path of the instance.
211+
/// </summary>
212+
/// <param name="pwszRelativePath">A relative path within the instance to
213+
/// resolve, or NULL to get the root path.</param>
214+
/// <param name="pbstrAbsolutePath">The full path to the optional relative
215+
/// path within the instance. If the relative path is NULL, the root path will
216+
/// always terminate in a backslash.</param>
217+
/// <returns>Standard HRESULT indicating success or failure, including
218+
/// E_FILENOTFOUND if the instance state does not exist and E_NOTFOUND if the
219+
/// property is not defined.</returns>
220+
STDMETHOD(ResolvePath)
221+
(_In_opt_z_ LPCOLESTR pwszRelativePath, _Out_ BSTR *pbstrAbsolutePath) = 0;
222+
};
223+
#endif
224+
225+
EXTERN_C const IID IID_ISetupInstance2;
226+
227+
#if defined(__cplusplus) && !defined(CINTERFACE)
228+
/// <summary>
229+
/// Information about an instance of a product.
230+
/// </summary>
231+
struct DECLSPEC_UUID("89143C9A-05AF-49B0-B717-72E218A2185C")
232+
DECLSPEC_NOVTABLE ISetupInstance2 : public ISetupInstance {
233+
/// <summary>
234+
/// Gets the state of the instance.
235+
/// </summary>
236+
/// <param name="pState">The state of the instance.</param>
237+
/// <returns>Standard HRESULT indicating success or failure, including
238+
/// E_FILENOTFOUND if the instance state does not exist.</returns>
239+
STDMETHOD(GetState)(_Out_ InstanceState *pState) = 0;
240+
241+
/// <summary>
242+
/// Gets an array of package references registered to the instance.
243+
/// </summary>
244+
/// <param name="ppsaPackages">Pointer to an array of <see
245+
/// cref="ISetupPackageReference"/>.</param>
246+
/// <returns>Standard HRESULT indicating success or failure, including
247+
/// E_FILENOTFOUND if the instance state does not exist and E_NOTFOUND if the
248+
/// packages property is not defined.</returns>
249+
STDMETHOD(GetPackages)(_Out_ LPSAFEARRAY *ppsaPackages) = 0;
250+
251+
/// <summary>
252+
/// Gets a pointer to the <see cref="ISetupPackageReference"/> that represents
253+
/// the registered product.
254+
/// </summary>
255+
/// <param name="ppPackage">Pointer to an instance of <see
256+
/// cref="ISetupPackageReference"/>. This may be NULL if <see
257+
/// cref="GetState"/> does not return <see cref="eComplete"/>.</param>
258+
/// <returns>Standard HRESULT indicating success or failure, including
259+
/// E_FILENOTFOUND if the instance state does not exist and E_NOTFOUND if the
260+
/// packages property is not defined.</returns>
261+
STDMETHOD(GetProduct)
262+
(_Outptr_result_maybenull_ ISetupPackageReference **ppPackage) = 0;
263+
264+
/// <summary>
265+
/// Gets the relative path to the product application, if available.
266+
/// </summary>
267+
/// <param name="pbstrProductPath">The relative path to the product
268+
/// application, if available.</param>
269+
/// <returns>Standard HRESULT indicating success or failure, including
270+
/// E_FILENOTFOUND if the instance state does not exist.</returns>
271+
STDMETHOD(GetProductPath)
272+
(_Outptr_result_maybenull_ BSTR *pbstrProductPath) = 0;
273+
};
274+
#endif
275+
276+
EXTERN_C const IID IID_IEnumSetupInstances;
277+
278+
#if defined(__cplusplus) && !defined(CINTERFACE)
279+
/// <summary>
280+
/// A enumerator of installed <see cref="ISetupInstance"/> objects.
281+
/// </summary>
282+
struct DECLSPEC_UUID("6380BCFF-41D3-4B2E-8B2E-BF8A6810C848")
283+
DECLSPEC_NOVTABLE IEnumSetupInstances : public IUnknown {
284+
/// <summary>
285+
/// Retrieves the next set of product instances in the enumeration sequence.
286+
/// </summary>
287+
/// <param name="celt">The number of product instances to retrieve.</param>
288+
/// <param name="rgelt">A pointer to an array of <see
289+
/// cref="ISetupInstance"/>.</param>
290+
/// <param name="pceltFetched">A pointer to the number of product instances
291+
/// retrieved. If celt is 1 this parameter may be NULL.</param>
292+
/// <returns>S_OK if the number of elements were fetched, S_FALSE if nothing
293+
/// was fetched (at end of enumeration), E_INVALIDARG if celt is greater than
294+
/// 1 and pceltFetched is NULL, or E_OUTOFMEMORY if an <see
295+
/// cref="ISetupInstance"/> could not be allocated.</returns>
296+
STDMETHOD(Next)
297+
(_In_ ULONG celt, _Out_writes_to_(celt, *pceltFetched) ISetupInstance **rgelt,
298+
_Out_opt_ _Deref_out_range_(0, celt) ULONG *pceltFetched) = 0;
299+
300+
/// <summary>
301+
/// Skips the next set of product instances in the enumeration sequence.
302+
/// </summary>
303+
/// <param name="celt">The number of product instances to skip.</param>
304+
/// <returns>S_OK if the number of elements could be skipped; otherwise,
305+
/// S_FALSE;</returns>
306+
STDMETHOD(Skip)(_In_ ULONG celt) = 0;
307+
308+
/// <summary>
309+
/// Resets the enumeration sequence to the beginning.
310+
/// </summary>
311+
/// <returns>Always returns S_OK;</returns>
312+
STDMETHOD(Reset)(void) = 0;
313+
314+
/// <summary>
315+
/// Creates a new enumeration object in the same state as the current
316+
/// enumeration object: the new object points to the same place in the
317+
/// enumeration sequence.
318+
/// </summary>
319+
/// <param name="ppenum">A pointer to a pointer to a new <see
320+
/// cref="IEnumSetupInstances"/> interface. If the method fails, this
321+
/// parameter is undefined.</param>
322+
/// <returns>S_OK if a clone was returned; otherwise, E_OUTOFMEMORY.</returns>
323+
STDMETHOD(Clone)(_Deref_out_opt_ IEnumSetupInstances **ppenum) = 0;
324+
};
325+
#endif
326+
327+
EXTERN_C const IID IID_ISetupConfiguration;
328+
329+
#if defined(__cplusplus) && !defined(CINTERFACE)
330+
/// <summary>
331+
/// Gets information about product instances set up on the machine.
332+
/// </summary>
333+
struct DECLSPEC_UUID("42843719-DB4C-46C2-8E7C-64F1816EFD5B")
334+
DECLSPEC_NOVTABLE ISetupConfiguration : public IUnknown {
335+
/// <summary>
336+
/// Enumerates all completed product instances installed.
337+
/// </summary>
338+
/// <param name="ppEnumInstances">An enumeration of completed, installed
339+
/// product instances.</param>
340+
/// <returns>Standard HRESULT indicating success or failure.</returns>
341+
STDMETHOD(EnumInstances)(_Out_ IEnumSetupInstances **ppEnumInstances) = 0;
342+
343+
/// <summary>
344+
/// Gets the instance for the current process path.
345+
/// </summary>
346+
/// <param name="ppInstance">The instance for the current process
347+
/// path.</param>
348+
/// <returns>The instance for the current process path, or E_NOTFOUND if not
349+
/// found.</returns>
350+
STDMETHOD(GetInstanceForCurrentProcess)
351+
(_Out_ ISetupInstance **ppInstance) = 0;
352+
353+
/// <summary>
354+
/// Gets the instance for the given path.
355+
/// </summary>
356+
/// <param name="ppInstance">The instance for the given path.</param>
357+
/// <returns>The instance for the given path, or E_NOTFOUND if not
358+
/// found.</returns>
359+
STDMETHOD(GetInstanceForPath)
360+
(_In_z_ LPCWSTR wzPath, _Out_ ISetupInstance **ppInstance) = 0;
361+
};
362+
#endif
363+
364+
EXTERN_C const IID IID_ISetupConfiguration2;
365+
366+
#if defined(__cplusplus) && !defined(CINTERFACE)
367+
/// <summary>
368+
/// Gets information about product instances.
369+
/// </summary>
370+
struct DECLSPEC_UUID("26AAB78C-4A60-49D6-AF3B-3C35BC93365D")
371+
DECLSPEC_NOVTABLE ISetupConfiguration2 : public ISetupConfiguration {
372+
/// <summary>
373+
/// Enumerates all product instances.
374+
/// </summary>
375+
/// <param name="ppEnumInstances">An enumeration of all product
376+
/// instances.</param>
377+
/// <returns>Standard HRESULT indicating success or failure.</returns>
378+
STDMETHOD(EnumAllInstances)(_Out_ IEnumSetupInstances **ppEnumInstances) = 0;
379+
};
380+
#endif
381+
382+
EXTERN_C const IID IID_ISetupPackageReference;
383+
384+
#if defined(__cplusplus) && !defined(CINTERFACE)
385+
/// <summary>
386+
/// A reference to a package.
387+
/// </summary>
388+
struct DECLSPEC_UUID("da8d8a16-b2b6-4487-a2f1-594ccccd6bf5")
389+
DECLSPEC_NOVTABLE ISetupPackageReference : public IUnknown {
390+
/// <summary>
391+
/// Gets the general package identifier.
392+
/// </summary>
393+
/// <param name="pbstrId">The general package identifier.</param>
394+
/// <returns>Standard HRESULT indicating success or failure.</returns>
395+
STDMETHOD(GetId)(_Out_ BSTR *pbstrId) = 0;
396+
397+
/// <summary>
398+
/// Gets the version of the package.
399+
/// </summary>
400+
/// <param name="pbstrVersion">The version of the package.</param>
401+
/// <returns>Standard HRESULT indicating success or failure.</returns>
402+
STDMETHOD(GetVersion)(_Out_ BSTR *pbstrVersion) = 0;
403+
404+
/// <summary>
405+
/// Gets the target process architecture of the package.
406+
/// </summary>
407+
/// <param name="pbstrChip">The target process architecture of the
408+
/// package.</param>
409+
/// <returns>Standard HRESULT indicating success or failure.</returns>
410+
STDMETHOD(GetChip)(_Out_ BSTR *pbstrChip) = 0;
411+
412+
/// <summary>
413+
/// Gets the language and optional region identifier.
414+
/// </summary>
415+
/// <param name="pbstrLanguage">The language and optional region
416+
/// identifier.</param>
417+
/// <returns>Standard HRESULT indicating success or failure.</returns>
418+
STDMETHOD(GetLanguage)(_Out_ BSTR *pbstrLanguage) = 0;
419+
420+
/// <summary>
421+
/// Gets the build branch of the package.
422+
/// </summary>
423+
/// <param name="pbstrBranch">The build branch of the package.</param>
424+
/// <returns>Standard HRESULT indicating success or failure.</returns>
425+
STDMETHOD(GetBranch)(_Out_ BSTR *pbstrBranch) = 0;
426+
427+
/// <summary>
428+
/// Gets the type of the package.
429+
/// </summary>
430+
/// <param name="pbstrType">The type of the package.</param>
431+
/// <returns>Standard HRESULT indicating success or failure.</returns>
432+
STDMETHOD(GetType)(_Out_ BSTR *pbstrType) = 0;
433+
434+
/// <summary>
435+
/// Gets the unique identifier consisting of all defined tokens.
436+
/// </summary>
437+
/// <param name="pbstrUniqueId">The unique identifier consisting of all
438+
/// defined tokens.</param>
439+
/// <returns>Standard HRESULT indicating success or failure, including
440+
/// E_UNEXPECTED if no Id was defined (required).</returns>
441+
STDMETHOD(GetUniqueId)(_Out_ BSTR *pbstrUniqueId) = 0;
442+
};
443+
#endif
444+
445+
EXTERN_C const IID IID_ISetupHelper;
446+
447+
#if defined(__cplusplus) && !defined(CINTERFACE)
448+
/// <summary>
449+
/// Helper functions.
450+
/// </summary>
451+
/// <remarks>
452+
/// You can query for this interface from the <see cref="SetupConfiguration"/>
453+
/// class.
454+
/// </remarks>
455+
struct DECLSPEC_UUID("42b21b78-6192-463e-87bf-d577838f1d5c")
456+
DECLSPEC_NOVTABLE ISetupHelper : public IUnknown {
457+
/// <summary>
458+
/// Parses a dotted quad version string into a 64-bit unsigned integer.
459+
/// </summary>
460+
/// <param name="pwszVersion">The dotted quad version string to parse, e.g.
461+
/// 1.2.3.4.</param>
462+
/// <param name="pullVersion">A 64-bit unsigned integer representing the
463+
/// version. You can compare this to other versions.</param>
464+
/// <returns>Standard HRESULT indicating success or failure.</returns>
465+
STDMETHOD(ParseVersion)
466+
(_In_ LPCOLESTR pwszVersion, _Out_ PULONGLONG pullVersion) = 0;
467+
468+
/// <summary>
469+
/// Parses a dotted quad version string into a 64-bit unsigned integer.
470+
/// </summary>
471+
/// <param name="pwszVersionRange">The string containing 1 or 2 dotted quad
472+
/// version strings to parse, e.g. [1.0,) that means 1.0.0.0 or newer.</param>
473+
/// <param name="pullMinVersion">A 64-bit unsigned integer representing the
474+
/// minimum version, which may be 0. You can compare this to other
475+
/// versions.</param>
476+
/// <param name="pullMaxVersion">A 64-bit unsigned integer representing the
477+
/// maximum version, which may be MAXULONGLONG. You can compare this to other
478+
/// versions.</param>
479+
/// <returns>Standard HRESULT indicating success or failure.</returns>
480+
STDMETHOD(ParseVersionRange)
481+
(_In_ LPCOLESTR pwszVersionRange, _Out_ PULONGLONG pullMinVersion,
482+
_Out_ PULONGLONG pullMaxVersion) = 0;
483+
};
484+
#endif
485+
486+
// Class declarations
487+
//
488+
EXTERN_C const CLSID CLSID_SetupConfiguration;
489+
490+
#ifdef __cplusplus
491+
/// <summary>
492+
/// This class implements <see cref="ISetupConfiguration"/>, <see
493+
/// cref="ISetupConfiguration2"/>, and <see cref="ISetupHelper"/>.
494+
/// </summary>
495+
class DECLSPEC_UUID("177F0C4A-1CD3-4DE7-A32C-71DBBB9FA36D") SetupConfiguration;
496+
#endif
497+
498+
// Function declarations
499+
//
500+
/// <summary>
501+
/// Gets an <see cref="ISetupConfiguration"/> that provides information about
502+
/// product instances installed on the machine.
503+
/// </summary>
504+
/// <param name="ppConfiguration">The <see cref="ISetupConfiguration"/> that
505+
/// provides information about product instances installed on the
506+
/// machine.</param>
507+
/// <param name="pReserved">Reserved for future use.</param>
508+
/// <returns>Standard HRESULT indicating success or failure.</returns>
509+
STDMETHODIMP GetSetupConfiguration(_Out_ ISetupConfiguration **ppConfiguration,
510+
_Reserved_ LPVOID pReserved);
511+
512+
#ifdef __cplusplus
513+
}
514+
#endif

Diff for: ‎clang/test/Driver/cl-link-at-file.c

-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
// be clueless and will emit "argument unused" warnings. If PR17239 is properly
1414
// fixed, this should not happen because the "/link" option is restricted to
1515
// consume only remaining args in its response file.
16-
// ARGS-NOT: warning
1716
// ARGS-NOT: argument unused during compilation
1817
// Identify the linker command
1918
// ARGS: link.exe

0 commit comments

Comments
 (0)
Please sign in to comment.