Skip to content

Commit

Permalink
[clang-cl] Treat inputs as C++ with /E, like MSVC
Browse files Browse the repository at this point in the history
midl invokes the compiler on .idl files with /E. Before this change, we
would treat unrecognized inputs as object files. Now we pre-process to
stdout as expected. I checked that MSVC defines __cplusplus when invoked
this way, so treating the input as C++ seems like the right thing to do.

After this change, I was able to run midl like this with clang-cl:
$ midl -cpp_cmd clang-cl.exe foo.idl

Things worked for the example IDL file in the Microsoft documentation,
but beyond that, I don't know if this will work well.

Fixes PR40140

llvm-svn: 350072
  • Loading branch information
rnk committed Dec 26, 2018
1 parent 3ab5a9c commit a643e64
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 1 deletion.
5 changes: 4 additions & 1 deletion clang/lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2057,7 +2057,8 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args,
Ty = types::TY_C;
} else {
// Otherwise lookup by extension.
// Fallback is C if invoked as C preprocessor or Object otherwise.
// Fallback is C if invoked as C preprocessor, C++ if invoked with
// clang-cl /E, or Object otherwise.
// We use a host hook here because Darwin at least has its own
// idea of what .s is.
if (const char *Ext = strrchr(Value, '.'))
Expand All @@ -2066,6 +2067,8 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args,
if (Ty == types::TY_INVALID) {
if (CCCIsCPP())
Ty = types::TY_C;
else if (IsCLMode() && Args.hasArgNoClaim(options::OPT_E))
Ty = types::TY_CXX;
else
Ty = types::TY_Object;
}
Expand Down
18 changes: 18 additions & 0 deletions clang/test/Driver/cl-idl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Note: %s must be preceded by --, otherwise it may be interpreted as a
// command-line option, e.g. on Mac where %s is commonly under /Users.

// Test that 'clang-cl /E' treats inputs as C++ if the extension is
// unrecognized. midl relies on this. See PR40140.

// Use a plain .cpp extension first.
// RUN: %clang_cl /E -- %s | FileCheck %s

// Copy to use .idl as the extension.
// RUN: cp %s %t.idl
// RUN: %clang_cl /E -- %t.idl | FileCheck %s

#ifdef __cplusplus
struct IsCPlusPlus {};
#endif

// CHECK: struct IsCPlusPlus {};

0 comments on commit a643e64

Please sign in to comment.