xref: /freebsd-src/contrib/llvm-project/clang/tools/driver/cc1_main.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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"
29*0fca6ea1SDimitry Andric #include "llvm/ADT/StringExtras.h"
300b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h"
310b57cec5SDimitry Andric #include "llvm/LinkAllPasses.h"
325f757f3fSDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
33349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h"
340b57cec5SDimitry Andric #include "llvm/Option/Arg.h"
350b57cec5SDimitry Andric #include "llvm/Option/ArgList.h"
360b57cec5SDimitry Andric #include "llvm/Option/OptTable.h"
370b57cec5SDimitry Andric #include "llvm/Support/BuryPointer.h"
380b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
390b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
400b57cec5SDimitry Andric #include "llvm/Support/ManagedStatic.h"
410b57cec5SDimitry Andric #include "llvm/Support/Path.h"
4213138422SDimitry Andric #include "llvm/Support/Process.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"
51*0fca6ea1SDimitry Andric #include "llvm/TargetParser/RISCVISAInfo.h"
520b57cec5SDimitry Andric #include <cstdio>
530b57cec5SDimitry Andric 
540b57cec5SDimitry Andric #ifdef CLANG_HAVE_RLIMITS
550b57cec5SDimitry Andric #include <sys/resource.h>
560b57cec5SDimitry Andric #endif
570b57cec5SDimitry Andric 
580b57cec5SDimitry Andric using namespace clang;
590b57cec5SDimitry Andric using namespace llvm::opt;
600b57cec5SDimitry Andric 
610b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
620b57cec5SDimitry Andric // Main driver
630b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
640b57cec5SDimitry Andric 
65349cc55cSDimitry Andric static void LLVMErrorHandler(void *UserData, const char *Message,
660b57cec5SDimitry Andric                              bool GenCrashDiag) {
670b57cec5SDimitry Andric   DiagnosticsEngine &Diags = *static_cast<DiagnosticsEngine*>(UserData);
680b57cec5SDimitry Andric 
690b57cec5SDimitry Andric   Diags.Report(diag::err_fe_error_backend) << Message;
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric   // Run the interrupt handlers to make sure any special cleanups get done, in
720b57cec5SDimitry Andric   // particular that we remove files registered with RemoveFileOnSignal.
730b57cec5SDimitry Andric   llvm::sys::RunInterruptHandlers();
740b57cec5SDimitry Andric 
750b57cec5SDimitry Andric   // We cannot recover from llvm errors.  When reporting a fatal error, exit
760b57cec5SDimitry Andric   // with status 70 to generate crash diagnostics.  For BSD systems this is
770b57cec5SDimitry Andric   // defined as an internal software error.  Otherwise, exit with status 1.
7813138422SDimitry Andric   llvm::sys::Process::Exit(GenCrashDiag ? 70 : 1);
790b57cec5SDimitry Andric }
800b57cec5SDimitry Andric 
810b57cec5SDimitry Andric #ifdef CLANG_HAVE_RLIMITS
820b57cec5SDimitry Andric /// Attempt to ensure that we have at least 8MiB of usable stack space.
830b57cec5SDimitry Andric static void ensureSufficientStack() {
840b57cec5SDimitry Andric   struct rlimit rlim;
850b57cec5SDimitry Andric   if (getrlimit(RLIMIT_STACK, &rlim) != 0)
860b57cec5SDimitry Andric     return;
870b57cec5SDimitry Andric 
880b57cec5SDimitry Andric   // Increase the soft stack limit to our desired level, if necessary and
890b57cec5SDimitry Andric   // possible.
900b57cec5SDimitry Andric   if (rlim.rlim_cur != RLIM_INFINITY &&
910b57cec5SDimitry Andric       rlim.rlim_cur < rlim_t(DesiredStackSize)) {
920b57cec5SDimitry Andric     // Try to allocate sufficient stack.
930b57cec5SDimitry Andric     if (rlim.rlim_max == RLIM_INFINITY ||
940b57cec5SDimitry Andric         rlim.rlim_max >= rlim_t(DesiredStackSize))
950b57cec5SDimitry Andric       rlim.rlim_cur = DesiredStackSize;
960b57cec5SDimitry Andric     else if (rlim.rlim_cur == rlim.rlim_max)
970b57cec5SDimitry Andric       return;
980b57cec5SDimitry Andric     else
990b57cec5SDimitry Andric       rlim.rlim_cur = rlim.rlim_max;
1000b57cec5SDimitry Andric 
1010b57cec5SDimitry Andric     if (setrlimit(RLIMIT_STACK, &rlim) != 0 ||
1020b57cec5SDimitry Andric         rlim.rlim_cur != DesiredStackSize)
1030b57cec5SDimitry Andric       return;
1040b57cec5SDimitry Andric   }
1050b57cec5SDimitry Andric }
1060b57cec5SDimitry Andric #else
1070b57cec5SDimitry Andric static void ensureSufficientStack() {}
1080b57cec5SDimitry Andric #endif
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric /// Print supported cpus of the given target.
1110b57cec5SDimitry Andric static int PrintSupportedCPUs(std::string TargetStr) {
1120b57cec5SDimitry Andric   std::string Error;
1130b57cec5SDimitry Andric   const llvm::Target *TheTarget =
1140b57cec5SDimitry Andric       llvm::TargetRegistry::lookupTarget(TargetStr, Error);
1150b57cec5SDimitry Andric   if (!TheTarget) {
1160b57cec5SDimitry Andric     llvm::errs() << Error;
1170b57cec5SDimitry Andric     return 1;
1180b57cec5SDimitry Andric   }
1190b57cec5SDimitry Andric 
1200b57cec5SDimitry Andric   // the target machine will handle the mcpu printing
1210b57cec5SDimitry Andric   llvm::TargetOptions Options;
1220b57cec5SDimitry Andric   std::unique_ptr<llvm::TargetMachine> TheTargetMachine(
123bdd1243dSDimitry Andric       TheTarget->createTargetMachine(TargetStr, "", "+cpuhelp", Options,
124bdd1243dSDimitry Andric                                      std::nullopt));
1250b57cec5SDimitry Andric   return 0;
1260b57cec5SDimitry Andric }
1270b57cec5SDimitry Andric 
1285f757f3fSDimitry Andric static int PrintSupportedExtensions(std::string TargetStr) {
1295f757f3fSDimitry Andric   std::string Error;
1305f757f3fSDimitry Andric   const llvm::Target *TheTarget =
1315f757f3fSDimitry Andric       llvm::TargetRegistry::lookupTarget(TargetStr, Error);
1325f757f3fSDimitry Andric   if (!TheTarget) {
1335f757f3fSDimitry Andric     llvm::errs() << Error;
1345f757f3fSDimitry Andric     return 1;
1355f757f3fSDimitry Andric   }
1365f757f3fSDimitry Andric 
1375f757f3fSDimitry Andric   llvm::TargetOptions Options;
1385f757f3fSDimitry Andric   std::unique_ptr<llvm::TargetMachine> TheTargetMachine(
1395f757f3fSDimitry Andric       TheTarget->createTargetMachine(TargetStr, "", "", Options, std::nullopt));
1405f757f3fSDimitry Andric   const llvm::Triple &MachineTriple = TheTargetMachine->getTargetTriple();
1415f757f3fSDimitry Andric   const llvm::MCSubtargetInfo *MCInfo = TheTargetMachine->getMCSubtargetInfo();
1425f757f3fSDimitry Andric   const llvm::ArrayRef<llvm::SubtargetFeatureKV> Features =
1435f757f3fSDimitry Andric     MCInfo->getAllProcessorFeatures();
1445f757f3fSDimitry Andric 
1455f757f3fSDimitry Andric   llvm::StringMap<llvm::StringRef> DescMap;
1465f757f3fSDimitry Andric   for (const llvm::SubtargetFeatureKV &feature : Features)
1475f757f3fSDimitry Andric     DescMap.insert({feature.Key, feature.Desc});
1485f757f3fSDimitry Andric 
1495f757f3fSDimitry Andric   if (MachineTriple.isRISCV())
150*0fca6ea1SDimitry Andric     llvm::RISCVISAInfo::printSupportedExtensions(DescMap);
1515f757f3fSDimitry Andric   else if (MachineTriple.isAArch64())
152*0fca6ea1SDimitry Andric     llvm::AArch64::PrintSupportedExtensions();
1535f757f3fSDimitry Andric   else if (MachineTriple.isARM())
1545f757f3fSDimitry Andric     llvm::ARM::PrintSupportedExtensions(DescMap);
1555f757f3fSDimitry Andric   else {
1565f757f3fSDimitry Andric     // The option was already checked in Driver::HandleImmediateArgs,
1575f757f3fSDimitry Andric     // so we do not expect to get here if we are not a supported architecture.
1585f757f3fSDimitry Andric     assert(0 && "Unhandled triple for --print-supported-extensions option.");
1595f757f3fSDimitry Andric     return 1;
1605f757f3fSDimitry Andric   }
1615f757f3fSDimitry Andric 
1625f757f3fSDimitry Andric   return 0;
1635f757f3fSDimitry Andric }
1645f757f3fSDimitry Andric 
165*0fca6ea1SDimitry Andric static int PrintEnabledExtensions(const TargetOptions& TargetOpts) {
166*0fca6ea1SDimitry Andric   std::string Error;
167*0fca6ea1SDimitry Andric   const llvm::Target *TheTarget =
168*0fca6ea1SDimitry Andric       llvm::TargetRegistry::lookupTarget(TargetOpts.Triple, Error);
169*0fca6ea1SDimitry Andric   if (!TheTarget) {
170*0fca6ea1SDimitry Andric     llvm::errs() << Error;
171*0fca6ea1SDimitry Andric     return 1;
172*0fca6ea1SDimitry Andric   }
173*0fca6ea1SDimitry Andric 
174*0fca6ea1SDimitry Andric   // Create a target machine using the input features, the triple information
175*0fca6ea1SDimitry Andric   // and a dummy instance of llvm::TargetOptions. Note that this is _not_ the
176*0fca6ea1SDimitry Andric   // same as the `clang::TargetOptions` instance we have access to here.
177*0fca6ea1SDimitry Andric   llvm::TargetOptions BackendOptions;
178*0fca6ea1SDimitry Andric   std::string FeaturesStr = llvm::join(TargetOpts.FeaturesAsWritten, ",");
179*0fca6ea1SDimitry Andric   std::unique_ptr<llvm::TargetMachine> TheTargetMachine(
180*0fca6ea1SDimitry Andric       TheTarget->createTargetMachine(TargetOpts.Triple, TargetOpts.CPU, FeaturesStr, BackendOptions, std::nullopt));
181*0fca6ea1SDimitry Andric   const llvm::Triple &MachineTriple = TheTargetMachine->getTargetTriple();
182*0fca6ea1SDimitry Andric   const llvm::MCSubtargetInfo *MCInfo = TheTargetMachine->getMCSubtargetInfo();
183*0fca6ea1SDimitry Andric 
184*0fca6ea1SDimitry Andric   // Extract the feature names that are enabled for the given target.
185*0fca6ea1SDimitry Andric   // We do that by capturing the key from the set of SubtargetFeatureKV entries
186*0fca6ea1SDimitry Andric   // provided by MCSubtargetInfo, which match the '-target-feature' values.
187*0fca6ea1SDimitry Andric   const std::vector<llvm::SubtargetFeatureKV> Features =
188*0fca6ea1SDimitry Andric     MCInfo->getEnabledProcessorFeatures();
189*0fca6ea1SDimitry Andric   std::set<llvm::StringRef> EnabledFeatureNames;
190*0fca6ea1SDimitry Andric   for (const llvm::SubtargetFeatureKV &feature : Features)
191*0fca6ea1SDimitry Andric     EnabledFeatureNames.insert(feature.Key);
192*0fca6ea1SDimitry Andric 
193*0fca6ea1SDimitry Andric   if (MachineTriple.isAArch64())
194*0fca6ea1SDimitry Andric     llvm::AArch64::printEnabledExtensions(EnabledFeatureNames);
195*0fca6ea1SDimitry Andric   else if (MachineTriple.isRISCV()) {
196*0fca6ea1SDimitry Andric     llvm::StringMap<llvm::StringRef> DescMap;
197*0fca6ea1SDimitry Andric     for (const llvm::SubtargetFeatureKV &feature : Features)
198*0fca6ea1SDimitry Andric       DescMap.insert({feature.Key, feature.Desc});
199*0fca6ea1SDimitry Andric     llvm::RISCVISAInfo::printEnabledExtensions(MachineTriple.isArch64Bit(),
200*0fca6ea1SDimitry Andric                                                EnabledFeatureNames, DescMap);
201*0fca6ea1SDimitry Andric   } else {
202*0fca6ea1SDimitry Andric     // The option was already checked in Driver::HandleImmediateArgs,
203*0fca6ea1SDimitry Andric     // so we do not expect to get here if we are not a supported architecture.
204*0fca6ea1SDimitry Andric     assert(0 && "Unhandled triple for --print-enabled-extensions option.");
205*0fca6ea1SDimitry Andric     return 1;
206*0fca6ea1SDimitry Andric   }
207*0fca6ea1SDimitry Andric 
208*0fca6ea1SDimitry Andric   return 0;
209*0fca6ea1SDimitry Andric }
210*0fca6ea1SDimitry Andric 
2110b57cec5SDimitry Andric int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
2120b57cec5SDimitry Andric   ensureSufficientStack();
2130b57cec5SDimitry Andric 
2140b57cec5SDimitry Andric   std::unique_ptr<CompilerInstance> Clang(new CompilerInstance());
2150b57cec5SDimitry Andric   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
2160b57cec5SDimitry Andric 
2170b57cec5SDimitry Andric   // Register the support for object-file-wrapped Clang modules.
2180b57cec5SDimitry Andric   auto PCHOps = Clang->getPCHContainerOperations();
219a7dea167SDimitry Andric   PCHOps->registerWriter(std::make_unique<ObjectFilePCHContainerWriter>());
220a7dea167SDimitry Andric   PCHOps->registerReader(std::make_unique<ObjectFilePCHContainerReader>());
2210b57cec5SDimitry Andric 
2220b57cec5SDimitry Andric   // Initialize targets first, so that --version shows registered targets.
2230b57cec5SDimitry Andric   llvm::InitializeAllTargets();
2240b57cec5SDimitry Andric   llvm::InitializeAllTargetMCs();
2250b57cec5SDimitry Andric   llvm::InitializeAllAsmPrinters();
2260b57cec5SDimitry Andric   llvm::InitializeAllAsmParsers();
2270b57cec5SDimitry Andric 
2280b57cec5SDimitry Andric   // Buffer diagnostics from argument parsing so that we can output them using a
2290b57cec5SDimitry Andric   // well formed diagnostic object.
2300b57cec5SDimitry Andric   IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
2310b57cec5SDimitry Andric   TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer;
2320b57cec5SDimitry Andric   DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagsBuffer);
233fe6060f1SDimitry Andric 
234fe6060f1SDimitry Andric   // Setup round-trip remarks for the DiagnosticsEngine used in CreateFromArgs.
235fe6060f1SDimitry Andric   if (find(Argv, StringRef("-Rround-trip-cc1-args")) != Argv.end())
236fe6060f1SDimitry Andric     Diags.setSeverity(diag::remark_cc1_round_trip_generated,
237fe6060f1SDimitry Andric                       diag::Severity::Remark, {});
238fe6060f1SDimitry Andric 
2395ffd83dbSDimitry Andric   bool Success = CompilerInvocation::CreateFromArgs(Clang->getInvocation(),
2405ffd83dbSDimitry Andric                                                     Argv, Diags, Argv0);
2410b57cec5SDimitry Andric 
24206c3fb27SDimitry Andric   if (!Clang->getFrontendOpts().TimeTracePath.empty()) {
243a7dea167SDimitry Andric     llvm::timeTraceProfilerInitialize(
244*0fca6ea1SDimitry Andric         Clang->getFrontendOpts().TimeTraceGranularity, Argv0,
245*0fca6ea1SDimitry Andric         Clang->getFrontendOpts().TimeTraceVerbose);
246a7dea167SDimitry Andric   }
2470b57cec5SDimitry Andric   // --print-supported-cpus takes priority over the actual compilation.
2480b57cec5SDimitry Andric   if (Clang->getFrontendOpts().PrintSupportedCPUs)
2490b57cec5SDimitry Andric     return PrintSupportedCPUs(Clang->getTargetOpts().Triple);
2500b57cec5SDimitry Andric 
2515f757f3fSDimitry Andric   // --print-supported-extensions takes priority over the actual compilation.
2525f757f3fSDimitry Andric   if (Clang->getFrontendOpts().PrintSupportedExtensions)
2535f757f3fSDimitry Andric     return PrintSupportedExtensions(Clang->getTargetOpts().Triple);
2545f757f3fSDimitry Andric 
255*0fca6ea1SDimitry Andric   // --print-enabled-extensions takes priority over the actual compilation.
256*0fca6ea1SDimitry Andric   if (Clang->getFrontendOpts().PrintEnabledExtensions)
257*0fca6ea1SDimitry Andric     return PrintEnabledExtensions(Clang->getTargetOpts());
258*0fca6ea1SDimitry Andric 
2590b57cec5SDimitry Andric   // Infer the builtin include path if unspecified.
2600b57cec5SDimitry Andric   if (Clang->getHeaderSearchOpts().UseBuiltinIncludes &&
2610b57cec5SDimitry Andric       Clang->getHeaderSearchOpts().ResourceDir.empty())
2620b57cec5SDimitry Andric     Clang->getHeaderSearchOpts().ResourceDir =
2630b57cec5SDimitry Andric       CompilerInvocation::GetResourcesPath(Argv0, MainAddr);
2640b57cec5SDimitry Andric 
2650b57cec5SDimitry Andric   // Create the actual diagnostics engine.
2660b57cec5SDimitry Andric   Clang->createDiagnostics();
2670b57cec5SDimitry Andric   if (!Clang->hasDiagnostics())
2680b57cec5SDimitry Andric     return 1;
2690b57cec5SDimitry Andric 
2700b57cec5SDimitry Andric   // Set an error handler, so that any LLVM backend diagnostics go through our
2710b57cec5SDimitry Andric   // error handler.
2720b57cec5SDimitry Andric   llvm::install_fatal_error_handler(LLVMErrorHandler,
2730b57cec5SDimitry Andric                                   static_cast<void*>(&Clang->getDiagnostics()));
2740b57cec5SDimitry Andric 
2750b57cec5SDimitry Andric   DiagsBuffer->FlushDiagnostics(Clang->getDiagnostics());
27604eeddc0SDimitry Andric   if (!Success) {
27704eeddc0SDimitry Andric     Clang->getDiagnosticClient().finish();
2780b57cec5SDimitry Andric     return 1;
27904eeddc0SDimitry Andric   }
2800b57cec5SDimitry Andric 
2810b57cec5SDimitry Andric   // Execute the frontend actions.
2820b57cec5SDimitry Andric   {
283480093f4SDimitry Andric     llvm::TimeTraceScope TimeScope("ExecuteCompiler");
2840b57cec5SDimitry Andric     Success = ExecuteCompilerInvocation(Clang.get());
2850b57cec5SDimitry Andric   }
2860b57cec5SDimitry Andric 
2870b57cec5SDimitry Andric   // If any timers were active but haven't been destroyed yet, print their
2880b57cec5SDimitry Andric   // results now.  This happens in -disable-free mode.
2890b57cec5SDimitry Andric   llvm::TimerGroup::printAll(llvm::errs());
290a7dea167SDimitry Andric   llvm::TimerGroup::clearAll();
2910b57cec5SDimitry Andric 
2920b57cec5SDimitry Andric   if (llvm::timeTraceProfilerEnabled()) {
29306c3fb27SDimitry Andric     // It is possible that the compiler instance doesn't own a file manager here
29406c3fb27SDimitry Andric     // if we're compiling a module unit. Since the file manager are owned by AST
29506c3fb27SDimitry Andric     // when we're compiling a module unit. So the file manager may be invalid
29606c3fb27SDimitry Andric     // here.
29706c3fb27SDimitry Andric     //
29806c3fb27SDimitry Andric     // It should be fine to create file manager here since the file system
29906c3fb27SDimitry Andric     // options are stored in the compiler invocation and we can recreate the VFS
30006c3fb27SDimitry Andric     // from the compiler invocation.
30106c3fb27SDimitry Andric     if (!Clang->hasFileManager())
30206c3fb27SDimitry Andric       Clang->createFileManager(createVFSFromCompilerInvocation(
30306c3fb27SDimitry Andric           Clang->getInvocation(), Clang->getDiagnostics()));
30406c3fb27SDimitry Andric 
305e8d8bef9SDimitry Andric     if (auto profilerOutput = Clang->createOutputFile(
30606c3fb27SDimitry Andric             Clang->getFrontendOpts().TimeTracePath, /*Binary=*/false,
30706c3fb27SDimitry Andric             /*RemoveFileOnSignal=*/false,
308a7dea167SDimitry Andric             /*useTemporary=*/false)) {
3090b57cec5SDimitry Andric       llvm::timeTraceProfilerWrite(*profilerOutput);
31081ad6265SDimitry Andric       profilerOutput.reset();
3110b57cec5SDimitry Andric       llvm::timeTraceProfilerCleanup();
3125ffd83dbSDimitry Andric       Clang->clearOutputFiles(false);
313a7dea167SDimitry Andric     }
3140b57cec5SDimitry Andric   }
3150b57cec5SDimitry Andric 
3160b57cec5SDimitry Andric   // Our error handler depends on the Diagnostics object, which we're
3170b57cec5SDimitry Andric   // potentially about to delete. Uninstall the handler now so that any
3180b57cec5SDimitry Andric   // later errors use the default handling behavior instead.
3190b57cec5SDimitry Andric   llvm::remove_fatal_error_handler();
3200b57cec5SDimitry Andric 
3210b57cec5SDimitry Andric   // When running with -disable-free, don't do any destruction or shutdown.
3220b57cec5SDimitry Andric   if (Clang->getFrontendOpts().DisableFree) {
3230b57cec5SDimitry Andric     llvm::BuryPointer(std::move(Clang));
3240b57cec5SDimitry Andric     return !Success;
3250b57cec5SDimitry Andric   }
3260b57cec5SDimitry Andric 
3270b57cec5SDimitry Andric   return !Success;
3280b57cec5SDimitry Andric }
329