╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ zig_clang_cc1_main.cpp ───────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭ find file ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╮ ╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │ │ │http│ ssh │ │ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╯ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
160 llvm::ARM::PrintSupportedExtensions(DescMap); 161 else { 162 // The option was already checked in Driver::HandleImmediateArgs, 163 // so we do not expect to get here if we are not a supported architecture. 164 assert(0 && "Unhandled triple for --print-supported-extensions option."); 165 return 1; 166 } 167 168 return 0; 169 } 170 171 static int PrintEnabledExtensions(const TargetOptions& TargetOpts) { 172 llvm::Triple Triple(TargetOpts.Triple); 173 std::string Error; 174 const llvm::Target *TheTarget = 175 llvm::TargetRegistry::lookupTarget(Triple, Error); 176 if (!TheTarget) { 177 llvm::errs() << Error; 178 return 1; 179 } 180 181 // Create a target machine using the input features, the triple information 182 // and a dummy instance of llvm::TargetOptions. Note that this is _not_ the 183 // same as the `clang::TargetOptions` instance we have access to here. 184 llvm::TargetOptions BackendOptions; 185 std::string FeaturesStr = llvm::join(TargetOpts.FeaturesAsWritten, ","); 186 std::unique_ptr<llvm::TargetMachine> TheTargetMachine( 187 TheTarget->createTargetMachine(Triple, TargetOpts.CPU, FeaturesStr, 188 BackendOptions, std::nullopt)); 189 const llvm::Triple &MachineTriple = TheTargetMachine->getTargetTriple(); 190 const llvm::MCSubtargetInfo *MCInfo = TheTargetMachine->getMCSubtargetInfo(); 191 192 // Extract the feature names that are enabled for the given target. 193 // We do that by capturing the key from the set of SubtargetFeatureKV entries 194 // provided by MCSubtargetInfo, which match the '-target-feature' values. 195 const std::vector<llvm::SubtargetFeatureKV> Features = 196 MCInfo->getEnabledProcessorFeatures(); 197 std::set<llvm::StringRef> EnabledFeatureNames; 198 for (const llvm::SubtargetFeatureKV &feature : Features) 199 EnabledFeatureNames.insert(feature.Key); 200 201 if (MachineTriple.isAArch64()) 202 llvm::AArch64::printEnabledExtensions(EnabledFeatureNames); 203 else if (MachineTriple.isRISCV()) { 204 llvm::StringMap<llvm::StringRef> DescMap; 205 for (const llvm::SubtargetFeatureKV &feature : Features) 206 DescMap.insert({feature.Key, feature.Desc}); 207 llvm::RISCVISAInfo::printEnabledExtensions(MachineTriple.isArch64Bit(), 208 EnabledFeatureNames, DescMap); 209 } else { 210 // The option was already checked in Driver::HandleImmediateArgs, 211 // so we do not expect to get here if we are not a supported architecture. 212 assert(0 && "Unhandled triple for --print-enabled-extensions option."); 213 return 1; 214 } 215 216 return 0; 217 } 218 219 int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) { 220 ensureSufficientStack(); 221 222 IntrusiveRefCntPtr<DiagnosticIDs> DiagID = DiagnosticIDs::create(); 223 224 // Register the support for object-file-wrapped Clang modules. 225 auto PCHOps = std::make_shared<PCHContainerOperations>(); 226 PCHOps->registerWriter(std::make_unique<ObjectFilePCHContainerWriter>()); 227 PCHOps->registerReader(std::make_unique<ObjectFilePCHContainerReader>()); 228 229 // Initialize targets first, so that --version shows registered targets. 230 llvm::InitializeAllTargets(); 231 llvm::InitializeAllTargetMCs(); 232 llvm::InitializeAllAsmPrinters(); 233 llvm::InitializeAllAsmParsers(); 234 235 // Buffer diagnostics from argument parsing so that we can output them using a 236 // well formed diagnostic object. 237 DiagnosticOptions DiagOpts; 238 TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer; 239 DiagnosticsEngine Diags(DiagID, DiagOpts, DiagsBuffer); 240 241 // Setup round-trip remarks for the DiagnosticsEngine used in CreateFromArgs. 242 if (find(Argv, StringRef("-Rround-trip-cc1-args")) != Argv.end()) 243 Diags.setSeverity(diag::remark_cc1_round_trip_generated, 244 diag::Severity::Remark, {}); 245 246 auto Invocation = std::make_shared<CompilerInvocation>(); 247 bool Success = 248 CompilerInvocation::CreateFromArgs(*Invocation, Argv, Diags, Argv0); 249 250 auto Clang = std::make_unique<CompilerInstance>(std::move(Invocation), 251 std::move(PCHOps)); 252 253 if (!Clang->getFrontendOpts().TimeTracePath.empty()) { 254 llvm::timeTraceProfilerInitialize( 255 Clang->getFrontendOpts().TimeTraceGranularity, Argv0, 256 Clang->getFrontendOpts().TimeTraceVerbose); 257 } 258 // --print-supported-cpus takes priority over the actual compilation. 259 if (Clang->getFrontendOpts().PrintSupportedCPUs) 260 return PrintSupportedCPUs(Clang->getTargetOpts().Triple); 261 262 // --print-supported-extensions takes priority over the actual compilation. 263 if (Clang->getFrontendOpts().PrintSupportedExtensions) 264 return PrintSupportedExtensions(Clang->getTargetOpts().Triple); 265 266 // --print-enabled-extensions takes priority over the actual compilation. 267 if (Clang->getFrontendOpts().PrintEnabledExtensions) 268 return PrintEnabledExtensions(Clang->getTargetOpts()); 269 270 // Infer the builtin include path if unspecified. 271 if (Clang->getHeaderSearchOpts().UseBuiltinIncludes && 272 Clang->getHeaderSearchOpts().ResourceDir.empty()) 273 Clang->getHeaderSearchOpts().ResourceDir = 274 GetResourcesPath(Argv0, MainAddr); 275 276 /// Create the actual file system. 277 auto VFS = [] { 278 auto BypassSandbox = llvm::sys::sandbox::scopedDisable(); 279 return llvm::vfs::getRealFileSystem(); 280 }(); 281 Clang->createVirtualFileSystem(std::move(VFS), DiagsBuffer); 282 283 // Create the actual diagnostics engine. 284 Clang->createDiagnostics(); 285 286 // Set an error handler, so that any LLVM backend diagnostics go through our 287 // error handler. 288 llvm::install_fatal_error_handler(LLVMErrorHandler, 289 static_cast<void*>(&Clang->getDiagnostics())); 290 291 DiagsBuffer->FlushDiagnostics(Clang->getDiagnostics()); 292 if (!Success) { 293 Clang->getDiagnosticClient().finish(); 294 return 1; 295 } 296 297 // Execute the frontend actions. 298 { 299 llvm::TimeTraceScope TimeScope("ExecuteCompiler"); 300 bool TimePasses = Clang->getCodeGenOpts().TimePasses; 301 if (TimePasses) 302 Clang->createFrontendTimer(); 303 llvm::TimeRegion Timer(TimePasses ? &Clang->getFrontendTimer() : nullptr); 304 Success = ExecuteCompilerInvocation(Clang.get()); 305 } 306 307 // If any timers were active but haven't been destroyed yet, print their 308 // results now. This happens in -disable-free mode. 309 { 310 // This isn't a formal input or output of the compiler. 311 auto BypassSandbox = llvm::sys::sandbox::scopedDisable(); 312 std::unique_ptr<raw_ostream> IOFile = llvm::CreateInfoOutputFile(); 313 if (Clang->getCodeGenOpts().TimePassesJson) { 314 *IOFile << "{\n"; 315 llvm::TimerGroup::printAllJSONValues(*IOFile, ""); 316 *IOFile << "\n}\n"; 317 } else if (!Clang->getCodeGenOpts().TimePassesStatsFile) { 318 llvm::TimerGroup::printAll(*IOFile); 319 } 320 llvm::TimerGroup::clearAll(); 321 } 322 323 if (llvm::timeTraceProfilerEnabled()) { 324 if (auto profilerOutput = Clang->createOutputFile( 325 Clang->getFrontendOpts().TimeTracePath, /*Binary=*/false, 326 /*RemoveFileOnSignal=*/false, 327 /*useTemporary=*/false)) { 328 llvm::timeTraceProfilerWrite(*profilerOutput); 329 profilerOutput.reset(); 330 llvm::timeTraceProfilerCleanup(); 331 Clang->clearOutputFiles(false); 332 } 333 } 334 335 // Our error handler depends on the Diagnostics object, which we're 336 // potentially about to delete. Uninstall the handler now so that any 337 // later errors use the default handling behavior instead. 338 llvm::remove_fatal_error_handler(); 339 340 // When running with -disable-free, don't do any destruction or shutdown. 341 if (Clang->getFrontendOpts().DisableFree) { 342 llvm::BuryPointer(std::move(Clang)); 343 return !Success; 344 } 345 346 return !Success; 347 } 348