10b57cec5SDimitry Andric //===-- cc1_main.cpp - Clang CC1 Compiler Frontend ------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This is the entry point to the clang -cc1 functionality, which implements the
100b57cec5SDimitry Andric // core compiler functionality along with a number of additional tools for
110b57cec5SDimitry Andric // demonstration and testing purposes.
120b57cec5SDimitry Andric //
130b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
140b57cec5SDimitry Andric 
150b57cec5SDimitry Andric #include "clang/Basic/Stack.h"
160b57cec5SDimitry Andric #include "clang/Basic/TargetOptions.h"
170b57cec5SDimitry Andric #include "clang/CodeGen/ObjectFilePCHContainerOperations.h"
180b57cec5SDimitry Andric #include "clang/Config/config.h"
190b57cec5SDimitry Andric #include "clang/Driver/DriverDiagnostic.h"
200b57cec5SDimitry Andric #include "clang/Driver/Options.h"
210b57cec5SDimitry Andric #include "clang/Frontend/CompilerInstance.h"
220b57cec5SDimitry Andric #include "clang/Frontend/CompilerInvocation.h"
230b57cec5SDimitry Andric #include "clang/Frontend/FrontendDiagnostic.h"
240b57cec5SDimitry Andric #include "clang/Frontend/TextDiagnosticBuffer.h"
250b57cec5SDimitry Andric #include "clang/Frontend/TextDiagnosticPrinter.h"
260b57cec5SDimitry Andric #include "clang/Frontend/Utils.h"
270b57cec5SDimitry Andric #include "clang/FrontendTool/Utils.h"
280b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h"
290b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h"
300b57cec5SDimitry Andric #include "llvm/LinkAllPasses.h"
315f757f3fSDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
32349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h"
330b57cec5SDimitry Andric #include "llvm/Option/Arg.h"
340b57cec5SDimitry Andric #include "llvm/Option/ArgList.h"
350b57cec5SDimitry Andric #include "llvm/Option/OptTable.h"
360b57cec5SDimitry Andric #include "llvm/Support/BuryPointer.h"
370b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
380b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
390b57cec5SDimitry Andric #include "llvm/Support/ManagedStatic.h"
400b57cec5SDimitry Andric #include "llvm/Support/Path.h"
4113138422SDimitry Andric #include "llvm/Support/Process.h"
425f757f3fSDimitry Andric #include "llvm/Support/RISCVISAInfo.h"
430b57cec5SDimitry Andric #include "llvm/Support/Signals.h"
440b57cec5SDimitry Andric #include "llvm/Support/TargetSelect.h"
450b57cec5SDimitry Andric #include "llvm/Support/TimeProfiler.h"
460b57cec5SDimitry Andric #include "llvm/Support/Timer.h"
470b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
480b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h"
495f757f3fSDimitry Andric #include "llvm/TargetParser/AArch64TargetParser.h"
505f757f3fSDimitry Andric #include "llvm/TargetParser/ARMTargetParser.h"
510b57cec5SDimitry Andric #include <cstdio>
520b57cec5SDimitry Andric 
530b57cec5SDimitry Andric #ifdef CLANG_HAVE_RLIMITS
540b57cec5SDimitry Andric #include <sys/resource.h>
550b57cec5SDimitry Andric #endif
560b57cec5SDimitry Andric 
570b57cec5SDimitry Andric using namespace clang;
580b57cec5SDimitry Andric using namespace llvm::opt;
590b57cec5SDimitry Andric 
600b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
610b57cec5SDimitry Andric // Main driver
620b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
630b57cec5SDimitry Andric 
LLVMErrorHandler(void * UserData,const char * Message,bool GenCrashDiag)64349cc55cSDimitry Andric static void LLVMErrorHandler(void *UserData, const char *Message,
650b57cec5SDimitry Andric                              bool GenCrashDiag) {
660b57cec5SDimitry Andric   DiagnosticsEngine &Diags = *static_cast<DiagnosticsEngine*>(UserData);
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric   Diags.Report(diag::err_fe_error_backend) << Message;
690b57cec5SDimitry Andric 
700b57cec5SDimitry Andric   // Run the interrupt handlers to make sure any special cleanups get done, in
710b57cec5SDimitry Andric   // particular that we remove files registered with RemoveFileOnSignal.
720b57cec5SDimitry Andric   llvm::sys::RunInterruptHandlers();
730b57cec5SDimitry Andric 
740b57cec5SDimitry Andric   // We cannot recover from llvm errors.  When reporting a fatal error, exit
750b57cec5SDimitry Andric   // with status 70 to generate crash diagnostics.  For BSD systems this is
760b57cec5SDimitry Andric   // defined as an internal software error.  Otherwise, exit with status 1.
7713138422SDimitry Andric   llvm::sys::Process::Exit(GenCrashDiag ? 70 : 1);
780b57cec5SDimitry Andric }
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric #ifdef CLANG_HAVE_RLIMITS
810b57cec5SDimitry Andric #if defined(__linux__) && defined(__PIE__)
getCurrentStackAllocation()820b57cec5SDimitry Andric static size_t getCurrentStackAllocation() {
830b57cec5SDimitry Andric   // If we can't compute the current stack usage, allow for 512K of command
840b57cec5SDimitry Andric   // line arguments and environment.
850b57cec5SDimitry Andric   size_t Usage = 512 * 1024;
860b57cec5SDimitry Andric   if (FILE *StatFile = fopen("/proc/self/stat", "r")) {
870b57cec5SDimitry Andric     // We assume that the stack extends from its current address to the end of
880b57cec5SDimitry Andric     // the environment space. In reality, there is another string literal (the
890b57cec5SDimitry Andric     // program name) after the environment, but this is close enough (we only
900b57cec5SDimitry Andric     // need to be within 100K or so).
910b57cec5SDimitry Andric     unsigned long StackPtr, EnvEnd;
920b57cec5SDimitry Andric     // Disable silly GCC -Wformat warning that complains about length
930b57cec5SDimitry Andric     // modifiers on ignored format specifiers. We want to retain these
940b57cec5SDimitry Andric     // for documentation purposes even though they have no effect.
950b57cec5SDimitry Andric #if defined(__GNUC__) && !defined(__clang__)
960b57cec5SDimitry Andric #pragma GCC diagnostic push
970b57cec5SDimitry Andric #pragma GCC diagnostic ignored "-Wformat"
980b57cec5SDimitry Andric #endif
990b57cec5SDimitry Andric     if (fscanf(StatFile,
1000b57cec5SDimitry Andric                "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*lu %*lu %*lu %*lu %*lu "
1010b57cec5SDimitry Andric                "%*lu %*ld %*ld %*ld %*ld %*ld %*ld %*llu %*lu %*ld %*lu %*lu "
1020b57cec5SDimitry Andric                "%*lu %*lu %lu %*lu %*lu %*lu %*lu %*lu %*llu %*lu %*lu %*d %*d "
1030b57cec5SDimitry Andric                "%*u %*u %*llu %*lu %*ld %*lu %*lu %*lu %*lu %*lu %*lu %lu %*d",
1040b57cec5SDimitry Andric                &StackPtr, &EnvEnd) == 2) {
1050b57cec5SDimitry Andric #if defined(__GNUC__) && !defined(__clang__)
1060b57cec5SDimitry Andric #pragma GCC diagnostic pop
1070b57cec5SDimitry Andric #endif
1080b57cec5SDimitry Andric       Usage = StackPtr < EnvEnd ? EnvEnd - StackPtr : StackPtr - EnvEnd;
1090b57cec5SDimitry Andric     }
1100b57cec5SDimitry Andric     fclose(StatFile);
1110b57cec5SDimitry Andric   }
1120b57cec5SDimitry Andric   return Usage;
1130b57cec5SDimitry Andric }
1140b57cec5SDimitry Andric 
1150b57cec5SDimitry Andric #include <alloca.h>
1160b57cec5SDimitry Andric 
1170b57cec5SDimitry Andric LLVM_ATTRIBUTE_NOINLINE
ensureStackAddressSpace()1180b57cec5SDimitry Andric static void ensureStackAddressSpace() {
1190b57cec5SDimitry Andric   // Linux kernels prior to 4.1 will sometimes locate the heap of a PIE binary
1200b57cec5SDimitry Andric   // relatively close to the stack (they are only guaranteed to be 128MiB
1210b57cec5SDimitry Andric   // apart). This results in crashes if we happen to heap-allocate more than
1220b57cec5SDimitry Andric   // 128MiB before we reach our stack high-water mark.
1230b57cec5SDimitry Andric   //
1240b57cec5SDimitry Andric   // To avoid these crashes, ensure that we have sufficient virtual memory
1250b57cec5SDimitry Andric   // pages allocated before we start running.
1260b57cec5SDimitry Andric   size_t Curr = getCurrentStackAllocation();
1270b57cec5SDimitry Andric   const int kTargetStack = DesiredStackSize - 256 * 1024;
1280b57cec5SDimitry Andric   if (Curr < kTargetStack) {
1290b57cec5SDimitry Andric     volatile char *volatile Alloc =
1300b57cec5SDimitry Andric         static_cast<volatile char *>(alloca(kTargetStack - Curr));
1310b57cec5SDimitry Andric     Alloc[0] = 0;
1320b57cec5SDimitry Andric     Alloc[kTargetStack - Curr - 1] = 0;
1330b57cec5SDimitry Andric   }
1340b57cec5SDimitry Andric }
1350b57cec5SDimitry Andric #else
ensureStackAddressSpace()1360b57cec5SDimitry Andric static void ensureStackAddressSpace() {}
1370b57cec5SDimitry Andric #endif
1380b57cec5SDimitry Andric 
1390b57cec5SDimitry Andric /// Attempt to ensure that we have at least 8MiB of usable stack space.
ensureSufficientStack()1400b57cec5SDimitry Andric static void ensureSufficientStack() {
1410b57cec5SDimitry Andric   struct rlimit rlim;
1420b57cec5SDimitry Andric   if (getrlimit(RLIMIT_STACK, &rlim) != 0)
1430b57cec5SDimitry Andric     return;
1440b57cec5SDimitry Andric 
1450b57cec5SDimitry Andric   // Increase the soft stack limit to our desired level, if necessary and
1460b57cec5SDimitry Andric   // possible.
1470b57cec5SDimitry Andric   if (rlim.rlim_cur != RLIM_INFINITY &&
1480b57cec5SDimitry Andric       rlim.rlim_cur < rlim_t(DesiredStackSize)) {
1490b57cec5SDimitry Andric     // Try to allocate sufficient stack.
1500b57cec5SDimitry Andric     if (rlim.rlim_max == RLIM_INFINITY ||
1510b57cec5SDimitry Andric         rlim.rlim_max >= rlim_t(DesiredStackSize))
1520b57cec5SDimitry Andric       rlim.rlim_cur = DesiredStackSize;
1530b57cec5SDimitry Andric     else if (rlim.rlim_cur == rlim.rlim_max)
1540b57cec5SDimitry Andric       return;
1550b57cec5SDimitry Andric     else
1560b57cec5SDimitry Andric       rlim.rlim_cur = rlim.rlim_max;
1570b57cec5SDimitry Andric 
1580b57cec5SDimitry Andric     if (setrlimit(RLIMIT_STACK, &rlim) != 0 ||
1590b57cec5SDimitry Andric         rlim.rlim_cur != DesiredStackSize)
1600b57cec5SDimitry Andric       return;
1610b57cec5SDimitry Andric   }
1620b57cec5SDimitry Andric 
1630b57cec5SDimitry Andric   // We should now have a stack of size at least DesiredStackSize. Ensure
1640b57cec5SDimitry Andric   // that we can actually use that much, if necessary.
1650b57cec5SDimitry Andric   ensureStackAddressSpace();
1660b57cec5SDimitry Andric }
1670b57cec5SDimitry Andric #else
ensureSufficientStack()1680b57cec5SDimitry Andric static void ensureSufficientStack() {}
1690b57cec5SDimitry Andric #endif
1700b57cec5SDimitry Andric 
1710b57cec5SDimitry Andric /// Print supported cpus of the given target.
PrintSupportedCPUs(std::string TargetStr)1720b57cec5SDimitry Andric static int PrintSupportedCPUs(std::string TargetStr) {
1730b57cec5SDimitry Andric   std::string Error;
1740b57cec5SDimitry Andric   const llvm::Target *TheTarget =
1750b57cec5SDimitry Andric       llvm::TargetRegistry::lookupTarget(TargetStr, Error);
1760b57cec5SDimitry Andric   if (!TheTarget) {
1770b57cec5SDimitry Andric     llvm::errs() << Error;
1780b57cec5SDimitry Andric     return 1;
1790b57cec5SDimitry Andric   }
1800b57cec5SDimitry Andric 
1810b57cec5SDimitry Andric   // the target machine will handle the mcpu printing
1820b57cec5SDimitry Andric   llvm::TargetOptions Options;
1830b57cec5SDimitry Andric   std::unique_ptr<llvm::TargetMachine> TheTargetMachine(
184bdd1243dSDimitry Andric       TheTarget->createTargetMachine(TargetStr, "", "+cpuhelp", Options,
185bdd1243dSDimitry Andric                                      std::nullopt));
1860b57cec5SDimitry Andric   return 0;
1870b57cec5SDimitry Andric }
1880b57cec5SDimitry Andric 
PrintSupportedExtensions(std::string TargetStr)1895f757f3fSDimitry Andric static int PrintSupportedExtensions(std::string TargetStr) {
1905f757f3fSDimitry Andric   std::string Error;
1915f757f3fSDimitry Andric   const llvm::Target *TheTarget =
1925f757f3fSDimitry Andric       llvm::TargetRegistry::lookupTarget(TargetStr, Error);
1935f757f3fSDimitry Andric   if (!TheTarget) {
1945f757f3fSDimitry Andric     llvm::errs() << Error;
1955f757f3fSDimitry Andric     return 1;
1965f757f3fSDimitry Andric   }
1975f757f3fSDimitry Andric 
1985f757f3fSDimitry Andric   llvm::TargetOptions Options;
1995f757f3fSDimitry Andric   std::unique_ptr<llvm::TargetMachine> TheTargetMachine(
2005f757f3fSDimitry Andric       TheTarget->createTargetMachine(TargetStr, "", "", Options, std::nullopt));
2015f757f3fSDimitry Andric   const llvm::Triple &MachineTriple = TheTargetMachine->getTargetTriple();
2025f757f3fSDimitry Andric   const llvm::MCSubtargetInfo *MCInfo = TheTargetMachine->getMCSubtargetInfo();
2035f757f3fSDimitry Andric   const llvm::ArrayRef<llvm::SubtargetFeatureKV> Features =
2045f757f3fSDimitry Andric     MCInfo->getAllProcessorFeatures();
2055f757f3fSDimitry Andric 
2065f757f3fSDimitry Andric   llvm::StringMap<llvm::StringRef> DescMap;
2075f757f3fSDimitry Andric   for (const llvm::SubtargetFeatureKV &feature : Features)
2085f757f3fSDimitry Andric     DescMap.insert({feature.Key, feature.Desc});
2095f757f3fSDimitry Andric 
2105f757f3fSDimitry Andric   if (MachineTriple.isRISCV())
2115f757f3fSDimitry Andric     llvm::riscvExtensionsHelp(DescMap);
2125f757f3fSDimitry Andric   else if (MachineTriple.isAArch64())
2135f757f3fSDimitry Andric     llvm::AArch64::PrintSupportedExtensions(DescMap);
2145f757f3fSDimitry Andric   else if (MachineTriple.isARM())
2155f757f3fSDimitry Andric     llvm::ARM::PrintSupportedExtensions(DescMap);
2165f757f3fSDimitry Andric   else {
2175f757f3fSDimitry Andric     // The option was already checked in Driver::HandleImmediateArgs,
2185f757f3fSDimitry Andric     // so we do not expect to get here if we are not a supported architecture.
2195f757f3fSDimitry Andric     assert(0 && "Unhandled triple for --print-supported-extensions option.");
2205f757f3fSDimitry Andric     return 1;
2215f757f3fSDimitry Andric   }
2225f757f3fSDimitry Andric 
2235f757f3fSDimitry Andric   return 0;
2245f757f3fSDimitry Andric }
2255f757f3fSDimitry Andric 
cc1_main(ArrayRef<const char * > Argv,const char * Argv0,void * MainAddr)2260b57cec5SDimitry Andric int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
2270b57cec5SDimitry Andric   ensureSufficientStack();
2280b57cec5SDimitry Andric 
2290b57cec5SDimitry Andric   std::unique_ptr<CompilerInstance> Clang(new CompilerInstance());
2300b57cec5SDimitry Andric   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
2310b57cec5SDimitry Andric 
2320b57cec5SDimitry Andric   // Register the support for object-file-wrapped Clang modules.
2330b57cec5SDimitry Andric   auto PCHOps = Clang->getPCHContainerOperations();
234a7dea167SDimitry Andric   PCHOps->registerWriter(std::make_unique<ObjectFilePCHContainerWriter>());
235a7dea167SDimitry Andric   PCHOps->registerReader(std::make_unique<ObjectFilePCHContainerReader>());
2360b57cec5SDimitry Andric 
2370b57cec5SDimitry Andric   // Initialize targets first, so that --version shows registered targets.
2380b57cec5SDimitry Andric   llvm::InitializeAllTargets();
2390b57cec5SDimitry Andric   llvm::InitializeAllTargetMCs();
2400b57cec5SDimitry Andric   llvm::InitializeAllAsmPrinters();
2410b57cec5SDimitry Andric   llvm::InitializeAllAsmParsers();
2420b57cec5SDimitry Andric 
2430b57cec5SDimitry Andric   // Buffer diagnostics from argument parsing so that we can output them using a
2440b57cec5SDimitry Andric   // well formed diagnostic object.
2450b57cec5SDimitry Andric   IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
2460b57cec5SDimitry Andric   TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer;
2470b57cec5SDimitry Andric   DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagsBuffer);
248fe6060f1SDimitry Andric 
249fe6060f1SDimitry Andric   // Setup round-trip remarks for the DiagnosticsEngine used in CreateFromArgs.
250fe6060f1SDimitry Andric   if (find(Argv, StringRef("-Rround-trip-cc1-args")) != Argv.end())
251fe6060f1SDimitry Andric     Diags.setSeverity(diag::remark_cc1_round_trip_generated,
252fe6060f1SDimitry Andric                       diag::Severity::Remark, {});
253fe6060f1SDimitry Andric 
2545ffd83dbSDimitry Andric   bool Success = CompilerInvocation::CreateFromArgs(Clang->getInvocation(),
2555ffd83dbSDimitry Andric                                                     Argv, Diags, Argv0);
2560b57cec5SDimitry Andric 
25706c3fb27SDimitry Andric   if (!Clang->getFrontendOpts().TimeTracePath.empty()) {
258a7dea167SDimitry Andric     llvm::timeTraceProfilerInitialize(
259480093f4SDimitry Andric         Clang->getFrontendOpts().TimeTraceGranularity, Argv0);
260a7dea167SDimitry Andric   }
2610b57cec5SDimitry Andric   // --print-supported-cpus takes priority over the actual compilation.
2620b57cec5SDimitry Andric   if (Clang->getFrontendOpts().PrintSupportedCPUs)
2630b57cec5SDimitry Andric     return PrintSupportedCPUs(Clang->getTargetOpts().Triple);
2640b57cec5SDimitry Andric 
2655f757f3fSDimitry Andric   // --print-supported-extensions takes priority over the actual compilation.
2665f757f3fSDimitry Andric   if (Clang->getFrontendOpts().PrintSupportedExtensions)
2675f757f3fSDimitry Andric     return PrintSupportedExtensions(Clang->getTargetOpts().Triple);
2685f757f3fSDimitry Andric 
2690b57cec5SDimitry Andric   // Infer the builtin include path if unspecified.
2700b57cec5SDimitry Andric   if (Clang->getHeaderSearchOpts().UseBuiltinIncludes &&
2710b57cec5SDimitry Andric       Clang->getHeaderSearchOpts().ResourceDir.empty())
2720b57cec5SDimitry Andric     Clang->getHeaderSearchOpts().ResourceDir =
2730b57cec5SDimitry Andric       CompilerInvocation::GetResourcesPath(Argv0, MainAddr);
2740b57cec5SDimitry Andric 
2750b57cec5SDimitry Andric   // Create the actual diagnostics engine.
2760b57cec5SDimitry Andric   Clang->createDiagnostics();
2770b57cec5SDimitry Andric   if (!Clang->hasDiagnostics())
2780b57cec5SDimitry Andric     return 1;
2790b57cec5SDimitry Andric 
2800b57cec5SDimitry Andric   // Set an error handler, so that any LLVM backend diagnostics go through our
2810b57cec5SDimitry Andric   // error handler.
2820b57cec5SDimitry Andric   llvm::install_fatal_error_handler(LLVMErrorHandler,
2830b57cec5SDimitry Andric                                   static_cast<void*>(&Clang->getDiagnostics()));
2840b57cec5SDimitry Andric 
2850b57cec5SDimitry Andric   DiagsBuffer->FlushDiagnostics(Clang->getDiagnostics());
28604eeddc0SDimitry Andric   if (!Success) {
28704eeddc0SDimitry Andric     Clang->getDiagnosticClient().finish();
2880b57cec5SDimitry Andric     return 1;
28904eeddc0SDimitry Andric   }
2900b57cec5SDimitry Andric 
2910b57cec5SDimitry Andric   // Execute the frontend actions.
2920b57cec5SDimitry Andric   {
293480093f4SDimitry Andric     llvm::TimeTraceScope TimeScope("ExecuteCompiler");
2940b57cec5SDimitry Andric     Success = ExecuteCompilerInvocation(Clang.get());
2950b57cec5SDimitry Andric   }
2960b57cec5SDimitry Andric 
2970b57cec5SDimitry Andric   // If any timers were active but haven't been destroyed yet, print their
2980b57cec5SDimitry Andric   // results now.  This happens in -disable-free mode.
2990b57cec5SDimitry Andric   llvm::TimerGroup::printAll(llvm::errs());
300a7dea167SDimitry Andric   llvm::TimerGroup::clearAll();
3010b57cec5SDimitry Andric 
3020b57cec5SDimitry Andric   if (llvm::timeTraceProfilerEnabled()) {
30306c3fb27SDimitry Andric     // It is possible that the compiler instance doesn't own a file manager here
30406c3fb27SDimitry Andric     // if we're compiling a module unit. Since the file manager are owned by AST
30506c3fb27SDimitry Andric     // when we're compiling a module unit. So the file manager may be invalid
30606c3fb27SDimitry Andric     // here.
30706c3fb27SDimitry Andric     //
30806c3fb27SDimitry Andric     // It should be fine to create file manager here since the file system
30906c3fb27SDimitry Andric     // options are stored in the compiler invocation and we can recreate the VFS
31006c3fb27SDimitry Andric     // from the compiler invocation.
31106c3fb27SDimitry Andric     if (!Clang->hasFileManager())
31206c3fb27SDimitry Andric       Clang->createFileManager(createVFSFromCompilerInvocation(
31306c3fb27SDimitry Andric           Clang->getInvocation(), Clang->getDiagnostics()));
31406c3fb27SDimitry Andric 
315e8d8bef9SDimitry Andric     if (auto profilerOutput = Clang->createOutputFile(
31606c3fb27SDimitry Andric             Clang->getFrontendOpts().TimeTracePath, /*Binary=*/false,
31706c3fb27SDimitry Andric             /*RemoveFileOnSignal=*/false,
318a7dea167SDimitry Andric             /*useTemporary=*/false)) {
3190b57cec5SDimitry Andric       llvm::timeTraceProfilerWrite(*profilerOutput);
32081ad6265SDimitry Andric       profilerOutput.reset();
3210b57cec5SDimitry Andric       llvm::timeTraceProfilerCleanup();
3225ffd83dbSDimitry Andric       Clang->clearOutputFiles(false);
323a7dea167SDimitry Andric     }
3240b57cec5SDimitry Andric   }
3250b57cec5SDimitry Andric 
3260b57cec5SDimitry Andric   // Our error handler depends on the Diagnostics object, which we're
3270b57cec5SDimitry Andric   // potentially about to delete. Uninstall the handler now so that any
3280b57cec5SDimitry Andric   // later errors use the default handling behavior instead.
3290b57cec5SDimitry Andric   llvm::remove_fatal_error_handler();
3300b57cec5SDimitry Andric 
3310b57cec5SDimitry Andric   // When running with -disable-free, don't do any destruction or shutdown.
3320b57cec5SDimitry Andric   if (Clang->getFrontendOpts().DisableFree) {
3330b57cec5SDimitry Andric     llvm::BuryPointer(std::move(Clang));
3340b57cec5SDimitry Andric     return !Success;
3350b57cec5SDimitry Andric   }
3360b57cec5SDimitry Andric 
3370b57cec5SDimitry Andric   return !Success;
3380b57cec5SDimitry Andric }
339