1163953Srrs//===-- cc1_main.cpp - Clang CC1 Compiler Frontend ------------------------===// 2185694Srrs// 3235828Stuexen// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4235828Stuexen// See https://llvm.org/LICENSE.txt for license information. 5163953Srrs// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6163953Srrs// 7163953Srrs//===----------------------------------------------------------------------===// 8163953Srrs// 9163953Srrs// This is the entry point to the clang -cc1 functionality, which implements the 10228653Stuexen// core compiler functionality along with a number of additional tools for 11163953Srrs// demonstration and testing purposes. 12163953Srrs// 13163953Srrs//===----------------------------------------------------------------------===// 14228653Stuexen 15163953Srrs#include "clang/Basic/Stack.h" 16163953Srrs#include "clang/Basic/TargetOptions.h" 17163953Srrs#include "clang/CodeGen/ObjectFilePCHContainerOperations.h" 18163953Srrs#include "clang/Config/config.h" 19163953Srrs#include "clang/Driver/DriverDiagnostic.h" 20163953Srrs#include "clang/Driver/Options.h" 21163953Srrs#include "clang/Frontend/CompilerInstance.h" 22163953Srrs#include "clang/Frontend/CompilerInvocation.h" 23163953Srrs#include "clang/Frontend/FrontendDiagnostic.h" 24163953Srrs#include "clang/Frontend/TextDiagnosticBuffer.h" 25163953Srrs#include "clang/Frontend/TextDiagnosticPrinter.h" 26163953Srrs#include "clang/Frontend/Utils.h" 27163953Srrs#include "clang/FrontendTool/Utils.h" 28163953Srrs#include "llvm/ADT/Statistic.h" 29163953Srrs#include "llvm/Config/llvm-config.h" 30163953Srrs#include "llvm/LinkAllPasses.h" 31163953Srrs#include "llvm/Option/Arg.h" 32163953Srrs#include "llvm/Option/ArgList.h" 33163953Srrs#include "llvm/Option/OptTable.h" 34163953Srrs#include "llvm/Support/BuryPointer.h" 35163953Srrs#include "llvm/Support/Compiler.h" 36163953Srrs#include "llvm/Support/ErrorHandling.h" 37163953Srrs#include "llvm/Support/ManagedStatic.h" 38167598Srrs#include "llvm/Support/Path.h" 39163953Srrs#include "llvm/Support/Process.h" 40163953Srrs#include "llvm/Support/Signals.h" 41163953Srrs#include "llvm/Support/TargetRegistry.h" 42163953Srrs#include "llvm/Support/TargetSelect.h" 43163953Srrs#include "llvm/Support/TimeProfiler.h" 44163953Srrs#include "llvm/Support/Timer.h" 45163953Srrs#include "llvm/Support/raw_ostream.h" 46163953Srrs#include "llvm/Target/TargetMachine.h" 47170091Srrs#include <cstdio> 48172091Srrs 49188067Srrs#ifdef CLANG_HAVE_RLIMITS 50270350Stuexen#include <sys/resource.h> 51179157Srrs#endif 52270350Stuexen 53218211Srrsusing namespace clang; 54163953Srrsusing namespace llvm::opt; 55163953Srrs 56163953Srrs//===----------------------------------------------------------------------===// 57163953Srrs// Main driver 58163953Srrs//===----------------------------------------------------------------------===// 59163953Srrs 60163953Srrsstatic void LLVMErrorHandler(void *UserData, const std::string &Message, 61163953Srrs bool GenCrashDiag) { 62165220Srrs DiagnosticsEngine &Diags = *static_cast<DiagnosticsEngine*>(UserData); 63165220Srrs 64165220Srrs Diags.Report(diag::err_fe_error_backend) << Message; 65165220Srrs 66165220Srrs // Run the interrupt handlers to make sure any special cleanups get done, in 67163953Srrs // particular that we remove files registered with RemoveFileOnSignal. 68163953Srrs llvm::sys::RunInterruptHandlers(); 69165220Srrs 70163953Srrs // We cannot recover from llvm errors. When reporting a fatal error, exit 71163953Srrs // with status 70 to generate crash diagnostics. For BSD systems this is 72163953Srrs // defined as an internal software error. Otherwise, exit with status 1. 73165220Srrs llvm::sys::Process::Exit(GenCrashDiag ? 70 : 1); 74165220Srrs} 75165220Srrs 76165220Srrs#ifdef CLANG_HAVE_RLIMITS 77165220Srrs#if defined(__linux__) && defined(__PIE__) 78165220Srrsstatic size_t getCurrentStackAllocation() { 79163953Srrs // If we can't compute the current stack usage, allow for 512K of command 80163953Srrs // line arguments and environment. 81163953Srrs size_t Usage = 512 * 1024; 82163953Srrs if (FILE *StatFile = fopen("/proc/self/stat", "r")) { 83163953Srrs // We assume that the stack extends from its current address to the end of 84163953Srrs // the environment space. In reality, there is another string literal (the 85237715Stuexen // program name) after the environment, but this is close enough (we only 86237715Stuexen // need to be within 100K or so). 87237049Stuexen unsigned long StackPtr, EnvEnd; 88237049Stuexen // Disable silly GCC -Wformat warning that complains about length 89281955Shiren // modifiers on ignored format specifiers. We want to retain these 90237049Stuexen // for documentation purposes even though they have no effect. 91163953Srrs#if defined(__GNUC__) && !defined(__clang__) 92163953Srrs#pragma GCC diagnostic push 93163953Srrs#pragma GCC diagnostic ignored "-Wformat" 94163953Srrs#endif 95169420Srrs if (fscanf(StatFile, 96240148Stuexen "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*lu %*lu %*lu %*lu %*lu " 97172396Srrs "%*lu %*ld %*ld %*ld %*ld %*ld %*ld %*llu %*lu %*ld %*lu %*lu " 98172396Srrs "%*lu %*lu %lu %*lu %*lu %*lu %*lu %*lu %*llu %*lu %*lu %*d %*d " 99172396Srrs "%*u %*u %*llu %*lu %*ld %*lu %*lu %*lu %*lu %*lu %*lu %lu %*d", 100229774Stuexen &StackPtr, &EnvEnd) == 2) { 101163953Srrs#if defined(__GNUC__) && !defined(__clang__) 102267723Stuexen#pragma GCC diagnostic pop 103237715Stuexen#endif 104281955Shiren Usage = StackPtr < EnvEnd ? EnvEnd - StackPtr : StackPtr - EnvEnd; 105179157Srrs } 106168299Srrs fclose(StatFile); 107168299Srrs } 108172396Srrs return Usage; 109163953Srrs} 110163953Srrs 111229774Stuexen#include <alloca.h> 112163953Srrs 113163953SrrsLLVM_ATTRIBUTE_NOINLINE 114267723Stuexenstatic void ensureStackAddressSpace() { 115237715Stuexen // Linux kernels prior to 4.1 will sometimes locate the heap of a PIE binary 116281955Shiren // relatively close to the stack (they are only guaranteed to be 128MiB 117179157Srrs // apart). This results in crashes if we happen to heap-allocate more than 118168299Srrs // 128MiB before we reach our stack high-water mark. 119168299Srrs // 120172396Srrs // To avoid these crashes, ensure that we have sufficient virtual memory 121163953Srrs // pages allocated before we start running. 122163953Srrs size_t Curr = getCurrentStackAllocation(); 123163953Srrs const int kTargetStack = DesiredStackSize - 256 * 1024; 124267723Stuexen if (Curr < kTargetStack) { 125237715Stuexen volatile char *volatile Alloc = 126281955Shiren static_cast<volatile char *>(alloca(kTargetStack - Curr)); 127179157Srrs Alloc[0] = 0; 128171440Srrs Alloc[kTargetStack - Curr - 1] = 0; 129171440Srrs } 130172396Srrs} 131163953Srrs#else 132163953Srrsstatic void ensureStackAddressSpace() {} 133163953Srrs#endif 134267723Stuexen 135237715Stuexen/// Attempt to ensure that we have at least 8MiB of usable stack space. 136281955Shirenstatic void ensureSufficientStack() { 137179157Srrs struct rlimit rlim; 138168299Srrs if (getrlimit(RLIMIT_STACK, &rlim) != 0) 139168299Srrs return; 140172396Srrs 141163953Srrs // Increase the soft stack limit to our desired level, if necessary and 142163953Srrs // possible. 143163953Srrs if (rlim.rlim_cur != RLIM_INFINITY && 144267723Stuexen rlim.rlim_cur < rlim_t(DesiredStackSize)) { 145237715Stuexen // Try to allocate sufficient stack. 146281955Shiren if (rlim.rlim_max == RLIM_INFINITY || 147179157Srrs rlim.rlim_max >= rlim_t(DesiredStackSize)) 148168299Srrs rlim.rlim_cur = DesiredStackSize; 149168299Srrs else if (rlim.rlim_cur == rlim.rlim_max) 150172396Srrs return; 151163953Srrs else 152163953Srrs rlim.rlim_cur = rlim.rlim_max; 153229774Stuexen 154163953Srrs if (setrlimit(RLIMIT_STACK, &rlim) != 0 || 155267723Stuexen rlim.rlim_cur != DesiredStackSize) 156267723Stuexen return; 157267723Stuexen } 158281955Shiren 159237049Stuexen // We should now have a stack of size at least DesiredStackSize. Ensure 160168299Srrs // that we can actually use that much, if necessary. 161168299Srrs ensureStackAddressSpace(); 162172396Srrs} 163163953Srrs#else 164229774Stuexenstatic void ensureSufficientStack() {} 165229774Stuexen#endif 166229774Stuexen 167229774Stuexen/// Print supported cpus of the given target. 168229774Stuexenstatic int PrintSupportedCPUs(std::string TargetStr) { 169229774Stuexen std::string Error; 170229774Stuexen const llvm::Target *TheTarget = 171229774Stuexen llvm::TargetRegistry::lookupTarget(TargetStr, Error); 172229774Stuexen if (!TheTarget) { 173229774Stuexen llvm::errs() << Error; 174229774Stuexen return 1; 175229774Stuexen } 176229774Stuexen 177229774Stuexen // the target machine will handle the mcpu printing 178229774Stuexen llvm::TargetOptions Options; 179229774Stuexen std::unique_ptr<llvm::TargetMachine> TheTargetMachine( 180229774Stuexen TheTarget->createTargetMachine(TargetStr, "", "+cpuhelp", Options, None)); 181229774Stuexen return 0; 182229774Stuexen} 183229774Stuexen 184229774Stuexenint cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) { 185229805Stuexen ensureSufficientStack(); 186267723Stuexen 187267723Stuexen std::unique_ptr<CompilerInstance> Clang(new CompilerInstance()); 188267723Stuexen IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); 189284633Stuexen 190237049Stuexen // Register the support for object-file-wrapped Clang modules. 191229805Stuexen auto PCHOps = Clang->getPCHContainerOperations(); 192229774Stuexen PCHOps->registerWriter(std::make_unique<ObjectFilePCHContainerWriter>()); 193229774Stuexen PCHOps->registerReader(std::make_unique<ObjectFilePCHContainerReader>()); 194229774Stuexen 195229774Stuexen // Initialize targets first, so that --version shows registered targets. 196229774Stuexen llvm::InitializeAllTargets(); 197229774Stuexen llvm::InitializeAllTargetMCs(); 198229774Stuexen llvm::InitializeAllAsmPrinters(); 199229774Stuexen llvm::InitializeAllAsmParsers(); 200229774Stuexen 201237715Stuexen // Buffer diagnostics from argument parsing so that we can output them using a 202237715Stuexen // well formed diagnostic object. 203281955Shiren IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions(); 204237049Stuexen TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer; 205229774Stuexen DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagsBuffer); 206229774Stuexen 207172396Srrs // Setup round-trip remarks for the DiagnosticsEngine used in CreateFromArgs. 208172396Srrs if (find(Argv, StringRef("-Rround-trip-cc1-args")) != Argv.end()) 209172396Srrs Diags.setSeverity(diag::remark_cc1_round_trip_generated, 210172396Srrs diag::Severity::Remark, {}); 211163953Srrs 212163953Srrs bool Success = CompilerInvocation::CreateFromArgs(Clang->getInvocation(), 213163953Srrs Argv, Diags, Argv0); 214163953Srrs 215163953Srrs if (Clang->getFrontendOpts().TimeTrace) { 216171158Srrs llvm::timeTraceProfilerInitialize( 217171158Srrs Clang->getFrontendOpts().TimeTraceGranularity, Argv0); 218221627Stuexen } 219221627Stuexen // --print-supported-cpus takes priority over the actual compilation. 220221627Stuexen if (Clang->getFrontendOpts().PrintSupportedCPUs) 221221627Stuexen return PrintSupportedCPUs(Clang->getTargetOpts().Triple); 222221627Stuexen 223171158Srrs // Infer the builtin include path if unspecified. 224171158Srrs if (Clang->getHeaderSearchOpts().UseBuiltinIncludes && 225217760Stuexen Clang->getHeaderSearchOpts().ResourceDir.empty()) 226217760Stuexen Clang->getHeaderSearchOpts().ResourceDir = 227171158Srrs CompilerInvocation::GetResourcesPath(Argv0, MainAddr); 228171158Srrs 229171158Srrs // Create the actual diagnostics engine. 230171158Srrs Clang->createDiagnostics(); 231171158Srrs if (!Clang->hasDiagnostics()) 232171158Srrs return 1; 233171158Srrs 234171158Srrs // Set an error handler, so that any LLVM backend diagnostics go through our 235171158Srrs // error handler. 236171158Srrs llvm::install_fatal_error_handler(LLVMErrorHandler, 237217760Stuexen static_cast<void*>(&Clang->getDiagnostics())); 238217760Stuexen 239217760Stuexen DiagsBuffer->FlushDiagnostics(Clang->getDiagnostics()); 240217760Stuexen if (!Success) 241217760Stuexen return 1; 242217760Stuexen 243217760Stuexen // Execute the frontend actions. 244217760Stuexen { 245171158Srrs llvm::TimeTraceScope TimeScope("ExecuteCompiler"); 246171158Srrs Success = ExecuteCompilerInvocation(Clang.get()); 247171158Srrs } 248171158Srrs 249171158Srrs // If any timers were active but haven't been destroyed yet, print their 250171158Srrs // results now. This happens in -disable-free mode. 251171158Srrs llvm::TimerGroup::printAll(llvm::errs()); 252171158Srrs llvm::TimerGroup::clearAll(); 253171158Srrs 254171158Srrs if (llvm::timeTraceProfilerEnabled()) { 255171158Srrs SmallString<128> Path(Clang->getFrontendOpts().OutputFile); 256171158Srrs llvm::sys::path::replace_extension(Path, "json"); 257171158Srrs if (auto profilerOutput = Clang->createOutputFile( 258171158Srrs Path.str(), /*Binary=*/false, /*RemoveFileOnSignal=*/false, 259171158Srrs /*useTemporary=*/false)) { 260171158Srrs llvm::timeTraceProfilerWrite(*profilerOutput); 261217760Stuexen // FIXME(ibiryukov): make profilerOutput flush in destructor instead. 262217760Stuexen profilerOutput->flush(); 263212712Stuexen llvm::timeTraceProfilerCleanup(); 264212712Stuexen Clang->clearOutputFiles(false); 265212712Stuexen } 266212712Stuexen } 267171158Srrs 268171158Srrs // Our error handler depends on the Diagnostics object, which we're 269171158Srrs // potentially about to delete. Uninstall the handler now so that any 270171158Srrs // later errors use the default handling behavior instead. 271221627Stuexen llvm::remove_fatal_error_handler(); 272171158Srrs 273171158Srrs // When running with -disable-free, don't do any destruction or shutdown. 274216822Stuexen if (Clang->getFrontendOpts().DisableFree) { 275171158Srrs llvm::BuryPointer(std::move(Clang)); 276171158Srrs return !Success; 277171158Srrs } 278171158Srrs 279171158Srrs return !Success; 280171158Srrs} 281171158Srrs