Index: lib/Support/GraphWriter.cpp =================================================================== --- lib/Support/GraphWriter.cpp +++ lib/Support/GraphWriter.cpp @@ -189,32 +189,47 @@ return ExecGraphViewer(ViewerPath, args, Filename, wait, ErrMsg); } - enum PSViewerKind { PSV_None, PSV_OSXOpen, PSV_XDGOpen, PSV_Ghostview }; - PSViewerKind PSViewer = PSV_None; + enum ViewerKind { + VK_None, + VK_OSXOpen, + VK_XDGOpen, + VK_Ghostview, + VK_CmdStart + }; + ViewerKind Viewer = VK_None; #ifdef __APPLE__ - if (!PSViewer && S.TryFindProgram("open", ViewerPath)) - PSViewer = PSV_OSXOpen; + if (!Viewer && S.TryFindProgram("open", ViewerPath)) + Viewer = VK_OSXOpen; +#endif + if (!Viewer && S.TryFindProgram("gv", ViewerPath)) + Viewer = VK_Ghostview; + if (!Viewer && S.TryFindProgram("xdg-open", ViewerPath)) + Viewer = VK_XDGOpen; +#ifdef LLVM_ON_WIN32 + if (!Viewer && S.TryFindProgram("cmd", ViewerPath)) { + Viewer = VK_CmdStart; + } #endif - if (!PSViewer && S.TryFindProgram("gv", ViewerPath)) - PSViewer = PSV_Ghostview; - if (!PSViewer && S.TryFindProgram("xdg-open", ViewerPath)) - PSViewer = PSV_XDGOpen; - // PostScript graph generator + PostScript viewer + // PostScript or PDF graph generator + PostScript/PDF viewer std::string GeneratorPath; - if (PSViewer && + if (Viewer && (S.TryFindProgram(getProgramName(program), GeneratorPath) || S.TryFindProgram("dot|fdp|neato|twopi|circo", GeneratorPath))) { - std::string PSFilename = Filename + ".ps"; + std::string OutputFilename = + Filename + (Viewer == VK_CmdStart ? ".pdf" : ".ps"); std::vector args; args.push_back(GeneratorPath.c_str()); - args.push_back("-Tps"); + if (Viewer == VK_CmdStart) + args.push_back("-Tpdf"); + else + args.push_back("-Tps"); args.push_back("-Nfontname=Courier"); args.push_back("-Gsize=7.5,10"); args.push_back(Filename.c_str()); args.push_back("-o"); - args.push_back(PSFilename.c_str()); + args.push_back(OutputFilename.c_str()); args.push_back(nullptr); errs() << "Running '" << GeneratorPath << "' program... "; @@ -222,28 +237,39 @@ if (ExecGraphViewer(GeneratorPath, args, Filename, wait, ErrMsg)) return true; + // The lifetime of StartArg must include the call of ExecGraphViewer + // because the args are passed as vector of char*. + std::string StartArg; + args.clear(); args.push_back(ViewerPath.c_str()); - switch (PSViewer) { - case PSV_OSXOpen: + switch (Viewer) { + case VK_OSXOpen: args.push_back("-W"); - args.push_back(PSFilename.c_str()); + args.push_back(OutputFilename.c_str()); break; - case PSV_XDGOpen: + case VK_XDGOpen: wait = false; - args.push_back(PSFilename.c_str()); + args.push_back(OutputFilename.c_str()); break; - case PSV_Ghostview: + case VK_Ghostview: args.push_back("--spartan"); - args.push_back(PSFilename.c_str()); + args.push_back(OutputFilename.c_str()); + break; + case VK_CmdStart: + args.push_back("/S"); + args.push_back("/C"); + StartArg = + (StringRef("start ") + (wait ? "/WAIT " : "") + OutputFilename).str(); + args.push_back(StartArg.c_str()); break; - case PSV_None: + case VK_None: llvm_unreachable("Invalid viewer"); } args.push_back(nullptr); ErrMsg.clear(); - return ExecGraphViewer(ViewerPath, args, PSFilename, wait, ErrMsg); + return ExecGraphViewer(ViewerPath, args, OutputFilename, wait, ErrMsg); } // dotty