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
LLVMErrorHandler(void * UserData,const char * Message,bool GenCrashDiag)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.
ensureSufficientStack()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
ensureSufficientStack()1070b57cec5SDimitry Andric static void ensureSufficientStack() {}
1080b57cec5SDimitry Andric #endif
1090b57cec5SDimitry Andric
1100b57cec5SDimitry Andric /// Print supported cpus of the given target.
PrintSupportedCPUs(std::string TargetStr)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
PrintSupportedExtensions(std::string TargetStr)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
PrintEnabledExtensions(const TargetOptions & TargetOpts)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
cc1_main(ArrayRef<const char * > Argv,const char * Argv0,void * MainAddr)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