TextDiagnosticPrinter::HandleDiagnostic() question

When using the x86_64-pc-win32-macho triple we end up compiling and debugging on OS X and building a Win32 API (for us really an EFI API) image.

The following code in TextDiagnosticPrinter::HandleDiagnostic() causes diagnostic messages that don't work with Xcode

        // Emit a Visual Studio compatible line number syntax.
        if (LangOpts && LangOpts->Microsoft) {
          OS << PLoc.getFilename() << '(' << LineNo << ')';
          OS << " : ";
        } else {
          OS << PLoc.getFilename() << ':' << LineNo << ':';
          if (DiagOpts->ShowColumn)
            if (unsigned ColNo = PLoc.getColumn())
              OS << ColNo << ':';
        }

On the backend side I know that we use things like Triple.getEnvironment() != llvm::Triple::MachO. I'm not sure what we do on the front end.

Seems to me that LangOpts->Microsoft implies code construction and not OS version that the system is running on?

So how could we make normal clang diagnostics appear for for the 86_64-pc-win32-macho triple?

Thanks,

Andrew Fish

Example:

clang /Users/fish/work/edk2/InOsEmuPkg/BootModePei/BootModePei.c
/Users/fish/work/edk2/InOsEmuPkg/BootModePei/BootModePei.c:27:10: fatal error: 'PiPei.h' file not found
#include <PiPei.h>
       ^
1 error generated.

vs

clang -ccc-host-triple x86_64-pc-win32-macho /Users/fish/work/edk2/InOsEmuPkg/BootModePei/BootModePei.c
/Users/fish/work/edk2/InOsEmuPkg/BootModePei/BootModePei.c(27) : fatal error: 'PiPei.h' file not found
#include <PiPei.h>
       ^
1 error generated.

(27) does not work for Xcode, but :27:10 does.

Andrew Fish

The right approach would be to add an option bit to DiagnosticOptions that tells the diagnostic printers to print in a cl.exe-compatible syntax, along with clang driver options to set that diagnostic bit.

  - Doug

When using the x86_64-pc-win32-macho triple we end up compiling and debugging on OS X and building a Win32 API (for us really an EFI API) image.

The following code in TextDiagnosticPrinter::HandleDiagnostic() causes diagnostic messages that don't work with Xcode

       // Emit a Visual Studio compatible line number syntax.
       if (LangOpts && LangOpts->Microsoft) {
         OS << PLoc.getFilename() << '(' << LineNo << ')';
         OS << " : ";
       } else {
         OS << PLoc.getFilename() << ':' << LineNo << ':';
         if (DiagOpts->ShowColumn)
           if (unsigned ColNo = PLoc.getColumn())
             OS << ColNo << ':';
       }

On the backend side I know that we use things like Triple.getEnvironment() != llvm::Triple::MachO. I'm not sure what we do on the front end.

Seems to me that LangOpts->Microsoft implies code construction and not OS version that the system is running on?

I agree; this should be triggered by the target, not LangOptions.Microsoft. On the other hand...

So how could we make normal clang diagnostics appear for for the 86_64-pc-win32-macho triple?

...I would think that this triple suggests a Microsoft target.

This was introduced in r90642, which refers to <rdar://problem/6309338>, if you want to figure out what the right trigger for this is.

John.

Seems to me that LangOpts->Microsoft implies code construction and not OS version that the system is running on?

I agree; this should be triggered by the target, not LangOptions.Microsoft. On the other hand...

So how could we make normal clang diagnostics appear for for the 86_64-pc-win32-macho triple?

...I would think that this triple suggests a Microsoft target.

Our target is really EFI system firmware (http://www.uefi.org/) so all we need is the win32 ABI and not any of the system stuff. The edk2 (Tianocore download | SourceForge.net) is an open source EFI code base that supports lots of flavors of compilers like Visual Studio 2003 - 2010, Intel, gcc, clang, and others for ARMv7, i386, 86_64, and Itanium processors, and you can build on Windows, Linux, or Mac OS X systems. The edk2 code base is C and there is zero dependency on any system libraries, not even for compiler intrinsics. Also there is a cctools command line tool, mtoc, that will convert a Mach-0 to an EFI PE/COFF executable (not a Windows PE/COFF executable!). We need the Mach-O for source level debugging.

So the 86_64-pc-win32-macho triple really means build and run a debugger for 86_64 EFI firmware on Mac OS X. The EFI 86_64 binaries can run on any 86_64 EFI system or emulator.

The edk2 code base was size optimized using Visual Studio link-time code gen. This means if the edk2 is compiled with gcc you get a much larger executable size. In the firmware world NOR FLASH cost real money so size is more important than raw performance from the compiler. Since clang also does link time optimization it is the obvious choice for a non Windows based compiler for the edk2 EFI code base.

This was introduced in r90642, which refers to <rdar://problem/6309338>, if you want to figure out what the right trigger for this is.

Sorry I'm an EFI expert, but my clang knowledge is not very good. We were hoping to get some one with the clang "big picture" to suggest the best way to fix this. We kind of hacked around in the back end using our crazy triple.... Of course we are happy to do testing and make a localized change, but I'd be very apprehensive about making a more global change.

Andrew

I don't know why this triple means that. Maybe you need your own triple?

John.

The triple means that because it's what we were asked to make it when we put it in originally. I think it makes sense - 64-bit Win32 ABI code in a Mach-O object file.

I think Douglas' suggestion to add an option to DiagnosticOptions sounds reasonable - the only question I'd still have is how to hook up that option as a default for non-Mach-O triples, to avoid breaking anyone who currently depends on the MSVC-style diagnostic messages.

-- Carl