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