10b57cec5SDimitry Andric //===--- CodeGenAction.cpp - LLVM Code Generation Frontend Action ---------===// 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 #include "clang/CodeGen/CodeGenAction.h" 105f757f3fSDimitry Andric #include "BackendConsumer.h" 1106c3fb27SDimitry Andric #include "CGCall.h" 120b57cec5SDimitry Andric #include "CodeGenModule.h" 130b57cec5SDimitry Andric #include "CoverageMappingGen.h" 140b57cec5SDimitry Andric #include "MacroPPCallbacks.h" 150b57cec5SDimitry Andric #include "clang/AST/ASTConsumer.h" 160b57cec5SDimitry Andric #include "clang/AST/ASTContext.h" 170b57cec5SDimitry Andric #include "clang/AST/DeclCXX.h" 180b57cec5SDimitry Andric #include "clang/AST/DeclGroup.h" 19a7dea167SDimitry Andric #include "clang/Basic/DiagnosticFrontend.h" 200b57cec5SDimitry Andric #include "clang/Basic/FileManager.h" 21a7dea167SDimitry Andric #include "clang/Basic/LangStandard.h" 220b57cec5SDimitry Andric #include "clang/Basic/SourceManager.h" 230b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h" 240b57cec5SDimitry Andric #include "clang/CodeGen/BackendUtil.h" 250b57cec5SDimitry Andric #include "clang/CodeGen/ModuleBuilder.h" 260b57cec5SDimitry Andric #include "clang/Driver/DriverDiagnostic.h" 270b57cec5SDimitry Andric #include "clang/Frontend/CompilerInstance.h" 28*0fca6ea1SDimitry Andric #include "clang/Frontend/FrontendActions.h" 290b57cec5SDimitry Andric #include "clang/Frontend/FrontendDiagnostic.h" 30*0fca6ea1SDimitry Andric #include "clang/Frontend/MultiplexConsumer.h" 310b57cec5SDimitry Andric #include "clang/Lex/Preprocessor.h" 32*0fca6ea1SDimitry Andric #include "clang/Serialization/ASTWriter.h" 33349cc55cSDimitry Andric #include "llvm/ADT/Hashing.h" 340b57cec5SDimitry Andric #include "llvm/Bitcode/BitcodeReader.h" 350b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h" 36349cc55cSDimitry Andric #include "llvm/Demangle/Demangle.h" 370b57cec5SDimitry Andric #include "llvm/IR/DebugInfo.h" 380b57cec5SDimitry Andric #include "llvm/IR/DiagnosticInfo.h" 390b57cec5SDimitry Andric #include "llvm/IR/DiagnosticPrinter.h" 400b57cec5SDimitry Andric #include "llvm/IR/GlobalValue.h" 410b57cec5SDimitry Andric #include "llvm/IR/LLVMContext.h" 425ffd83dbSDimitry Andric #include "llvm/IR/LLVMRemarkStreamer.h" 430b57cec5SDimitry Andric #include "llvm/IR/Module.h" 440b57cec5SDimitry Andric #include "llvm/IRReader/IRReader.h" 45e8d8bef9SDimitry Andric #include "llvm/LTO/LTOBackend.h" 460b57cec5SDimitry Andric #include "llvm/Linker/Linker.h" 470b57cec5SDimitry Andric #include "llvm/Pass.h" 480b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 490b57cec5SDimitry Andric #include "llvm/Support/SourceMgr.h" 50a7dea167SDimitry Andric #include "llvm/Support/TimeProfiler.h" 510b57cec5SDimitry Andric #include "llvm/Support/Timer.h" 520b57cec5SDimitry Andric #include "llvm/Support/ToolOutputFile.h" 530b57cec5SDimitry Andric #include "llvm/Support/YAMLTraits.h" 540b57cec5SDimitry Andric #include "llvm/Transforms/IPO/Internalize.h" 555f757f3fSDimitry Andric #include "llvm/Transforms/Utils/Cloning.h" 560b57cec5SDimitry Andric 57bdd1243dSDimitry Andric #include <optional> 580b57cec5SDimitry Andric using namespace clang; 590b57cec5SDimitry Andric using namespace llvm; 600b57cec5SDimitry Andric 61349cc55cSDimitry Andric #define DEBUG_TYPE "codegenaction" 62349cc55cSDimitry Andric 630b57cec5SDimitry Andric namespace clang { 640b57cec5SDimitry Andric class BackendConsumer; 650b57cec5SDimitry Andric class ClangDiagnosticHandler final : public DiagnosticHandler { 660b57cec5SDimitry Andric public: 670b57cec5SDimitry Andric ClangDiagnosticHandler(const CodeGenOptions &CGOpts, BackendConsumer *BCon) 680b57cec5SDimitry Andric : CodeGenOpts(CGOpts), BackendCon(BCon) {} 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric bool handleDiagnostics(const DiagnosticInfo &DI) override; 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric bool isAnalysisRemarkEnabled(StringRef PassName) const override { 73fe6060f1SDimitry Andric return CodeGenOpts.OptimizationRemarkAnalysis.patternMatches(PassName); 740b57cec5SDimitry Andric } 750b57cec5SDimitry Andric bool isMissedOptRemarkEnabled(StringRef PassName) const override { 76fe6060f1SDimitry Andric return CodeGenOpts.OptimizationRemarkMissed.patternMatches(PassName); 770b57cec5SDimitry Andric } 780b57cec5SDimitry Andric bool isPassedOptRemarkEnabled(StringRef PassName) const override { 79fe6060f1SDimitry Andric return CodeGenOpts.OptimizationRemark.patternMatches(PassName); 800b57cec5SDimitry Andric } 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric bool isAnyRemarkEnabled() const override { 83fe6060f1SDimitry Andric return CodeGenOpts.OptimizationRemarkAnalysis.hasValidPattern() || 84fe6060f1SDimitry Andric CodeGenOpts.OptimizationRemarkMissed.hasValidPattern() || 85fe6060f1SDimitry Andric CodeGenOpts.OptimizationRemark.hasValidPattern(); 860b57cec5SDimitry Andric } 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric private: 890b57cec5SDimitry Andric const CodeGenOptions &CodeGenOpts; 900b57cec5SDimitry Andric BackendConsumer *BackendCon; 910b57cec5SDimitry Andric }; 920b57cec5SDimitry Andric 93480093f4SDimitry Andric static void reportOptRecordError(Error E, DiagnosticsEngine &Diags, 9406c3fb27SDimitry Andric const CodeGenOptions &CodeGenOpts) { 95480093f4SDimitry Andric handleAllErrors( 96480093f4SDimitry Andric std::move(E), 975ffd83dbSDimitry Andric [&](const LLVMRemarkSetupFileError &E) { 98480093f4SDimitry Andric Diags.Report(diag::err_cannot_open_file) 99480093f4SDimitry Andric << CodeGenOpts.OptRecordFile << E.message(); 100480093f4SDimitry Andric }, 1015ffd83dbSDimitry Andric [&](const LLVMRemarkSetupPatternError &E) { 102480093f4SDimitry Andric Diags.Report(diag::err_drv_optimization_remark_pattern) 103480093f4SDimitry Andric << E.message() << CodeGenOpts.OptRecordPasses; 104480093f4SDimitry Andric }, 1055ffd83dbSDimitry Andric [&](const LLVMRemarkSetupFormatError &E) { 106480093f4SDimitry Andric Diags.Report(diag::err_drv_optimization_remark_format) 107480093f4SDimitry Andric << CodeGenOpts.OptRecordFormat; 108480093f4SDimitry Andric }); 109480093f4SDimitry Andric } 110480093f4SDimitry Andric 111*0fca6ea1SDimitry Andric BackendConsumer::BackendConsumer( 112*0fca6ea1SDimitry Andric BackendAction Action, DiagnosticsEngine &Diags, 11306c3fb27SDimitry Andric IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, 1140b57cec5SDimitry Andric const HeaderSearchOptions &HeaderSearchOpts, 115*0fca6ea1SDimitry Andric const PreprocessorOptions &PPOpts, const CodeGenOptions &CodeGenOpts, 116*0fca6ea1SDimitry Andric const TargetOptions &TargetOpts, const LangOptions &LangOpts, 117*0fca6ea1SDimitry Andric const std::string &InFile, SmallVector<LinkModule, 4> LinkModules, 118*0fca6ea1SDimitry Andric std::unique_ptr<raw_pwrite_stream> OS, LLVMContext &C, 1195f757f3fSDimitry Andric CoverageSourceInfo *CoverageInfo) 1200b57cec5SDimitry Andric : Diags(Diags), Action(Action), HeaderSearchOpts(HeaderSearchOpts), 1210b57cec5SDimitry Andric CodeGenOpts(CodeGenOpts), TargetOpts(TargetOpts), LangOpts(LangOpts), 12206c3fb27SDimitry Andric AsmOutStream(std::move(OS)), Context(nullptr), FS(VFS), 1230b57cec5SDimitry Andric LLVMIRGeneration("irgen", "LLVM IR Generation Time"), 1240b57cec5SDimitry Andric LLVMIRGenerationRefCount(0), 12506c3fb27SDimitry Andric Gen(CreateLLVMCodeGen(Diags, InFile, std::move(VFS), HeaderSearchOpts, 126972a253aSDimitry Andric PPOpts, CodeGenOpts, C, CoverageInfo)), 1270b57cec5SDimitry Andric LinkModules(std::move(LinkModules)) { 128e8d8bef9SDimitry Andric TimerIsEnabled = CodeGenOpts.TimePasses; 129e8d8bef9SDimitry Andric llvm::TimePassesIsEnabled = CodeGenOpts.TimePasses; 130e8d8bef9SDimitry Andric llvm::TimePassesPerRun = CodeGenOpts.TimePassesPerRun; 1310b57cec5SDimitry Andric } 132480093f4SDimitry Andric 133480093f4SDimitry Andric // This constructor is used in installing an empty BackendConsumer 134480093f4SDimitry Andric // to use the clang diagnostic handler for IR input files. It avoids 135480093f4SDimitry Andric // initializing the OS field. 136*0fca6ea1SDimitry Andric BackendConsumer::BackendConsumer( 137*0fca6ea1SDimitry Andric BackendAction Action, DiagnosticsEngine &Diags, 13806c3fb27SDimitry Andric IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, 139480093f4SDimitry Andric const HeaderSearchOptions &HeaderSearchOpts, 140*0fca6ea1SDimitry Andric const PreprocessorOptions &PPOpts, const CodeGenOptions &CodeGenOpts, 141*0fca6ea1SDimitry Andric const TargetOptions &TargetOpts, const LangOptions &LangOpts, 142*0fca6ea1SDimitry Andric llvm::Module *Module, SmallVector<LinkModule, 4> LinkModules, 143*0fca6ea1SDimitry Andric LLVMContext &C, CoverageSourceInfo *CoverageInfo) 144480093f4SDimitry Andric : Diags(Diags), Action(Action), HeaderSearchOpts(HeaderSearchOpts), 145480093f4SDimitry Andric CodeGenOpts(CodeGenOpts), TargetOpts(TargetOpts), LangOpts(LangOpts), 14606c3fb27SDimitry Andric Context(nullptr), FS(VFS), 147480093f4SDimitry Andric LLVMIRGeneration("irgen", "LLVM IR Generation Time"), 148480093f4SDimitry Andric LLVMIRGenerationRefCount(0), 149*0fca6ea1SDimitry Andric Gen(CreateLLVMCodeGen(Diags, "", std::move(VFS), HeaderSearchOpts, PPOpts, 150*0fca6ea1SDimitry Andric CodeGenOpts, C, CoverageInfo)), 151349cc55cSDimitry Andric LinkModules(std::move(LinkModules)), CurLinkModule(Module) { 152e8d8bef9SDimitry Andric TimerIsEnabled = CodeGenOpts.TimePasses; 153e8d8bef9SDimitry Andric llvm::TimePassesIsEnabled = CodeGenOpts.TimePasses; 154e8d8bef9SDimitry Andric llvm::TimePassesPerRun = CodeGenOpts.TimePassesPerRun; 155480093f4SDimitry Andric } 1565f757f3fSDimitry Andric 1575f757f3fSDimitry Andric llvm::Module* BackendConsumer::getModule() const { 1585f757f3fSDimitry Andric return Gen->GetModule(); 1595f757f3fSDimitry Andric } 1605f757f3fSDimitry Andric 1615f757f3fSDimitry Andric std::unique_ptr<llvm::Module> BackendConsumer::takeModule() { 1620b57cec5SDimitry Andric return std::unique_ptr<llvm::Module>(Gen->ReleaseModule()); 1630b57cec5SDimitry Andric } 1640b57cec5SDimitry Andric 1655f757f3fSDimitry Andric CodeGenerator* BackendConsumer::getCodeGenerator() { 1665f757f3fSDimitry Andric return Gen.get(); 1675f757f3fSDimitry Andric } 1680b57cec5SDimitry Andric 1695f757f3fSDimitry Andric void BackendConsumer::HandleCXXStaticMemberVarInstantiation(VarDecl *VD) { 1700b57cec5SDimitry Andric Gen->HandleCXXStaticMemberVarInstantiation(VD); 1710b57cec5SDimitry Andric } 1720b57cec5SDimitry Andric 1735f757f3fSDimitry Andric void BackendConsumer::Initialize(ASTContext &Ctx) { 1740b57cec5SDimitry Andric assert(!Context && "initialized multiple times"); 1750b57cec5SDimitry Andric 1760b57cec5SDimitry Andric Context = &Ctx; 1770b57cec5SDimitry Andric 178e8d8bef9SDimitry Andric if (TimerIsEnabled) 1790b57cec5SDimitry Andric LLVMIRGeneration.startTimer(); 1800b57cec5SDimitry Andric 1810b57cec5SDimitry Andric Gen->Initialize(Ctx); 1820b57cec5SDimitry Andric 183e8d8bef9SDimitry Andric if (TimerIsEnabled) 1840b57cec5SDimitry Andric LLVMIRGeneration.stopTimer(); 1850b57cec5SDimitry Andric } 1860b57cec5SDimitry Andric 1875f757f3fSDimitry Andric bool BackendConsumer::HandleTopLevelDecl(DeclGroupRef D) { 1880b57cec5SDimitry Andric PrettyStackTraceDecl CrashInfo(*D.begin(), SourceLocation(), 1890b57cec5SDimitry Andric Context->getSourceManager(), 1900b57cec5SDimitry Andric "LLVM IR generation of declaration"); 1910b57cec5SDimitry Andric 1920b57cec5SDimitry Andric // Recurse. 193e8d8bef9SDimitry Andric if (TimerIsEnabled) { 1940b57cec5SDimitry Andric LLVMIRGenerationRefCount += 1; 1950b57cec5SDimitry Andric if (LLVMIRGenerationRefCount == 1) 1960b57cec5SDimitry Andric LLVMIRGeneration.startTimer(); 1970b57cec5SDimitry Andric } 1980b57cec5SDimitry Andric 1990b57cec5SDimitry Andric Gen->HandleTopLevelDecl(D); 2000b57cec5SDimitry Andric 201e8d8bef9SDimitry Andric if (TimerIsEnabled) { 2020b57cec5SDimitry Andric LLVMIRGenerationRefCount -= 1; 2030b57cec5SDimitry Andric if (LLVMIRGenerationRefCount == 0) 2040b57cec5SDimitry Andric LLVMIRGeneration.stopTimer(); 2050b57cec5SDimitry Andric } 2060b57cec5SDimitry Andric 2070b57cec5SDimitry Andric return true; 2080b57cec5SDimitry Andric } 2090b57cec5SDimitry Andric 2105f757f3fSDimitry Andric void BackendConsumer::HandleInlineFunctionDefinition(FunctionDecl *D) { 2110b57cec5SDimitry Andric PrettyStackTraceDecl CrashInfo(D, SourceLocation(), 2120b57cec5SDimitry Andric Context->getSourceManager(), 2130b57cec5SDimitry Andric "LLVM IR generation of inline function"); 214e8d8bef9SDimitry Andric if (TimerIsEnabled) 2150b57cec5SDimitry Andric LLVMIRGeneration.startTimer(); 2160b57cec5SDimitry Andric 2170b57cec5SDimitry Andric Gen->HandleInlineFunctionDefinition(D); 2180b57cec5SDimitry Andric 219e8d8bef9SDimitry Andric if (TimerIsEnabled) 2200b57cec5SDimitry Andric LLVMIRGeneration.stopTimer(); 2210b57cec5SDimitry Andric } 2220b57cec5SDimitry Andric 2235f757f3fSDimitry Andric void BackendConsumer::HandleInterestingDecl(DeclGroupRef D) { 2240b57cec5SDimitry Andric // Ignore interesting decls from the AST reader after IRGen is finished. 2250b57cec5SDimitry Andric if (!IRGenFinished) 2260b57cec5SDimitry Andric HandleTopLevelDecl(D); 2270b57cec5SDimitry Andric } 2280b57cec5SDimitry Andric 2290b57cec5SDimitry Andric // Links each entry in LinkModules into our module. Returns true on error. 230*0fca6ea1SDimitry Andric bool BackendConsumer::LinkInModules(llvm::Module *M) { 2310b57cec5SDimitry Andric for (auto &LM : LinkModules) { 23206c3fb27SDimitry Andric assert(LM.Module && "LinkModule does not actually have a module"); 2335f757f3fSDimitry Andric 2340b57cec5SDimitry Andric if (LM.PropagateAttrs) 235e8d8bef9SDimitry Andric for (Function &F : *LM.Module) { 236e8d8bef9SDimitry Andric // Skip intrinsics. Keep consistent with how intrinsics are created 237e8d8bef9SDimitry Andric // in LLVM IR. 238e8d8bef9SDimitry Andric if (F.isIntrinsic()) 239e8d8bef9SDimitry Andric continue; 24006c3fb27SDimitry Andric CodeGen::mergeDefaultFunctionDefinitionAttributes( 24106c3fb27SDimitry Andric F, CodeGenOpts, LangOpts, TargetOpts, LM.Internalize); 242e8d8bef9SDimitry Andric } 2430b57cec5SDimitry Andric 2440b57cec5SDimitry Andric CurLinkModule = LM.Module.get(); 2450b57cec5SDimitry Andric bool Err; 2465f757f3fSDimitry Andric 2470b57cec5SDimitry Andric if (LM.Internalize) { 2480b57cec5SDimitry Andric Err = Linker::linkModules( 249*0fca6ea1SDimitry Andric *M, std::move(LM.Module), LM.LinkFlags, 2500b57cec5SDimitry Andric [](llvm::Module &M, const llvm::StringSet<> &GVS) { 2510b57cec5SDimitry Andric internalizeModule(M, [&GVS](const llvm::GlobalValue &GV) { 2520b57cec5SDimitry Andric return !GV.hasName() || (GVS.count(GV.getName()) == 0); 2530b57cec5SDimitry Andric }); 2540b57cec5SDimitry Andric }); 2555f757f3fSDimitry Andric } else 256*0fca6ea1SDimitry Andric Err = Linker::linkModules(*M, std::move(LM.Module), LM.LinkFlags); 2575f757f3fSDimitry Andric 258*0fca6ea1SDimitry Andric if (Err) 259*0fca6ea1SDimitry Andric return true; 2600b57cec5SDimitry Andric } 2610b57cec5SDimitry Andric 262*0fca6ea1SDimitry Andric LinkModules.clear(); 2630b57cec5SDimitry Andric return false; // success 2640b57cec5SDimitry Andric } 2650b57cec5SDimitry Andric 2665f757f3fSDimitry Andric void BackendConsumer::HandleTranslationUnit(ASTContext &C) { 2670b57cec5SDimitry Andric { 268480093f4SDimitry Andric llvm::TimeTraceScope TimeScope("Frontend"); 2690b57cec5SDimitry Andric PrettyStackTraceString CrashInfo("Per-file LLVM IR generation"); 270e8d8bef9SDimitry Andric if (TimerIsEnabled) { 2710b57cec5SDimitry Andric LLVMIRGenerationRefCount += 1; 2720b57cec5SDimitry Andric if (LLVMIRGenerationRefCount == 1) 2730b57cec5SDimitry Andric LLVMIRGeneration.startTimer(); 2740b57cec5SDimitry Andric } 2750b57cec5SDimitry Andric 2760b57cec5SDimitry Andric Gen->HandleTranslationUnit(C); 2770b57cec5SDimitry Andric 278e8d8bef9SDimitry Andric if (TimerIsEnabled) { 2790b57cec5SDimitry Andric LLVMIRGenerationRefCount -= 1; 2800b57cec5SDimitry Andric if (LLVMIRGenerationRefCount == 0) 2810b57cec5SDimitry Andric LLVMIRGeneration.stopTimer(); 2820b57cec5SDimitry Andric } 2830b57cec5SDimitry Andric 2840b57cec5SDimitry Andric IRGenFinished = true; 2850b57cec5SDimitry Andric } 2860b57cec5SDimitry Andric 2870b57cec5SDimitry Andric // Silently ignore if we weren't initialized for some reason. 2880b57cec5SDimitry Andric if (!getModule()) 2890b57cec5SDimitry Andric return; 2900b57cec5SDimitry Andric 2910b57cec5SDimitry Andric LLVMContext &Ctx = getModule()->getContext(); 2920b57cec5SDimitry Andric std::unique_ptr<DiagnosticHandler> OldDiagnosticHandler = 2930b57cec5SDimitry Andric Ctx.getDiagnosticHandler(); 294a7dea167SDimitry Andric Ctx.setDiagnosticHandler(std::make_unique<ClangDiagnosticHandler>( 2950b57cec5SDimitry Andric CodeGenOpts, this)); 2960b57cec5SDimitry Andric 297*0fca6ea1SDimitry Andric Ctx.setDefaultTargetCPU(TargetOpts.CPU); 298*0fca6ea1SDimitry Andric Ctx.setDefaultTargetFeatures(llvm::join(TargetOpts.Features, ",")); 299*0fca6ea1SDimitry Andric 3000b57cec5SDimitry Andric Expected<std::unique_ptr<llvm::ToolOutputFile>> OptRecordFileOrErr = 3015ffd83dbSDimitry Andric setupLLVMOptimizationRemarks( 302480093f4SDimitry Andric Ctx, CodeGenOpts.OptRecordFile, CodeGenOpts.OptRecordPasses, 303480093f4SDimitry Andric CodeGenOpts.OptRecordFormat, CodeGenOpts.DiagnosticsWithHotness, 3040b57cec5SDimitry Andric CodeGenOpts.DiagnosticsHotnessThreshold); 3050b57cec5SDimitry Andric 3060b57cec5SDimitry Andric if (Error E = OptRecordFileOrErr.takeError()) { 307480093f4SDimitry Andric reportOptRecordError(std::move(E), Diags, CodeGenOpts); 3080b57cec5SDimitry Andric return; 3090b57cec5SDimitry Andric } 310480093f4SDimitry Andric 3110b57cec5SDimitry Andric std::unique_ptr<llvm::ToolOutputFile> OptRecordFile = 3120b57cec5SDimitry Andric std::move(*OptRecordFileOrErr); 3130b57cec5SDimitry Andric 3140b57cec5SDimitry Andric if (OptRecordFile && 3150b57cec5SDimitry Andric CodeGenOpts.getProfileUse() != CodeGenOptions::ProfileNone) 3160b57cec5SDimitry Andric Ctx.setDiagnosticsHotnessRequested(true); 3170b57cec5SDimitry Andric 31881ad6265SDimitry Andric if (CodeGenOpts.MisExpect) { 31981ad6265SDimitry Andric Ctx.setMisExpectWarningRequested(true); 32081ad6265SDimitry Andric } 32181ad6265SDimitry Andric 32281ad6265SDimitry Andric if (CodeGenOpts.DiagnosticsMisExpectTolerance) { 32381ad6265SDimitry Andric Ctx.setDiagnosticsMisExpectTolerance( 32481ad6265SDimitry Andric CodeGenOpts.DiagnosticsMisExpectTolerance); 32581ad6265SDimitry Andric } 32681ad6265SDimitry Andric 3270b57cec5SDimitry Andric // Link each LinkModule into our module. 328*0fca6ea1SDimitry Andric if (!CodeGenOpts.LinkBitcodePostopt && LinkInModules(getModule())) 3290b57cec5SDimitry Andric return; 3300b57cec5SDimitry Andric 331349cc55cSDimitry Andric for (auto &F : getModule()->functions()) { 332349cc55cSDimitry Andric if (const Decl *FD = Gen->GetDeclForMangledName(F.getName())) { 333349cc55cSDimitry Andric auto Loc = FD->getASTContext().getFullLoc(FD->getLocation()); 334349cc55cSDimitry Andric // TODO: use a fast content hash when available. 335349cc55cSDimitry Andric auto NameHash = llvm::hash_value(F.getName()); 336349cc55cSDimitry Andric ManglingFullSourceLocs.push_back(std::make_pair(NameHash, Loc)); 337349cc55cSDimitry Andric } 338349cc55cSDimitry Andric } 339349cc55cSDimitry Andric 340349cc55cSDimitry Andric if (CodeGenOpts.ClearASTBeforeBackend) { 341349cc55cSDimitry Andric LLVM_DEBUG(llvm::dbgs() << "Clearing AST...\n"); 342349cc55cSDimitry Andric // Access to the AST is no longer available after this. 343349cc55cSDimitry Andric // Other things that the ASTContext manages are still available, e.g. 344349cc55cSDimitry Andric // the SourceManager. It'd be nice if we could separate out all the 345349cc55cSDimitry Andric // things in ASTContext used after this point and null out the 346349cc55cSDimitry Andric // ASTContext, but too many various parts of the ASTContext are still 347349cc55cSDimitry Andric // used in various parts. 348349cc55cSDimitry Andric C.cleanup(); 349349cc55cSDimitry Andric C.getAllocator().Reset(); 350349cc55cSDimitry Andric } 351349cc55cSDimitry Andric 3520b57cec5SDimitry Andric EmbedBitcode(getModule(), CodeGenOpts, llvm::MemoryBufferRef()); 3530b57cec5SDimitry Andric 3545f757f3fSDimitry Andric EmitBackendOutput(Diags, HeaderSearchOpts, CodeGenOpts, TargetOpts, LangOpts, 3555f757f3fSDimitry Andric C.getTargetInfo().getDataLayoutString(), getModule(), 3565f757f3fSDimitry Andric Action, FS, std::move(AsmOutStream), this); 3570b57cec5SDimitry Andric 3580b57cec5SDimitry Andric Ctx.setDiagnosticHandler(std::move(OldDiagnosticHandler)); 3590b57cec5SDimitry Andric 3600b57cec5SDimitry Andric if (OptRecordFile) 3610b57cec5SDimitry Andric OptRecordFile->keep(); 3620b57cec5SDimitry Andric } 3630b57cec5SDimitry Andric 3645f757f3fSDimitry Andric void BackendConsumer::HandleTagDeclDefinition(TagDecl *D) { 3650b57cec5SDimitry Andric PrettyStackTraceDecl CrashInfo(D, SourceLocation(), 3660b57cec5SDimitry Andric Context->getSourceManager(), 3670b57cec5SDimitry Andric "LLVM IR generation of declaration"); 3680b57cec5SDimitry Andric Gen->HandleTagDeclDefinition(D); 3690b57cec5SDimitry Andric } 3700b57cec5SDimitry Andric 3715f757f3fSDimitry Andric void BackendConsumer::HandleTagDeclRequiredDefinition(const TagDecl *D) { 3720b57cec5SDimitry Andric Gen->HandleTagDeclRequiredDefinition(D); 3730b57cec5SDimitry Andric } 3740b57cec5SDimitry Andric 3755f757f3fSDimitry Andric void BackendConsumer::CompleteTentativeDefinition(VarDecl *D) { 3760b57cec5SDimitry Andric Gen->CompleteTentativeDefinition(D); 3770b57cec5SDimitry Andric } 3780b57cec5SDimitry Andric 379*0fca6ea1SDimitry Andric void BackendConsumer::CompleteExternalDeclaration(DeclaratorDecl *D) { 380480093f4SDimitry Andric Gen->CompleteExternalDeclaration(D); 381480093f4SDimitry Andric } 382480093f4SDimitry Andric 3835f757f3fSDimitry Andric void BackendConsumer::AssignInheritanceModel(CXXRecordDecl *RD) { 3840b57cec5SDimitry Andric Gen->AssignInheritanceModel(RD); 3850b57cec5SDimitry Andric } 3860b57cec5SDimitry Andric 3875f757f3fSDimitry Andric void BackendConsumer::HandleVTable(CXXRecordDecl *RD) { 3880b57cec5SDimitry Andric Gen->HandleVTable(RD); 3890b57cec5SDimitry Andric } 3900b57cec5SDimitry Andric 3910b57cec5SDimitry Andric void BackendConsumer::anchor() { } 3925f757f3fSDimitry Andric 3935f757f3fSDimitry Andric } // namespace clang 3940b57cec5SDimitry Andric 3950b57cec5SDimitry Andric bool ClangDiagnosticHandler::handleDiagnostics(const DiagnosticInfo &DI) { 3960b57cec5SDimitry Andric BackendCon->DiagnosticHandlerImpl(DI); 3970b57cec5SDimitry Andric return true; 3980b57cec5SDimitry Andric } 3990b57cec5SDimitry Andric 4000b57cec5SDimitry Andric /// ConvertBackendLocation - Convert a location in a temporary llvm::SourceMgr 4010b57cec5SDimitry Andric /// buffer to be a valid FullSourceLoc. 4020b57cec5SDimitry Andric static FullSourceLoc ConvertBackendLocation(const llvm::SMDiagnostic &D, 4030b57cec5SDimitry Andric SourceManager &CSM) { 4040b57cec5SDimitry Andric // Get both the clang and llvm source managers. The location is relative to 4050b57cec5SDimitry Andric // a memory buffer that the LLVM Source Manager is handling, we need to add 4060b57cec5SDimitry Andric // a copy to the Clang source manager. 4070b57cec5SDimitry Andric const llvm::SourceMgr &LSM = *D.getSourceMgr(); 4080b57cec5SDimitry Andric 4090b57cec5SDimitry Andric // We need to copy the underlying LLVM memory buffer because llvm::SourceMgr 4100b57cec5SDimitry Andric // already owns its one and clang::SourceManager wants to own its one. 4110b57cec5SDimitry Andric const MemoryBuffer *LBuf = 4120b57cec5SDimitry Andric LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc())); 4130b57cec5SDimitry Andric 4140b57cec5SDimitry Andric // Create the copy and transfer ownership to clang::SourceManager. 4150b57cec5SDimitry Andric // TODO: Avoid copying files into memory. 4160b57cec5SDimitry Andric std::unique_ptr<llvm::MemoryBuffer> CBuf = 4170b57cec5SDimitry Andric llvm::MemoryBuffer::getMemBufferCopy(LBuf->getBuffer(), 4180b57cec5SDimitry Andric LBuf->getBufferIdentifier()); 4190b57cec5SDimitry Andric // FIXME: Keep a file ID map instead of creating new IDs for each location. 4200b57cec5SDimitry Andric FileID FID = CSM.createFileID(std::move(CBuf)); 4210b57cec5SDimitry Andric 4220b57cec5SDimitry Andric // Translate the offset into the file. 4230b57cec5SDimitry Andric unsigned Offset = D.getLoc().getPointer() - LBuf->getBufferStart(); 4240b57cec5SDimitry Andric SourceLocation NewLoc = 4250b57cec5SDimitry Andric CSM.getLocForStartOfFile(FID).getLocWithOffset(Offset); 4260b57cec5SDimitry Andric return FullSourceLoc(NewLoc, CSM); 4270b57cec5SDimitry Andric } 4280b57cec5SDimitry Andric 4290b57cec5SDimitry Andric #define ComputeDiagID(Severity, GroupName, DiagID) \ 4300b57cec5SDimitry Andric do { \ 4310b57cec5SDimitry Andric switch (Severity) { \ 4320b57cec5SDimitry Andric case llvm::DS_Error: \ 4330b57cec5SDimitry Andric DiagID = diag::err_fe_##GroupName; \ 4340b57cec5SDimitry Andric break; \ 4350b57cec5SDimitry Andric case llvm::DS_Warning: \ 4360b57cec5SDimitry Andric DiagID = diag::warn_fe_##GroupName; \ 4370b57cec5SDimitry Andric break; \ 4380b57cec5SDimitry Andric case llvm::DS_Remark: \ 4390b57cec5SDimitry Andric llvm_unreachable("'remark' severity not expected"); \ 4400b57cec5SDimitry Andric break; \ 4410b57cec5SDimitry Andric case llvm::DS_Note: \ 4420b57cec5SDimitry Andric DiagID = diag::note_fe_##GroupName; \ 4430b57cec5SDimitry Andric break; \ 4440b57cec5SDimitry Andric } \ 4450b57cec5SDimitry Andric } while (false) 4460b57cec5SDimitry Andric 4470b57cec5SDimitry Andric #define ComputeDiagRemarkID(Severity, GroupName, DiagID) \ 4480b57cec5SDimitry Andric do { \ 4490b57cec5SDimitry Andric switch (Severity) { \ 4500b57cec5SDimitry Andric case llvm::DS_Error: \ 4510b57cec5SDimitry Andric DiagID = diag::err_fe_##GroupName; \ 4520b57cec5SDimitry Andric break; \ 4530b57cec5SDimitry Andric case llvm::DS_Warning: \ 4540b57cec5SDimitry Andric DiagID = diag::warn_fe_##GroupName; \ 4550b57cec5SDimitry Andric break; \ 4560b57cec5SDimitry Andric case llvm::DS_Remark: \ 4570b57cec5SDimitry Andric DiagID = diag::remark_fe_##GroupName; \ 4580b57cec5SDimitry Andric break; \ 4590b57cec5SDimitry Andric case llvm::DS_Note: \ 4600b57cec5SDimitry Andric DiagID = diag::note_fe_##GroupName; \ 4610b57cec5SDimitry Andric break; \ 4620b57cec5SDimitry Andric } \ 4630b57cec5SDimitry Andric } while (false) 4640b57cec5SDimitry Andric 465fe6060f1SDimitry Andric void BackendConsumer::SrcMgrDiagHandler(const llvm::DiagnosticInfoSrcMgr &DI) { 466fe6060f1SDimitry Andric const llvm::SMDiagnostic &D = DI.getSMDiag(); 467fe6060f1SDimitry Andric 468fe6060f1SDimitry Andric unsigned DiagID; 469fe6060f1SDimitry Andric if (DI.isInlineAsmDiag()) 470fe6060f1SDimitry Andric ComputeDiagID(DI.getSeverity(), inline_asm, DiagID); 471fe6060f1SDimitry Andric else 472fe6060f1SDimitry Andric ComputeDiagID(DI.getSeverity(), source_mgr, DiagID); 473fe6060f1SDimitry Andric 474fe6060f1SDimitry Andric // This is for the empty BackendConsumer that uses the clang diagnostic 475fe6060f1SDimitry Andric // handler for IR input files. 476fe6060f1SDimitry Andric if (!Context) { 477fe6060f1SDimitry Andric D.print(nullptr, llvm::errs()); 478fe6060f1SDimitry Andric Diags.Report(DiagID).AddString("cannot compile inline asm"); 479fe6060f1SDimitry Andric return; 480fe6060f1SDimitry Andric } 481fe6060f1SDimitry Andric 482fe6060f1SDimitry Andric // There are a couple of different kinds of errors we could get here. 483fe6060f1SDimitry Andric // First, we re-format the SMDiagnostic in terms of a clang diagnostic. 484fe6060f1SDimitry Andric 485fe6060f1SDimitry Andric // Strip "error: " off the start of the message string. 486fe6060f1SDimitry Andric StringRef Message = D.getMessage(); 487fe6060f1SDimitry Andric (void)Message.consume_front("error: "); 488fe6060f1SDimitry Andric 489fe6060f1SDimitry Andric // If the SMDiagnostic has an inline asm source location, translate it. 490fe6060f1SDimitry Andric FullSourceLoc Loc; 491fe6060f1SDimitry Andric if (D.getLoc() != SMLoc()) 492fe6060f1SDimitry Andric Loc = ConvertBackendLocation(D, Context->getSourceManager()); 493fe6060f1SDimitry Andric 494fe6060f1SDimitry Andric // If this problem has clang-level source location information, report the 495fe6060f1SDimitry Andric // issue in the source with a note showing the instantiated 496fe6060f1SDimitry Andric // code. 497fe6060f1SDimitry Andric if (DI.isInlineAsmDiag()) { 498fe6060f1SDimitry Andric SourceLocation LocCookie = 499fe6060f1SDimitry Andric SourceLocation::getFromRawEncoding(DI.getLocCookie()); 500fe6060f1SDimitry Andric if (LocCookie.isValid()) { 501fe6060f1SDimitry Andric Diags.Report(LocCookie, DiagID).AddString(Message); 502fe6060f1SDimitry Andric 503fe6060f1SDimitry Andric if (D.getLoc().isValid()) { 504fe6060f1SDimitry Andric DiagnosticBuilder B = Diags.Report(Loc, diag::note_fe_inline_asm_here); 505fe6060f1SDimitry Andric // Convert the SMDiagnostic ranges into SourceRange and attach them 506fe6060f1SDimitry Andric // to the diagnostic. 507fe6060f1SDimitry Andric for (const std::pair<unsigned, unsigned> &Range : D.getRanges()) { 508fe6060f1SDimitry Andric unsigned Column = D.getColumnNo(); 509fe6060f1SDimitry Andric B << SourceRange(Loc.getLocWithOffset(Range.first - Column), 510fe6060f1SDimitry Andric Loc.getLocWithOffset(Range.second - Column)); 511fe6060f1SDimitry Andric } 512fe6060f1SDimitry Andric } 513fe6060f1SDimitry Andric return; 514fe6060f1SDimitry Andric } 515fe6060f1SDimitry Andric } 516fe6060f1SDimitry Andric 517fe6060f1SDimitry Andric // Otherwise, report the backend issue as occurring in the generated .s file. 518fe6060f1SDimitry Andric // If Loc is invalid, we still need to report the issue, it just gets no 519fe6060f1SDimitry Andric // location info. 520fe6060f1SDimitry Andric Diags.Report(Loc, DiagID).AddString(Message); 521fe6060f1SDimitry Andric } 522fe6060f1SDimitry Andric 5230b57cec5SDimitry Andric bool 5240b57cec5SDimitry Andric BackendConsumer::InlineAsmDiagHandler(const llvm::DiagnosticInfoInlineAsm &D) { 5250b57cec5SDimitry Andric unsigned DiagID; 5260b57cec5SDimitry Andric ComputeDiagID(D.getSeverity(), inline_asm, DiagID); 5270b57cec5SDimitry Andric std::string Message = D.getMsgStr().str(); 5280b57cec5SDimitry Andric 5290b57cec5SDimitry Andric // If this problem has clang-level source location information, report the 5300b57cec5SDimitry Andric // issue as being a problem in the source with a note showing the instantiated 5310b57cec5SDimitry Andric // code. 5320b57cec5SDimitry Andric SourceLocation LocCookie = 5330b57cec5SDimitry Andric SourceLocation::getFromRawEncoding(D.getLocCookie()); 5340b57cec5SDimitry Andric if (LocCookie.isValid()) 5350b57cec5SDimitry Andric Diags.Report(LocCookie, DiagID).AddString(Message); 5360b57cec5SDimitry Andric else { 5370b57cec5SDimitry Andric // Otherwise, report the backend diagnostic as occurring in the generated 5380b57cec5SDimitry Andric // .s file. 5390b57cec5SDimitry Andric // If Loc is invalid, we still need to report the diagnostic, it just gets 5400b57cec5SDimitry Andric // no location info. 5410b57cec5SDimitry Andric FullSourceLoc Loc; 5420b57cec5SDimitry Andric Diags.Report(Loc, DiagID).AddString(Message); 5430b57cec5SDimitry Andric } 5440b57cec5SDimitry Andric // We handled all the possible severities. 5450b57cec5SDimitry Andric return true; 5460b57cec5SDimitry Andric } 5470b57cec5SDimitry Andric 5480b57cec5SDimitry Andric bool 5490b57cec5SDimitry Andric BackendConsumer::StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D) { 5500b57cec5SDimitry Andric if (D.getSeverity() != llvm::DS_Warning) 5510b57cec5SDimitry Andric // For now, the only support we have for StackSize diagnostic is warning. 5520b57cec5SDimitry Andric // We do not know how to format other severities. 5530b57cec5SDimitry Andric return false; 5540b57cec5SDimitry Andric 555349cc55cSDimitry Andric auto Loc = getFunctionSourceLocation(D.getFunction()); 556349cc55cSDimitry Andric if (!Loc) 557349cc55cSDimitry Andric return false; 558349cc55cSDimitry Andric 559349cc55cSDimitry Andric Diags.Report(*Loc, diag::warn_fe_frame_larger_than) 56006c3fb27SDimitry Andric << D.getStackSize() << D.getStackLimit() 56106c3fb27SDimitry Andric << llvm::demangle(D.getFunction().getName()); 562bdd1243dSDimitry Andric return true; 563bdd1243dSDimitry Andric } 564bdd1243dSDimitry Andric 565bdd1243dSDimitry Andric bool BackendConsumer::ResourceLimitDiagHandler( 566bdd1243dSDimitry Andric const llvm::DiagnosticInfoResourceLimit &D) { 567bdd1243dSDimitry Andric auto Loc = getFunctionSourceLocation(D.getFunction()); 568bdd1243dSDimitry Andric if (!Loc) 569bdd1243dSDimitry Andric return false; 570bdd1243dSDimitry Andric unsigned DiagID = diag::err_fe_backend_resource_limit; 571bdd1243dSDimitry Andric ComputeDiagID(D.getSeverity(), backend_resource_limit, DiagID); 572bdd1243dSDimitry Andric 573bdd1243dSDimitry Andric Diags.Report(*Loc, DiagID) 574bdd1243dSDimitry Andric << D.getResourceName() << D.getResourceSize() << D.getResourceLimit() 57506c3fb27SDimitry Andric << llvm::demangle(D.getFunction().getName()); 5760b57cec5SDimitry Andric return true; 5770b57cec5SDimitry Andric } 5780b57cec5SDimitry Andric 5790b57cec5SDimitry Andric const FullSourceLoc BackendConsumer::getBestLocationFromDebugLoc( 5800b57cec5SDimitry Andric const llvm::DiagnosticInfoWithLocationBase &D, bool &BadDebugInfo, 5810b57cec5SDimitry Andric StringRef &Filename, unsigned &Line, unsigned &Column) const { 5820b57cec5SDimitry Andric SourceManager &SourceMgr = Context->getSourceManager(); 5830b57cec5SDimitry Andric FileManager &FileMgr = SourceMgr.getFileManager(); 5840b57cec5SDimitry Andric SourceLocation DILoc; 5850b57cec5SDimitry Andric 5860b57cec5SDimitry Andric if (D.isLocationAvailable()) { 5870b57cec5SDimitry Andric D.getLocation(Filename, Line, Column); 5880b57cec5SDimitry Andric if (Line > 0) { 589a7dea167SDimitry Andric auto FE = FileMgr.getFile(Filename); 5900b57cec5SDimitry Andric if (!FE) 5910b57cec5SDimitry Andric FE = FileMgr.getFile(D.getAbsolutePath()); 5920b57cec5SDimitry Andric if (FE) { 5930b57cec5SDimitry Andric // If -gcolumn-info was not used, Column will be 0. This upsets the 5940b57cec5SDimitry Andric // source manager, so pass 1 if Column is not set. 595a7dea167SDimitry Andric DILoc = SourceMgr.translateFileLineCol(*FE, Line, Column ? Column : 1); 5960b57cec5SDimitry Andric } 5970b57cec5SDimitry Andric } 5980b57cec5SDimitry Andric BadDebugInfo = DILoc.isInvalid(); 5990b57cec5SDimitry Andric } 6000b57cec5SDimitry Andric 6010b57cec5SDimitry Andric // If a location isn't available, try to approximate it using the associated 6020b57cec5SDimitry Andric // function definition. We use the definition's right brace to differentiate 6030b57cec5SDimitry Andric // from diagnostics that genuinely relate to the function itself. 6040b57cec5SDimitry Andric FullSourceLoc Loc(DILoc, SourceMgr); 605349cc55cSDimitry Andric if (Loc.isInvalid()) { 606349cc55cSDimitry Andric if (auto MaybeLoc = getFunctionSourceLocation(D.getFunction())) 607349cc55cSDimitry Andric Loc = *MaybeLoc; 608349cc55cSDimitry Andric } 6090b57cec5SDimitry Andric 6100b57cec5SDimitry Andric if (DILoc.isInvalid() && D.isLocationAvailable()) 6110b57cec5SDimitry Andric // If we were not able to translate the file:line:col information 6120b57cec5SDimitry Andric // back to a SourceLocation, at least emit a note stating that 6130b57cec5SDimitry Andric // we could not translate this location. This can happen in the 6140b57cec5SDimitry Andric // case of #line directives. 6150b57cec5SDimitry Andric Diags.Report(Loc, diag::note_fe_backend_invalid_loc) 6160b57cec5SDimitry Andric << Filename << Line << Column; 6170b57cec5SDimitry Andric 6180b57cec5SDimitry Andric return Loc; 6190b57cec5SDimitry Andric } 6200b57cec5SDimitry Andric 621bdd1243dSDimitry Andric std::optional<FullSourceLoc> 622349cc55cSDimitry Andric BackendConsumer::getFunctionSourceLocation(const Function &F) const { 623349cc55cSDimitry Andric auto Hash = llvm::hash_value(F.getName()); 624349cc55cSDimitry Andric for (const auto &Pair : ManglingFullSourceLocs) { 625349cc55cSDimitry Andric if (Pair.first == Hash) 626349cc55cSDimitry Andric return Pair.second; 627349cc55cSDimitry Andric } 628bdd1243dSDimitry Andric return std::nullopt; 629349cc55cSDimitry Andric } 630349cc55cSDimitry Andric 6310b57cec5SDimitry Andric void BackendConsumer::UnsupportedDiagHandler( 6320b57cec5SDimitry Andric const llvm::DiagnosticInfoUnsupported &D) { 6335ffd83dbSDimitry Andric // We only support warnings or errors. 6345ffd83dbSDimitry Andric assert(D.getSeverity() == llvm::DS_Error || 6355ffd83dbSDimitry Andric D.getSeverity() == llvm::DS_Warning); 6360b57cec5SDimitry Andric 6370b57cec5SDimitry Andric StringRef Filename; 6380b57cec5SDimitry Andric unsigned Line, Column; 6390b57cec5SDimitry Andric bool BadDebugInfo = false; 640480093f4SDimitry Andric FullSourceLoc Loc; 641480093f4SDimitry Andric std::string Msg; 642480093f4SDimitry Andric raw_string_ostream MsgStream(Msg); 6430b57cec5SDimitry Andric 644480093f4SDimitry Andric // Context will be nullptr for IR input files, we will construct the diag 645480093f4SDimitry Andric // message from llvm::DiagnosticInfoUnsupported. 646480093f4SDimitry Andric if (Context != nullptr) { 647480093f4SDimitry Andric Loc = getBestLocationFromDebugLoc(D, BadDebugInfo, Filename, Line, Column); 648480093f4SDimitry Andric MsgStream << D.getMessage(); 649480093f4SDimitry Andric } else { 650480093f4SDimitry Andric DiagnosticPrinterRawOStream DP(MsgStream); 651480093f4SDimitry Andric D.print(DP); 652480093f4SDimitry Andric } 6535ffd83dbSDimitry Andric 6545ffd83dbSDimitry Andric auto DiagType = D.getSeverity() == llvm::DS_Error 6555ffd83dbSDimitry Andric ? diag::err_fe_backend_unsupported 6565ffd83dbSDimitry Andric : diag::warn_fe_backend_unsupported; 6575ffd83dbSDimitry Andric Diags.Report(Loc, DiagType) << MsgStream.str(); 6580b57cec5SDimitry Andric 6590b57cec5SDimitry Andric if (BadDebugInfo) 6600b57cec5SDimitry Andric // If we were not able to translate the file:line:col information 6610b57cec5SDimitry Andric // back to a SourceLocation, at least emit a note stating that 6620b57cec5SDimitry Andric // we could not translate this location. This can happen in the 6630b57cec5SDimitry Andric // case of #line directives. 6640b57cec5SDimitry Andric Diags.Report(Loc, diag::note_fe_backend_invalid_loc) 6650b57cec5SDimitry Andric << Filename << Line << Column; 6660b57cec5SDimitry Andric } 6670b57cec5SDimitry Andric 6680b57cec5SDimitry Andric void BackendConsumer::EmitOptimizationMessage( 6690b57cec5SDimitry Andric const llvm::DiagnosticInfoOptimizationBase &D, unsigned DiagID) { 6700b57cec5SDimitry Andric // We only support warnings and remarks. 6710b57cec5SDimitry Andric assert(D.getSeverity() == llvm::DS_Remark || 6720b57cec5SDimitry Andric D.getSeverity() == llvm::DS_Warning); 6730b57cec5SDimitry Andric 6740b57cec5SDimitry Andric StringRef Filename; 6750b57cec5SDimitry Andric unsigned Line, Column; 6760b57cec5SDimitry Andric bool BadDebugInfo = false; 677480093f4SDimitry Andric FullSourceLoc Loc; 6780b57cec5SDimitry Andric std::string Msg; 6790b57cec5SDimitry Andric raw_string_ostream MsgStream(Msg); 680480093f4SDimitry Andric 681480093f4SDimitry Andric // Context will be nullptr for IR input files, we will construct the remark 682480093f4SDimitry Andric // message from llvm::DiagnosticInfoOptimizationBase. 683480093f4SDimitry Andric if (Context != nullptr) { 684480093f4SDimitry Andric Loc = getBestLocationFromDebugLoc(D, BadDebugInfo, Filename, Line, Column); 6850b57cec5SDimitry Andric MsgStream << D.getMsg(); 686480093f4SDimitry Andric } else { 687480093f4SDimitry Andric DiagnosticPrinterRawOStream DP(MsgStream); 688480093f4SDimitry Andric D.print(DP); 689480093f4SDimitry Andric } 6900b57cec5SDimitry Andric 6910b57cec5SDimitry Andric if (D.getHotness()) 6920b57cec5SDimitry Andric MsgStream << " (hotness: " << *D.getHotness() << ")"; 6930b57cec5SDimitry Andric 6940b57cec5SDimitry Andric Diags.Report(Loc, DiagID) 6950b57cec5SDimitry Andric << AddFlagValue(D.getPassName()) 6960b57cec5SDimitry Andric << MsgStream.str(); 6970b57cec5SDimitry Andric 6980b57cec5SDimitry Andric if (BadDebugInfo) 6990b57cec5SDimitry Andric // If we were not able to translate the file:line:col information 7000b57cec5SDimitry Andric // back to a SourceLocation, at least emit a note stating that 7010b57cec5SDimitry Andric // we could not translate this location. This can happen in the 7020b57cec5SDimitry Andric // case of #line directives. 7030b57cec5SDimitry Andric Diags.Report(Loc, diag::note_fe_backend_invalid_loc) 7040b57cec5SDimitry Andric << Filename << Line << Column; 7050b57cec5SDimitry Andric } 7060b57cec5SDimitry Andric 7070b57cec5SDimitry Andric void BackendConsumer::OptimizationRemarkHandler( 7080b57cec5SDimitry Andric const llvm::DiagnosticInfoOptimizationBase &D) { 7090b57cec5SDimitry Andric // Without hotness information, don't show noisy remarks. 7100b57cec5SDimitry Andric if (D.isVerbose() && !D.getHotness()) 7110b57cec5SDimitry Andric return; 7120b57cec5SDimitry Andric 7130b57cec5SDimitry Andric if (D.isPassed()) { 7140b57cec5SDimitry Andric // Optimization remarks are active only if the -Rpass flag has a regular 7150b57cec5SDimitry Andric // expression that matches the name of the pass name in \p D. 716fe6060f1SDimitry Andric if (CodeGenOpts.OptimizationRemark.patternMatches(D.getPassName())) 7170b57cec5SDimitry Andric EmitOptimizationMessage(D, diag::remark_fe_backend_optimization_remark); 7180b57cec5SDimitry Andric } else if (D.isMissed()) { 7190b57cec5SDimitry Andric // Missed optimization remarks are active only if the -Rpass-missed 7200b57cec5SDimitry Andric // flag has a regular expression that matches the name of the pass 7210b57cec5SDimitry Andric // name in \p D. 722fe6060f1SDimitry Andric if (CodeGenOpts.OptimizationRemarkMissed.patternMatches(D.getPassName())) 7230b57cec5SDimitry Andric EmitOptimizationMessage( 7240b57cec5SDimitry Andric D, diag::remark_fe_backend_optimization_remark_missed); 7250b57cec5SDimitry Andric } else { 7260b57cec5SDimitry Andric assert(D.isAnalysis() && "Unknown remark type"); 7270b57cec5SDimitry Andric 7280b57cec5SDimitry Andric bool ShouldAlwaysPrint = false; 7290b57cec5SDimitry Andric if (auto *ORA = dyn_cast<llvm::OptimizationRemarkAnalysis>(&D)) 7300b57cec5SDimitry Andric ShouldAlwaysPrint = ORA->shouldAlwaysPrint(); 7310b57cec5SDimitry Andric 7320b57cec5SDimitry Andric if (ShouldAlwaysPrint || 733fe6060f1SDimitry Andric CodeGenOpts.OptimizationRemarkAnalysis.patternMatches(D.getPassName())) 7340b57cec5SDimitry Andric EmitOptimizationMessage( 7350b57cec5SDimitry Andric D, diag::remark_fe_backend_optimization_remark_analysis); 7360b57cec5SDimitry Andric } 7370b57cec5SDimitry Andric } 7380b57cec5SDimitry Andric 7390b57cec5SDimitry Andric void BackendConsumer::OptimizationRemarkHandler( 7400b57cec5SDimitry Andric const llvm::OptimizationRemarkAnalysisFPCommute &D) { 7410b57cec5SDimitry Andric // Optimization analysis remarks are active if the pass name is set to 7420b57cec5SDimitry Andric // llvm::DiagnosticInfo::AlwasyPrint or if the -Rpass-analysis flag has a 7430b57cec5SDimitry Andric // regular expression that matches the name of the pass name in \p D. 7440b57cec5SDimitry Andric 7450b57cec5SDimitry Andric if (D.shouldAlwaysPrint() || 746fe6060f1SDimitry Andric CodeGenOpts.OptimizationRemarkAnalysis.patternMatches(D.getPassName())) 7470b57cec5SDimitry Andric EmitOptimizationMessage( 7480b57cec5SDimitry Andric D, diag::remark_fe_backend_optimization_remark_analysis_fpcommute); 7490b57cec5SDimitry Andric } 7500b57cec5SDimitry Andric 7510b57cec5SDimitry Andric void BackendConsumer::OptimizationRemarkHandler( 7520b57cec5SDimitry Andric const llvm::OptimizationRemarkAnalysisAliasing &D) { 7530b57cec5SDimitry Andric // Optimization analysis remarks are active if the pass name is set to 7540b57cec5SDimitry Andric // llvm::DiagnosticInfo::AlwasyPrint or if the -Rpass-analysis flag has a 7550b57cec5SDimitry Andric // regular expression that matches the name of the pass name in \p D. 7560b57cec5SDimitry Andric 7570b57cec5SDimitry Andric if (D.shouldAlwaysPrint() || 758fe6060f1SDimitry Andric CodeGenOpts.OptimizationRemarkAnalysis.patternMatches(D.getPassName())) 7590b57cec5SDimitry Andric EmitOptimizationMessage( 7600b57cec5SDimitry Andric D, diag::remark_fe_backend_optimization_remark_analysis_aliasing); 7610b57cec5SDimitry Andric } 7620b57cec5SDimitry Andric 7630b57cec5SDimitry Andric void BackendConsumer::OptimizationFailureHandler( 7640b57cec5SDimitry Andric const llvm::DiagnosticInfoOptimizationFailure &D) { 7650b57cec5SDimitry Andric EmitOptimizationMessage(D, diag::warn_fe_backend_optimization_failure); 7660b57cec5SDimitry Andric } 7670b57cec5SDimitry Andric 768349cc55cSDimitry Andric void BackendConsumer::DontCallDiagHandler(const DiagnosticInfoDontCall &D) { 769349cc55cSDimitry Andric SourceLocation LocCookie = 770349cc55cSDimitry Andric SourceLocation::getFromRawEncoding(D.getLocCookie()); 771349cc55cSDimitry Andric 772349cc55cSDimitry Andric // FIXME: we can't yet diagnose indirect calls. When/if we can, we 773349cc55cSDimitry Andric // should instead assert that LocCookie.isValid(). 774349cc55cSDimitry Andric if (!LocCookie.isValid()) 775349cc55cSDimitry Andric return; 776349cc55cSDimitry Andric 777349cc55cSDimitry Andric Diags.Report(LocCookie, D.getSeverity() == DiagnosticSeverity::DS_Error 778349cc55cSDimitry Andric ? diag::err_fe_backend_error_attr 779349cc55cSDimitry Andric : diag::warn_fe_backend_warning_attr) 78006c3fb27SDimitry Andric << llvm::demangle(D.getFunctionName()) << D.getNote(); 781349cc55cSDimitry Andric } 782349cc55cSDimitry Andric 78381ad6265SDimitry Andric void BackendConsumer::MisExpectDiagHandler( 78481ad6265SDimitry Andric const llvm::DiagnosticInfoMisExpect &D) { 78581ad6265SDimitry Andric StringRef Filename; 78681ad6265SDimitry Andric unsigned Line, Column; 78781ad6265SDimitry Andric bool BadDebugInfo = false; 78881ad6265SDimitry Andric FullSourceLoc Loc = 78981ad6265SDimitry Andric getBestLocationFromDebugLoc(D, BadDebugInfo, Filename, Line, Column); 79081ad6265SDimitry Andric 79181ad6265SDimitry Andric Diags.Report(Loc, diag::warn_profile_data_misexpect) << D.getMsg().str(); 79281ad6265SDimitry Andric 79381ad6265SDimitry Andric if (BadDebugInfo) 79481ad6265SDimitry Andric // If we were not able to translate the file:line:col information 79581ad6265SDimitry Andric // back to a SourceLocation, at least emit a note stating that 79681ad6265SDimitry Andric // we could not translate this location. This can happen in the 79781ad6265SDimitry Andric // case of #line directives. 79881ad6265SDimitry Andric Diags.Report(Loc, diag::note_fe_backend_invalid_loc) 79981ad6265SDimitry Andric << Filename << Line << Column; 80081ad6265SDimitry Andric } 80181ad6265SDimitry Andric 8020b57cec5SDimitry Andric /// This function is invoked when the backend needs 8030b57cec5SDimitry Andric /// to report something to the user. 8040b57cec5SDimitry Andric void BackendConsumer::DiagnosticHandlerImpl(const DiagnosticInfo &DI) { 8050b57cec5SDimitry Andric unsigned DiagID = diag::err_fe_inline_asm; 8060b57cec5SDimitry Andric llvm::DiagnosticSeverity Severity = DI.getSeverity(); 8070b57cec5SDimitry Andric // Get the diagnostic ID based. 8080b57cec5SDimitry Andric switch (DI.getKind()) { 8090b57cec5SDimitry Andric case llvm::DK_InlineAsm: 8100b57cec5SDimitry Andric if (InlineAsmDiagHandler(cast<DiagnosticInfoInlineAsm>(DI))) 8110b57cec5SDimitry Andric return; 8120b57cec5SDimitry Andric ComputeDiagID(Severity, inline_asm, DiagID); 8130b57cec5SDimitry Andric break; 814fe6060f1SDimitry Andric case llvm::DK_SrcMgr: 815fe6060f1SDimitry Andric SrcMgrDiagHandler(cast<DiagnosticInfoSrcMgr>(DI)); 816fe6060f1SDimitry Andric return; 8170b57cec5SDimitry Andric case llvm::DK_StackSize: 8180b57cec5SDimitry Andric if (StackSizeDiagHandler(cast<DiagnosticInfoStackSize>(DI))) 8190b57cec5SDimitry Andric return; 8200b57cec5SDimitry Andric ComputeDiagID(Severity, backend_frame_larger_than, DiagID); 8210b57cec5SDimitry Andric break; 822bdd1243dSDimitry Andric case llvm::DK_ResourceLimit: 823bdd1243dSDimitry Andric if (ResourceLimitDiagHandler(cast<DiagnosticInfoResourceLimit>(DI))) 824bdd1243dSDimitry Andric return; 825bdd1243dSDimitry Andric ComputeDiagID(Severity, backend_resource_limit, DiagID); 826bdd1243dSDimitry Andric break; 8270b57cec5SDimitry Andric case DK_Linker: 828349cc55cSDimitry Andric ComputeDiagID(Severity, linking_module, DiagID); 8290b57cec5SDimitry Andric break; 8300b57cec5SDimitry Andric case llvm::DK_OptimizationRemark: 8310b57cec5SDimitry Andric // Optimization remarks are always handled completely by this 8320b57cec5SDimitry Andric // handler. There is no generic way of emitting them. 8330b57cec5SDimitry Andric OptimizationRemarkHandler(cast<OptimizationRemark>(DI)); 8340b57cec5SDimitry Andric return; 8350b57cec5SDimitry Andric case llvm::DK_OptimizationRemarkMissed: 8360b57cec5SDimitry Andric // Optimization remarks are always handled completely by this 8370b57cec5SDimitry Andric // handler. There is no generic way of emitting them. 8380b57cec5SDimitry Andric OptimizationRemarkHandler(cast<OptimizationRemarkMissed>(DI)); 8390b57cec5SDimitry Andric return; 8400b57cec5SDimitry Andric case llvm::DK_OptimizationRemarkAnalysis: 8410b57cec5SDimitry Andric // Optimization remarks are always handled completely by this 8420b57cec5SDimitry Andric // handler. There is no generic way of emitting them. 8430b57cec5SDimitry Andric OptimizationRemarkHandler(cast<OptimizationRemarkAnalysis>(DI)); 8440b57cec5SDimitry Andric return; 8450b57cec5SDimitry Andric case llvm::DK_OptimizationRemarkAnalysisFPCommute: 8460b57cec5SDimitry Andric // Optimization remarks are always handled completely by this 8470b57cec5SDimitry Andric // handler. There is no generic way of emitting them. 8480b57cec5SDimitry Andric OptimizationRemarkHandler(cast<OptimizationRemarkAnalysisFPCommute>(DI)); 8490b57cec5SDimitry Andric return; 8500b57cec5SDimitry Andric case llvm::DK_OptimizationRemarkAnalysisAliasing: 8510b57cec5SDimitry Andric // Optimization remarks are always handled completely by this 8520b57cec5SDimitry Andric // handler. There is no generic way of emitting them. 8530b57cec5SDimitry Andric OptimizationRemarkHandler(cast<OptimizationRemarkAnalysisAliasing>(DI)); 8540b57cec5SDimitry Andric return; 8550b57cec5SDimitry Andric case llvm::DK_MachineOptimizationRemark: 8560b57cec5SDimitry Andric // Optimization remarks are always handled completely by this 8570b57cec5SDimitry Andric // handler. There is no generic way of emitting them. 8580b57cec5SDimitry Andric OptimizationRemarkHandler(cast<MachineOptimizationRemark>(DI)); 8590b57cec5SDimitry Andric return; 8600b57cec5SDimitry Andric case llvm::DK_MachineOptimizationRemarkMissed: 8610b57cec5SDimitry Andric // Optimization remarks are always handled completely by this 8620b57cec5SDimitry Andric // handler. There is no generic way of emitting them. 8630b57cec5SDimitry Andric OptimizationRemarkHandler(cast<MachineOptimizationRemarkMissed>(DI)); 8640b57cec5SDimitry Andric return; 8650b57cec5SDimitry Andric case llvm::DK_MachineOptimizationRemarkAnalysis: 8660b57cec5SDimitry Andric // Optimization remarks are always handled completely by this 8670b57cec5SDimitry Andric // handler. There is no generic way of emitting them. 8680b57cec5SDimitry Andric OptimizationRemarkHandler(cast<MachineOptimizationRemarkAnalysis>(DI)); 8690b57cec5SDimitry Andric return; 8700b57cec5SDimitry Andric case llvm::DK_OptimizationFailure: 8710b57cec5SDimitry Andric // Optimization failures are always handled completely by this 8720b57cec5SDimitry Andric // handler. 8730b57cec5SDimitry Andric OptimizationFailureHandler(cast<DiagnosticInfoOptimizationFailure>(DI)); 8740b57cec5SDimitry Andric return; 8750b57cec5SDimitry Andric case llvm::DK_Unsupported: 8760b57cec5SDimitry Andric UnsupportedDiagHandler(cast<DiagnosticInfoUnsupported>(DI)); 8770b57cec5SDimitry Andric return; 878349cc55cSDimitry Andric case llvm::DK_DontCall: 879349cc55cSDimitry Andric DontCallDiagHandler(cast<DiagnosticInfoDontCall>(DI)); 880349cc55cSDimitry Andric return; 88181ad6265SDimitry Andric case llvm::DK_MisExpect: 88281ad6265SDimitry Andric MisExpectDiagHandler(cast<DiagnosticInfoMisExpect>(DI)); 88381ad6265SDimitry Andric return; 8840b57cec5SDimitry Andric default: 8850b57cec5SDimitry Andric // Plugin IDs are not bound to any value as they are set dynamically. 8860b57cec5SDimitry Andric ComputeDiagRemarkID(Severity, backend_plugin, DiagID); 8870b57cec5SDimitry Andric break; 8880b57cec5SDimitry Andric } 8890b57cec5SDimitry Andric std::string MsgStorage; 8900b57cec5SDimitry Andric { 8910b57cec5SDimitry Andric raw_string_ostream Stream(MsgStorage); 8920b57cec5SDimitry Andric DiagnosticPrinterRawOStream DP(Stream); 8930b57cec5SDimitry Andric DI.print(DP); 8940b57cec5SDimitry Andric } 8950b57cec5SDimitry Andric 896349cc55cSDimitry Andric if (DI.getKind() == DK_Linker) { 897349cc55cSDimitry Andric assert(CurLinkModule && "CurLinkModule must be set for linker diagnostics"); 898349cc55cSDimitry Andric Diags.Report(DiagID) << CurLinkModule->getModuleIdentifier() << MsgStorage; 8990b57cec5SDimitry Andric return; 9000b57cec5SDimitry Andric } 9010b57cec5SDimitry Andric 9020b57cec5SDimitry Andric // Report the backend message using the usual diagnostic mechanism. 9030b57cec5SDimitry Andric FullSourceLoc Loc; 9040b57cec5SDimitry Andric Diags.Report(Loc, DiagID).AddString(MsgStorage); 9050b57cec5SDimitry Andric } 9060b57cec5SDimitry Andric #undef ComputeDiagID 9070b57cec5SDimitry Andric 9080b57cec5SDimitry Andric CodeGenAction::CodeGenAction(unsigned _Act, LLVMContext *_VMContext) 9090b57cec5SDimitry Andric : Act(_Act), VMContext(_VMContext ? _VMContext : new LLVMContext), 9100b57cec5SDimitry Andric OwnsVMContext(!_VMContext) {} 9110b57cec5SDimitry Andric 9120b57cec5SDimitry Andric CodeGenAction::~CodeGenAction() { 9130b57cec5SDimitry Andric TheModule.reset(); 9140b57cec5SDimitry Andric if (OwnsVMContext) 9150b57cec5SDimitry Andric delete VMContext; 9160b57cec5SDimitry Andric } 9170b57cec5SDimitry Andric 91806c3fb27SDimitry Andric bool CodeGenAction::loadLinkModules(CompilerInstance &CI) { 91906c3fb27SDimitry Andric if (!LinkModules.empty()) 92006c3fb27SDimitry Andric return false; 92106c3fb27SDimitry Andric 92206c3fb27SDimitry Andric for (const CodeGenOptions::BitcodeFileToLink &F : 92306c3fb27SDimitry Andric CI.getCodeGenOpts().LinkBitcodeFiles) { 92406c3fb27SDimitry Andric auto BCBuf = CI.getFileManager().getBufferForFile(F.Filename); 92506c3fb27SDimitry Andric if (!BCBuf) { 92606c3fb27SDimitry Andric CI.getDiagnostics().Report(diag::err_cannot_open_file) 92706c3fb27SDimitry Andric << F.Filename << BCBuf.getError().message(); 92806c3fb27SDimitry Andric LinkModules.clear(); 92906c3fb27SDimitry Andric return true; 93006c3fb27SDimitry Andric } 93106c3fb27SDimitry Andric 93206c3fb27SDimitry Andric Expected<std::unique_ptr<llvm::Module>> ModuleOrErr = 93306c3fb27SDimitry Andric getOwningLazyBitcodeModule(std::move(*BCBuf), *VMContext); 93406c3fb27SDimitry Andric if (!ModuleOrErr) { 93506c3fb27SDimitry Andric handleAllErrors(ModuleOrErr.takeError(), [&](ErrorInfoBase &EIB) { 93606c3fb27SDimitry Andric CI.getDiagnostics().Report(diag::err_cannot_open_file) 93706c3fb27SDimitry Andric << F.Filename << EIB.message(); 93806c3fb27SDimitry Andric }); 93906c3fb27SDimitry Andric LinkModules.clear(); 94006c3fb27SDimitry Andric return true; 94106c3fb27SDimitry Andric } 94206c3fb27SDimitry Andric LinkModules.push_back({std::move(ModuleOrErr.get()), F.PropagateAttrs, 94306c3fb27SDimitry Andric F.Internalize, F.LinkFlags}); 94406c3fb27SDimitry Andric } 94506c3fb27SDimitry Andric return false; 94606c3fb27SDimitry Andric } 94706c3fb27SDimitry Andric 9480b57cec5SDimitry Andric bool CodeGenAction::hasIRSupport() const { return true; } 9490b57cec5SDimitry Andric 9500b57cec5SDimitry Andric void CodeGenAction::EndSourceFileAction() { 9510b57cec5SDimitry Andric // If the consumer creation failed, do nothing. 9520b57cec5SDimitry Andric if (!getCompilerInstance().hasASTConsumer()) 9530b57cec5SDimitry Andric return; 9540b57cec5SDimitry Andric 9550b57cec5SDimitry Andric // Steal the module from the consumer. 9560b57cec5SDimitry Andric TheModule = BEConsumer->takeModule(); 9570b57cec5SDimitry Andric } 9580b57cec5SDimitry Andric 9590b57cec5SDimitry Andric std::unique_ptr<llvm::Module> CodeGenAction::takeModule() { 9600b57cec5SDimitry Andric return std::move(TheModule); 9610b57cec5SDimitry Andric } 9620b57cec5SDimitry Andric 9630b57cec5SDimitry Andric llvm::LLVMContext *CodeGenAction::takeLLVMContext() { 9640b57cec5SDimitry Andric OwnsVMContext = false; 9650b57cec5SDimitry Andric return VMContext; 9660b57cec5SDimitry Andric } 9670b57cec5SDimitry Andric 968fe6060f1SDimitry Andric CodeGenerator *CodeGenAction::getCodeGenerator() const { 969fe6060f1SDimitry Andric return BEConsumer->getCodeGenerator(); 970fe6060f1SDimitry Andric } 971fe6060f1SDimitry Andric 972*0fca6ea1SDimitry Andric bool CodeGenAction::BeginSourceFileAction(CompilerInstance &CI) { 973*0fca6ea1SDimitry Andric if (CI.getFrontendOpts().GenReducedBMI) 974*0fca6ea1SDimitry Andric CI.getLangOpts().setCompilingModule(LangOptions::CMK_ModuleInterface); 975*0fca6ea1SDimitry Andric return true; 976*0fca6ea1SDimitry Andric } 977*0fca6ea1SDimitry Andric 9780b57cec5SDimitry Andric static std::unique_ptr<raw_pwrite_stream> 9790b57cec5SDimitry Andric GetOutputStream(CompilerInstance &CI, StringRef InFile, BackendAction Action) { 9800b57cec5SDimitry Andric switch (Action) { 9810b57cec5SDimitry Andric case Backend_EmitAssembly: 9820b57cec5SDimitry Andric return CI.createDefaultOutputFile(false, InFile, "s"); 9830b57cec5SDimitry Andric case Backend_EmitLL: 9840b57cec5SDimitry Andric return CI.createDefaultOutputFile(false, InFile, "ll"); 9850b57cec5SDimitry Andric case Backend_EmitBC: 9860b57cec5SDimitry Andric return CI.createDefaultOutputFile(true, InFile, "bc"); 9870b57cec5SDimitry Andric case Backend_EmitNothing: 9880b57cec5SDimitry Andric return nullptr; 9890b57cec5SDimitry Andric case Backend_EmitMCNull: 9900b57cec5SDimitry Andric return CI.createNullOutputFile(); 9910b57cec5SDimitry Andric case Backend_EmitObj: 9920b57cec5SDimitry Andric return CI.createDefaultOutputFile(true, InFile, "o"); 9930b57cec5SDimitry Andric } 9940b57cec5SDimitry Andric 9950b57cec5SDimitry Andric llvm_unreachable("Invalid action!"); 9960b57cec5SDimitry Andric } 9970b57cec5SDimitry Andric 9980b57cec5SDimitry Andric std::unique_ptr<ASTConsumer> 9990b57cec5SDimitry Andric CodeGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { 10000b57cec5SDimitry Andric BackendAction BA = static_cast<BackendAction>(Act); 10010b57cec5SDimitry Andric std::unique_ptr<raw_pwrite_stream> OS = CI.takeOutputStream(); 10020b57cec5SDimitry Andric if (!OS) 10030b57cec5SDimitry Andric OS = GetOutputStream(CI, InFile, BA); 10040b57cec5SDimitry Andric 10050b57cec5SDimitry Andric if (BA != Backend_EmitNothing && !OS) 10060b57cec5SDimitry Andric return nullptr; 10070b57cec5SDimitry Andric 10080b57cec5SDimitry Andric // Load bitcode modules to link with, if we need to. 100906c3fb27SDimitry Andric if (loadLinkModules(CI)) 10100b57cec5SDimitry Andric return nullptr; 10110b57cec5SDimitry Andric 10120b57cec5SDimitry Andric CoverageSourceInfo *CoverageInfo = nullptr; 10130b57cec5SDimitry Andric // Add the preprocessor callback only when the coverage mapping is generated. 1014e8d8bef9SDimitry Andric if (CI.getCodeGenOpts().CoverageMapping) 1015e8d8bef9SDimitry Andric CoverageInfo = CodeGen::CoverageMappingModuleGen::setUpCoverageCallbacks( 1016e8d8bef9SDimitry Andric CI.getPreprocessor()); 10170b57cec5SDimitry Andric 10180b57cec5SDimitry Andric std::unique_ptr<BackendConsumer> Result(new BackendConsumer( 1019972a253aSDimitry Andric BA, CI.getDiagnostics(), &CI.getVirtualFileSystem(), 1020972a253aSDimitry Andric CI.getHeaderSearchOpts(), CI.getPreprocessorOpts(), CI.getCodeGenOpts(), 1021972a253aSDimitry Andric CI.getTargetOpts(), CI.getLangOpts(), std::string(InFile), 1022972a253aSDimitry Andric std::move(LinkModules), std::move(OS), *VMContext, CoverageInfo)); 10230b57cec5SDimitry Andric BEConsumer = Result.get(); 10240b57cec5SDimitry Andric 10250b57cec5SDimitry Andric // Enable generating macro debug info only when debug info is not disabled and 10260b57cec5SDimitry Andric // also macro debug info is enabled. 10270b57cec5SDimitry Andric if (CI.getCodeGenOpts().getDebugInfo() != codegenoptions::NoDebugInfo && 10280b57cec5SDimitry Andric CI.getCodeGenOpts().MacroDebugInfo) { 10290b57cec5SDimitry Andric std::unique_ptr<PPCallbacks> Callbacks = 1030a7dea167SDimitry Andric std::make_unique<MacroPPCallbacks>(BEConsumer->getCodeGenerator(), 10310b57cec5SDimitry Andric CI.getPreprocessor()); 10320b57cec5SDimitry Andric CI.getPreprocessor().addPPCallbacks(std::move(Callbacks)); 10330b57cec5SDimitry Andric } 10340b57cec5SDimitry Andric 1035*0fca6ea1SDimitry Andric if (CI.getFrontendOpts().GenReducedBMI && 1036*0fca6ea1SDimitry Andric !CI.getFrontendOpts().ModuleOutputPath.empty()) { 1037*0fca6ea1SDimitry Andric std::vector<std::unique_ptr<ASTConsumer>> Consumers(2); 1038*0fca6ea1SDimitry Andric Consumers[0] = std::make_unique<ReducedBMIGenerator>( 1039*0fca6ea1SDimitry Andric CI.getPreprocessor(), CI.getModuleCache(), 1040*0fca6ea1SDimitry Andric CI.getFrontendOpts().ModuleOutputPath); 1041*0fca6ea1SDimitry Andric Consumers[1] = std::move(Result); 1042*0fca6ea1SDimitry Andric return std::make_unique<MultiplexConsumer>(std::move(Consumers)); 1043*0fca6ea1SDimitry Andric } 1044*0fca6ea1SDimitry Andric 10450b57cec5SDimitry Andric return std::move(Result); 10460b57cec5SDimitry Andric } 10470b57cec5SDimitry Andric 10480b57cec5SDimitry Andric std::unique_ptr<llvm::Module> 10490b57cec5SDimitry Andric CodeGenAction::loadModule(MemoryBufferRef MBRef) { 10500b57cec5SDimitry Andric CompilerInstance &CI = getCompilerInstance(); 10510b57cec5SDimitry Andric SourceManager &SM = CI.getSourceManager(); 10520b57cec5SDimitry Andric 10530b57cec5SDimitry Andric auto DiagErrors = [&](Error E) -> std::unique_ptr<llvm::Module> { 10540b57cec5SDimitry Andric unsigned DiagID = 10550b57cec5SDimitry Andric CI.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error, "%0"); 10560b57cec5SDimitry Andric handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) { 10570b57cec5SDimitry Andric CI.getDiagnostics().Report(DiagID) << EIB.message(); 10580b57cec5SDimitry Andric }); 10590b57cec5SDimitry Andric return {}; 10600b57cec5SDimitry Andric }; 10610b57cec5SDimitry Andric 106206c3fb27SDimitry Andric // For ThinLTO backend invocations, ensure that the context 106306c3fb27SDimitry Andric // merges types based on ODR identifiers. We also need to read 106406c3fb27SDimitry Andric // the correct module out of a multi-module bitcode file. 106506c3fb27SDimitry Andric if (!CI.getCodeGenOpts().ThinLTOIndexFile.empty()) { 106606c3fb27SDimitry Andric VMContext->enableDebugTypeODRUniquing(); 106706c3fb27SDimitry Andric 10680b57cec5SDimitry Andric Expected<std::vector<BitcodeModule>> BMsOrErr = getBitcodeModuleList(MBRef); 10690b57cec5SDimitry Andric if (!BMsOrErr) 10700b57cec5SDimitry Andric return DiagErrors(BMsOrErr.takeError()); 1071e8d8bef9SDimitry Andric BitcodeModule *Bm = llvm::lto::findThinLTOModule(*BMsOrErr); 10720b57cec5SDimitry Andric // We have nothing to do if the file contains no ThinLTO module. This is 10730b57cec5SDimitry Andric // possible if ThinLTO compilation was not able to split module. Content of 10740b57cec5SDimitry Andric // the file was already processed by indexing and will be passed to the 10750b57cec5SDimitry Andric // linker using merged object file. 10760b57cec5SDimitry Andric if (!Bm) { 1077a7dea167SDimitry Andric auto M = std::make_unique<llvm::Module>("empty", *VMContext); 10780b57cec5SDimitry Andric M->setTargetTriple(CI.getTargetOpts().Triple); 10790b57cec5SDimitry Andric return M; 10800b57cec5SDimitry Andric } 10810b57cec5SDimitry Andric Expected<std::unique_ptr<llvm::Module>> MOrErr = 10820b57cec5SDimitry Andric Bm->parseModule(*VMContext); 10830b57cec5SDimitry Andric if (!MOrErr) 10840b57cec5SDimitry Andric return DiagErrors(MOrErr.takeError()); 10850b57cec5SDimitry Andric return std::move(*MOrErr); 10860b57cec5SDimitry Andric } 10870b57cec5SDimitry Andric 108806c3fb27SDimitry Andric // Load bitcode modules to link with, if we need to. 108906c3fb27SDimitry Andric if (loadLinkModules(CI)) 109006c3fb27SDimitry Andric return nullptr; 109106c3fb27SDimitry Andric 109206c3fb27SDimitry Andric // Handle textual IR and bitcode file with one single module. 10930b57cec5SDimitry Andric llvm::SMDiagnostic Err; 10940b57cec5SDimitry Andric if (std::unique_ptr<llvm::Module> M = parseIR(MBRef, Err, *VMContext)) 10950b57cec5SDimitry Andric return M; 10960b57cec5SDimitry Andric 109706c3fb27SDimitry Andric // If MBRef is a bitcode with multiple modules (e.g., -fsplit-lto-unit 109806c3fb27SDimitry Andric // output), place the extra modules (actually only one, a regular LTO module) 109906c3fb27SDimitry Andric // into LinkModules as if we are using -mlink-bitcode-file. 110006c3fb27SDimitry Andric Expected<std::vector<BitcodeModule>> BMsOrErr = getBitcodeModuleList(MBRef); 110106c3fb27SDimitry Andric if (BMsOrErr && BMsOrErr->size()) { 110206c3fb27SDimitry Andric std::unique_ptr<llvm::Module> FirstM; 110306c3fb27SDimitry Andric for (auto &BM : *BMsOrErr) { 110406c3fb27SDimitry Andric Expected<std::unique_ptr<llvm::Module>> MOrErr = 110506c3fb27SDimitry Andric BM.parseModule(*VMContext); 110606c3fb27SDimitry Andric if (!MOrErr) 110706c3fb27SDimitry Andric return DiagErrors(MOrErr.takeError()); 110806c3fb27SDimitry Andric if (FirstM) 110906c3fb27SDimitry Andric LinkModules.push_back({std::move(*MOrErr), /*PropagateAttrs=*/false, 111006c3fb27SDimitry Andric /*Internalize=*/false, /*LinkFlags=*/{}}); 111106c3fb27SDimitry Andric else 111206c3fb27SDimitry Andric FirstM = std::move(*MOrErr); 111306c3fb27SDimitry Andric } 111406c3fb27SDimitry Andric if (FirstM) 111506c3fb27SDimitry Andric return FirstM; 111606c3fb27SDimitry Andric } 111706c3fb27SDimitry Andric // If BMsOrErr fails, consume the error and use the error message from 111806c3fb27SDimitry Andric // parseIR. 111906c3fb27SDimitry Andric consumeError(BMsOrErr.takeError()); 112006c3fb27SDimitry Andric 11210b57cec5SDimitry Andric // Translate from the diagnostic info to the SourceManager location if 11220b57cec5SDimitry Andric // available. 11230b57cec5SDimitry Andric // TODO: Unify this with ConvertBackendLocation() 11240b57cec5SDimitry Andric SourceLocation Loc; 11250b57cec5SDimitry Andric if (Err.getLineNo() > 0) { 11260b57cec5SDimitry Andric assert(Err.getColumnNo() >= 0); 11270b57cec5SDimitry Andric Loc = SM.translateFileLineCol(SM.getFileEntryForID(SM.getMainFileID()), 11280b57cec5SDimitry Andric Err.getLineNo(), Err.getColumnNo() + 1); 11290b57cec5SDimitry Andric } 11300b57cec5SDimitry Andric 11310b57cec5SDimitry Andric // Strip off a leading diagnostic code if there is one. 11320b57cec5SDimitry Andric StringRef Msg = Err.getMessage(); 1133647cbc5dSDimitry Andric Msg.consume_front("error: "); 11340b57cec5SDimitry Andric 11350b57cec5SDimitry Andric unsigned DiagID = 11360b57cec5SDimitry Andric CI.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error, "%0"); 11370b57cec5SDimitry Andric 11380b57cec5SDimitry Andric CI.getDiagnostics().Report(Loc, DiagID) << Msg; 11390b57cec5SDimitry Andric return {}; 11400b57cec5SDimitry Andric } 11410b57cec5SDimitry Andric 11420b57cec5SDimitry Andric void CodeGenAction::ExecuteAction() { 1143e8d8bef9SDimitry Andric if (getCurrentFileKind().getLanguage() != Language::LLVM_IR) { 1144e8d8bef9SDimitry Andric this->ASTFrontendAction::ExecuteAction(); 1145e8d8bef9SDimitry Andric return; 1146e8d8bef9SDimitry Andric } 1147e8d8bef9SDimitry Andric 11480b57cec5SDimitry Andric // If this is an IR file, we have to treat it specially. 11490b57cec5SDimitry Andric BackendAction BA = static_cast<BackendAction>(Act); 11500b57cec5SDimitry Andric CompilerInstance &CI = getCompilerInstance(); 1151480093f4SDimitry Andric auto &CodeGenOpts = CI.getCodeGenOpts(); 1152480093f4SDimitry Andric auto &Diagnostics = CI.getDiagnostics(); 11530b57cec5SDimitry Andric std::unique_ptr<raw_pwrite_stream> OS = 115481ad6265SDimitry Andric GetOutputStream(CI, getCurrentFileOrBufferName(), BA); 11550b57cec5SDimitry Andric if (BA != Backend_EmitNothing && !OS) 11560b57cec5SDimitry Andric return; 11570b57cec5SDimitry Andric 11580b57cec5SDimitry Andric SourceManager &SM = CI.getSourceManager(); 11590b57cec5SDimitry Andric FileID FID = SM.getMainFileID(); 1160bdd1243dSDimitry Andric std::optional<MemoryBufferRef> MainFile = SM.getBufferOrNone(FID); 1161e8d8bef9SDimitry Andric if (!MainFile) 11620b57cec5SDimitry Andric return; 11630b57cec5SDimitry Andric 11640b57cec5SDimitry Andric TheModule = loadModule(*MainFile); 11650b57cec5SDimitry Andric if (!TheModule) 11660b57cec5SDimitry Andric return; 11670b57cec5SDimitry Andric 11680b57cec5SDimitry Andric const TargetOptions &TargetOpts = CI.getTargetOpts(); 11690b57cec5SDimitry Andric if (TheModule->getTargetTriple() != TargetOpts.Triple) { 1170e8d8bef9SDimitry Andric Diagnostics.Report(SourceLocation(), diag::warn_fe_override_module) 11710b57cec5SDimitry Andric << TargetOpts.Triple; 11720b57cec5SDimitry Andric TheModule->setTargetTriple(TargetOpts.Triple); 11730b57cec5SDimitry Andric } 11740b57cec5SDimitry Andric 11751fd87a68SDimitry Andric EmbedObject(TheModule.get(), CodeGenOpts, Diagnostics); 1176e8d8bef9SDimitry Andric EmbedBitcode(TheModule.get(), CodeGenOpts, *MainFile); 11770b57cec5SDimitry Andric 11780b57cec5SDimitry Andric LLVMContext &Ctx = TheModule->getContext(); 1179fe6060f1SDimitry Andric 1180fe6060f1SDimitry Andric // Restore any diagnostic handler previously set before returning from this 1181fe6060f1SDimitry Andric // function. 1182fe6060f1SDimitry Andric struct RAII { 1183fe6060f1SDimitry Andric LLVMContext &Ctx; 1184fe6060f1SDimitry Andric std::unique_ptr<DiagnosticHandler> PrevHandler = Ctx.getDiagnosticHandler(); 1185fe6060f1SDimitry Andric ~RAII() { Ctx.setDiagnosticHandler(std::move(PrevHandler)); } 1186fe6060f1SDimitry Andric } _{Ctx}; 11870b57cec5SDimitry Andric 1188480093f4SDimitry Andric // Set clang diagnostic handler. To do this we need to create a fake 1189480093f4SDimitry Andric // BackendConsumer. 1190972a253aSDimitry Andric BackendConsumer Result(BA, CI.getDiagnostics(), &CI.getVirtualFileSystem(), 1191972a253aSDimitry Andric CI.getHeaderSearchOpts(), CI.getPreprocessorOpts(), 1192972a253aSDimitry Andric CI.getCodeGenOpts(), CI.getTargetOpts(), 1193972a253aSDimitry Andric CI.getLangOpts(), TheModule.get(), 1194480093f4SDimitry Andric std::move(LinkModules), *VMContext, nullptr); 119506c3fb27SDimitry Andric 119606c3fb27SDimitry Andric // Link in each pending link module. 1197*0fca6ea1SDimitry Andric if (!CodeGenOpts.LinkBitcodePostopt && Result.LinkInModules(&*TheModule)) 119806c3fb27SDimitry Andric return; 119906c3fb27SDimitry Andric 120047395794SDimitry Andric // PR44896: Force DiscardValueNames as false. DiscardValueNames cannot be 120147395794SDimitry Andric // true here because the valued names are needed for reading textual IR. 120247395794SDimitry Andric Ctx.setDiscardValueNames(false); 1203480093f4SDimitry Andric Ctx.setDiagnosticHandler( 1204480093f4SDimitry Andric std::make_unique<ClangDiagnosticHandler>(CodeGenOpts, &Result)); 1205480093f4SDimitry Andric 1206*0fca6ea1SDimitry Andric Ctx.setDefaultTargetCPU(TargetOpts.CPU); 1207*0fca6ea1SDimitry Andric Ctx.setDefaultTargetFeatures(llvm::join(TargetOpts.Features, ",")); 1208*0fca6ea1SDimitry Andric 1209480093f4SDimitry Andric Expected<std::unique_ptr<llvm::ToolOutputFile>> OptRecordFileOrErr = 12105ffd83dbSDimitry Andric setupLLVMOptimizationRemarks( 1211480093f4SDimitry Andric Ctx, CodeGenOpts.OptRecordFile, CodeGenOpts.OptRecordPasses, 1212480093f4SDimitry Andric CodeGenOpts.OptRecordFormat, CodeGenOpts.DiagnosticsWithHotness, 1213480093f4SDimitry Andric CodeGenOpts.DiagnosticsHotnessThreshold); 1214480093f4SDimitry Andric 1215480093f4SDimitry Andric if (Error E = OptRecordFileOrErr.takeError()) { 1216480093f4SDimitry Andric reportOptRecordError(std::move(E), Diagnostics, CodeGenOpts); 1217480093f4SDimitry Andric return; 1218480093f4SDimitry Andric } 1219480093f4SDimitry Andric std::unique_ptr<llvm::ToolOutputFile> OptRecordFile = 1220480093f4SDimitry Andric std::move(*OptRecordFileOrErr); 1221480093f4SDimitry Andric 122206c3fb27SDimitry Andric EmitBackendOutput( 122306c3fb27SDimitry Andric Diagnostics, CI.getHeaderSearchOpts(), CodeGenOpts, TargetOpts, 122406c3fb27SDimitry Andric CI.getLangOpts(), CI.getTarget().getDataLayoutString(), TheModule.get(), 122506c3fb27SDimitry Andric BA, CI.getFileManager().getVirtualFileSystemPtr(), std::move(OS)); 1226480093f4SDimitry Andric if (OptRecordFile) 1227480093f4SDimitry Andric OptRecordFile->keep(); 12280b57cec5SDimitry Andric } 12290b57cec5SDimitry Andric 12300b57cec5SDimitry Andric // 12310b57cec5SDimitry Andric 12320b57cec5SDimitry Andric void EmitAssemblyAction::anchor() { } 12330b57cec5SDimitry Andric EmitAssemblyAction::EmitAssemblyAction(llvm::LLVMContext *_VMContext) 12340b57cec5SDimitry Andric : CodeGenAction(Backend_EmitAssembly, _VMContext) {} 12350b57cec5SDimitry Andric 12360b57cec5SDimitry Andric void EmitBCAction::anchor() { } 12370b57cec5SDimitry Andric EmitBCAction::EmitBCAction(llvm::LLVMContext *_VMContext) 12380b57cec5SDimitry Andric : CodeGenAction(Backend_EmitBC, _VMContext) {} 12390b57cec5SDimitry Andric 12400b57cec5SDimitry Andric void EmitLLVMAction::anchor() { } 12410b57cec5SDimitry Andric EmitLLVMAction::EmitLLVMAction(llvm::LLVMContext *_VMContext) 12420b57cec5SDimitry Andric : CodeGenAction(Backend_EmitLL, _VMContext) {} 12430b57cec5SDimitry Andric 12440b57cec5SDimitry Andric void EmitLLVMOnlyAction::anchor() { } 12450b57cec5SDimitry Andric EmitLLVMOnlyAction::EmitLLVMOnlyAction(llvm::LLVMContext *_VMContext) 12460b57cec5SDimitry Andric : CodeGenAction(Backend_EmitNothing, _VMContext) {} 12470b57cec5SDimitry Andric 12480b57cec5SDimitry Andric void EmitCodeGenOnlyAction::anchor() { } 12490b57cec5SDimitry Andric EmitCodeGenOnlyAction::EmitCodeGenOnlyAction(llvm::LLVMContext *_VMContext) 12500b57cec5SDimitry Andric : CodeGenAction(Backend_EmitMCNull, _VMContext) {} 12510b57cec5SDimitry Andric 12520b57cec5SDimitry Andric void EmitObjAction::anchor() { } 12530b57cec5SDimitry Andric EmitObjAction::EmitObjAction(llvm::LLVMContext *_VMContext) 12540b57cec5SDimitry Andric : CodeGenAction(Backend_EmitObj, _VMContext) {} 1255