17330f729Sjoerg //===--- CodeGenAction.cpp - LLVM Code Generation Frontend Action ---------===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg
97330f729Sjoerg #include "clang/CodeGen/CodeGenAction.h"
107330f729Sjoerg #include "CodeGenModule.h"
117330f729Sjoerg #include "CoverageMappingGen.h"
127330f729Sjoerg #include "MacroPPCallbacks.h"
137330f729Sjoerg #include "clang/AST/ASTConsumer.h"
147330f729Sjoerg #include "clang/AST/ASTContext.h"
157330f729Sjoerg #include "clang/AST/DeclCXX.h"
167330f729Sjoerg #include "clang/AST/DeclGroup.h"
177330f729Sjoerg #include "clang/Basic/DiagnosticFrontend.h"
187330f729Sjoerg #include "clang/Basic/FileManager.h"
197330f729Sjoerg #include "clang/Basic/LangStandard.h"
207330f729Sjoerg #include "clang/Basic/SourceManager.h"
217330f729Sjoerg #include "clang/Basic/TargetInfo.h"
227330f729Sjoerg #include "clang/CodeGen/BackendUtil.h"
237330f729Sjoerg #include "clang/CodeGen/ModuleBuilder.h"
247330f729Sjoerg #include "clang/Driver/DriverDiagnostic.h"
257330f729Sjoerg #include "clang/Frontend/CompilerInstance.h"
267330f729Sjoerg #include "clang/Frontend/FrontendDiagnostic.h"
277330f729Sjoerg #include "clang/Lex/Preprocessor.h"
287330f729Sjoerg #include "llvm/Bitcode/BitcodeReader.h"
297330f729Sjoerg #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
307330f729Sjoerg #include "llvm/IR/DebugInfo.h"
317330f729Sjoerg #include "llvm/IR/DiagnosticInfo.h"
327330f729Sjoerg #include "llvm/IR/DiagnosticPrinter.h"
337330f729Sjoerg #include "llvm/IR/GlobalValue.h"
347330f729Sjoerg #include "llvm/IR/LLVMContext.h"
35*e038c9c4Sjoerg #include "llvm/IR/LLVMRemarkStreamer.h"
367330f729Sjoerg #include "llvm/IR/Module.h"
377330f729Sjoerg #include "llvm/IRReader/IRReader.h"
38*e038c9c4Sjoerg #include "llvm/LTO/LTOBackend.h"
397330f729Sjoerg #include "llvm/Linker/Linker.h"
407330f729Sjoerg #include "llvm/Pass.h"
417330f729Sjoerg #include "llvm/Support/MemoryBuffer.h"
427330f729Sjoerg #include "llvm/Support/SourceMgr.h"
437330f729Sjoerg #include "llvm/Support/TimeProfiler.h"
447330f729Sjoerg #include "llvm/Support/Timer.h"
457330f729Sjoerg #include "llvm/Support/ToolOutputFile.h"
467330f729Sjoerg #include "llvm/Support/YAMLTraits.h"
477330f729Sjoerg #include "llvm/Transforms/IPO/Internalize.h"
487330f729Sjoerg
497330f729Sjoerg #include <memory>
507330f729Sjoerg using namespace clang;
517330f729Sjoerg using namespace llvm;
527330f729Sjoerg
537330f729Sjoerg namespace clang {
547330f729Sjoerg class BackendConsumer;
557330f729Sjoerg class ClangDiagnosticHandler final : public DiagnosticHandler {
567330f729Sjoerg public:
ClangDiagnosticHandler(const CodeGenOptions & CGOpts,BackendConsumer * BCon)577330f729Sjoerg ClangDiagnosticHandler(const CodeGenOptions &CGOpts, BackendConsumer *BCon)
587330f729Sjoerg : CodeGenOpts(CGOpts), BackendCon(BCon) {}
597330f729Sjoerg
607330f729Sjoerg bool handleDiagnostics(const DiagnosticInfo &DI) override;
617330f729Sjoerg
isAnalysisRemarkEnabled(StringRef PassName) const627330f729Sjoerg bool isAnalysisRemarkEnabled(StringRef PassName) const override {
63*e038c9c4Sjoerg return CodeGenOpts.OptimizationRemarkAnalysis.patternMatches(PassName);
647330f729Sjoerg }
isMissedOptRemarkEnabled(StringRef PassName) const657330f729Sjoerg bool isMissedOptRemarkEnabled(StringRef PassName) const override {
66*e038c9c4Sjoerg return CodeGenOpts.OptimizationRemarkMissed.patternMatches(PassName);
677330f729Sjoerg }
isPassedOptRemarkEnabled(StringRef PassName) const687330f729Sjoerg bool isPassedOptRemarkEnabled(StringRef PassName) const override {
69*e038c9c4Sjoerg return CodeGenOpts.OptimizationRemark.patternMatches(PassName);
707330f729Sjoerg }
717330f729Sjoerg
isAnyRemarkEnabled() const727330f729Sjoerg bool isAnyRemarkEnabled() const override {
73*e038c9c4Sjoerg return CodeGenOpts.OptimizationRemarkAnalysis.hasValidPattern() ||
74*e038c9c4Sjoerg CodeGenOpts.OptimizationRemarkMissed.hasValidPattern() ||
75*e038c9c4Sjoerg CodeGenOpts.OptimizationRemark.hasValidPattern();
767330f729Sjoerg }
777330f729Sjoerg
787330f729Sjoerg private:
797330f729Sjoerg const CodeGenOptions &CodeGenOpts;
807330f729Sjoerg BackendConsumer *BackendCon;
817330f729Sjoerg };
827330f729Sjoerg
reportOptRecordError(Error E,DiagnosticsEngine & Diags,const CodeGenOptions CodeGenOpts)83*e038c9c4Sjoerg static void reportOptRecordError(Error E, DiagnosticsEngine &Diags,
84*e038c9c4Sjoerg const CodeGenOptions CodeGenOpts) {
85*e038c9c4Sjoerg handleAllErrors(
86*e038c9c4Sjoerg std::move(E),
87*e038c9c4Sjoerg [&](const LLVMRemarkSetupFileError &E) {
88*e038c9c4Sjoerg Diags.Report(diag::err_cannot_open_file)
89*e038c9c4Sjoerg << CodeGenOpts.OptRecordFile << E.message();
90*e038c9c4Sjoerg },
91*e038c9c4Sjoerg [&](const LLVMRemarkSetupPatternError &E) {
92*e038c9c4Sjoerg Diags.Report(diag::err_drv_optimization_remark_pattern)
93*e038c9c4Sjoerg << E.message() << CodeGenOpts.OptRecordPasses;
94*e038c9c4Sjoerg },
95*e038c9c4Sjoerg [&](const LLVMRemarkSetupFormatError &E) {
96*e038c9c4Sjoerg Diags.Report(diag::err_drv_optimization_remark_format)
97*e038c9c4Sjoerg << CodeGenOpts.OptRecordFormat;
98*e038c9c4Sjoerg });
99*e038c9c4Sjoerg }
100*e038c9c4Sjoerg
1017330f729Sjoerg class BackendConsumer : public ASTConsumer {
1027330f729Sjoerg using LinkModule = CodeGenAction::LinkModule;
1037330f729Sjoerg
1047330f729Sjoerg virtual void anchor();
1057330f729Sjoerg DiagnosticsEngine &Diags;
1067330f729Sjoerg BackendAction Action;
1077330f729Sjoerg const HeaderSearchOptions &HeaderSearchOpts;
1087330f729Sjoerg const CodeGenOptions &CodeGenOpts;
1097330f729Sjoerg const TargetOptions &TargetOpts;
1107330f729Sjoerg const LangOptions &LangOpts;
1117330f729Sjoerg std::unique_ptr<raw_pwrite_stream> AsmOutStream;
1127330f729Sjoerg ASTContext *Context;
1137330f729Sjoerg
1147330f729Sjoerg Timer LLVMIRGeneration;
1157330f729Sjoerg unsigned LLVMIRGenerationRefCount;
1167330f729Sjoerg
1177330f729Sjoerg /// True if we've finished generating IR. This prevents us from generating
1187330f729Sjoerg /// additional LLVM IR after emitting output in HandleTranslationUnit. This
1197330f729Sjoerg /// can happen when Clang plugins trigger additional AST deserialization.
1207330f729Sjoerg bool IRGenFinished = false;
1217330f729Sjoerg
122*e038c9c4Sjoerg bool TimerIsEnabled = false;
123*e038c9c4Sjoerg
1247330f729Sjoerg std::unique_ptr<CodeGenerator> Gen;
1257330f729Sjoerg
1267330f729Sjoerg SmallVector<LinkModule, 4> LinkModules;
1277330f729Sjoerg
1287330f729Sjoerg // This is here so that the diagnostic printer knows the module a diagnostic
1297330f729Sjoerg // refers to.
1307330f729Sjoerg llvm::Module *CurLinkModule = nullptr;
1317330f729Sjoerg
1327330f729Sjoerg public:
BackendConsumer(BackendAction Action,DiagnosticsEngine & Diags,const HeaderSearchOptions & HeaderSearchOpts,const PreprocessorOptions & PPOpts,const CodeGenOptions & CodeGenOpts,const TargetOptions & TargetOpts,const LangOptions & LangOpts,const std::string & InFile,SmallVector<LinkModule,4> LinkModules,std::unique_ptr<raw_pwrite_stream> OS,LLVMContext & C,CoverageSourceInfo * CoverageInfo=nullptr)1337330f729Sjoerg BackendConsumer(BackendAction Action, DiagnosticsEngine &Diags,
1347330f729Sjoerg const HeaderSearchOptions &HeaderSearchOpts,
1357330f729Sjoerg const PreprocessorOptions &PPOpts,
1367330f729Sjoerg const CodeGenOptions &CodeGenOpts,
1377330f729Sjoerg const TargetOptions &TargetOpts,
138*e038c9c4Sjoerg const LangOptions &LangOpts, const std::string &InFile,
1397330f729Sjoerg SmallVector<LinkModule, 4> LinkModules,
1407330f729Sjoerg std::unique_ptr<raw_pwrite_stream> OS, LLVMContext &C,
1417330f729Sjoerg CoverageSourceInfo *CoverageInfo = nullptr)
1427330f729Sjoerg : Diags(Diags), Action(Action), HeaderSearchOpts(HeaderSearchOpts),
1437330f729Sjoerg CodeGenOpts(CodeGenOpts), TargetOpts(TargetOpts), LangOpts(LangOpts),
1447330f729Sjoerg AsmOutStream(std::move(OS)), Context(nullptr),
1457330f729Sjoerg LLVMIRGeneration("irgen", "LLVM IR Generation Time"),
1467330f729Sjoerg LLVMIRGenerationRefCount(0),
1477330f729Sjoerg Gen(CreateLLVMCodeGen(Diags, InFile, HeaderSearchOpts, PPOpts,
1487330f729Sjoerg CodeGenOpts, C, CoverageInfo)),
1497330f729Sjoerg LinkModules(std::move(LinkModules)) {
150*e038c9c4Sjoerg TimerIsEnabled = CodeGenOpts.TimePasses;
151*e038c9c4Sjoerg llvm::TimePassesIsEnabled = CodeGenOpts.TimePasses;
152*e038c9c4Sjoerg llvm::TimePassesPerRun = CodeGenOpts.TimePassesPerRun;
153*e038c9c4Sjoerg }
154*e038c9c4Sjoerg
155*e038c9c4Sjoerg // This constructor is used in installing an empty BackendConsumer
156*e038c9c4Sjoerg // to use the clang diagnostic handler for IR input files. It avoids
157*e038c9c4Sjoerg // initializing the OS field.
BackendConsumer(BackendAction Action,DiagnosticsEngine & Diags,const HeaderSearchOptions & HeaderSearchOpts,const PreprocessorOptions & PPOpts,const CodeGenOptions & CodeGenOpts,const TargetOptions & TargetOpts,const LangOptions & LangOpts,SmallVector<LinkModule,4> LinkModules,LLVMContext & C,CoverageSourceInfo * CoverageInfo=nullptr)158*e038c9c4Sjoerg BackendConsumer(BackendAction Action, DiagnosticsEngine &Diags,
159*e038c9c4Sjoerg const HeaderSearchOptions &HeaderSearchOpts,
160*e038c9c4Sjoerg const PreprocessorOptions &PPOpts,
161*e038c9c4Sjoerg const CodeGenOptions &CodeGenOpts,
162*e038c9c4Sjoerg const TargetOptions &TargetOpts,
163*e038c9c4Sjoerg const LangOptions &LangOpts,
164*e038c9c4Sjoerg SmallVector<LinkModule, 4> LinkModules, LLVMContext &C,
165*e038c9c4Sjoerg CoverageSourceInfo *CoverageInfo = nullptr)
166*e038c9c4Sjoerg : Diags(Diags), Action(Action), HeaderSearchOpts(HeaderSearchOpts),
167*e038c9c4Sjoerg CodeGenOpts(CodeGenOpts), TargetOpts(TargetOpts), LangOpts(LangOpts),
168*e038c9c4Sjoerg Context(nullptr),
169*e038c9c4Sjoerg LLVMIRGeneration("irgen", "LLVM IR Generation Time"),
170*e038c9c4Sjoerg LLVMIRGenerationRefCount(0),
171*e038c9c4Sjoerg Gen(CreateLLVMCodeGen(Diags, "", HeaderSearchOpts, PPOpts,
172*e038c9c4Sjoerg CodeGenOpts, C, CoverageInfo)),
173*e038c9c4Sjoerg LinkModules(std::move(LinkModules)) {
174*e038c9c4Sjoerg TimerIsEnabled = CodeGenOpts.TimePasses;
175*e038c9c4Sjoerg llvm::TimePassesIsEnabled = CodeGenOpts.TimePasses;
176*e038c9c4Sjoerg llvm::TimePassesPerRun = CodeGenOpts.TimePassesPerRun;
1777330f729Sjoerg }
getModule() const1787330f729Sjoerg llvm::Module *getModule() const { return Gen->GetModule(); }
takeModule()1797330f729Sjoerg std::unique_ptr<llvm::Module> takeModule() {
1807330f729Sjoerg return std::unique_ptr<llvm::Module>(Gen->ReleaseModule());
1817330f729Sjoerg }
1827330f729Sjoerg
getCodeGenerator()1837330f729Sjoerg CodeGenerator *getCodeGenerator() { return Gen.get(); }
1847330f729Sjoerg
HandleCXXStaticMemberVarInstantiation(VarDecl * VD)1857330f729Sjoerg void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override {
1867330f729Sjoerg Gen->HandleCXXStaticMemberVarInstantiation(VD);
1877330f729Sjoerg }
1887330f729Sjoerg
Initialize(ASTContext & Ctx)1897330f729Sjoerg void Initialize(ASTContext &Ctx) override {
1907330f729Sjoerg assert(!Context && "initialized multiple times");
1917330f729Sjoerg
1927330f729Sjoerg Context = &Ctx;
1937330f729Sjoerg
194*e038c9c4Sjoerg if (TimerIsEnabled)
1957330f729Sjoerg LLVMIRGeneration.startTimer();
1967330f729Sjoerg
1977330f729Sjoerg Gen->Initialize(Ctx);
1987330f729Sjoerg
199*e038c9c4Sjoerg if (TimerIsEnabled)
2007330f729Sjoerg LLVMIRGeneration.stopTimer();
2017330f729Sjoerg }
2027330f729Sjoerg
HandleTopLevelDecl(DeclGroupRef D)2037330f729Sjoerg bool HandleTopLevelDecl(DeclGroupRef D) override {
2047330f729Sjoerg PrettyStackTraceDecl CrashInfo(*D.begin(), SourceLocation(),
2057330f729Sjoerg Context->getSourceManager(),
2067330f729Sjoerg "LLVM IR generation of declaration");
2077330f729Sjoerg
2087330f729Sjoerg // Recurse.
209*e038c9c4Sjoerg if (TimerIsEnabled) {
2107330f729Sjoerg LLVMIRGenerationRefCount += 1;
2117330f729Sjoerg if (LLVMIRGenerationRefCount == 1)
2127330f729Sjoerg LLVMIRGeneration.startTimer();
2137330f729Sjoerg }
2147330f729Sjoerg
2157330f729Sjoerg Gen->HandleTopLevelDecl(D);
2167330f729Sjoerg
217*e038c9c4Sjoerg if (TimerIsEnabled) {
2187330f729Sjoerg LLVMIRGenerationRefCount -= 1;
2197330f729Sjoerg if (LLVMIRGenerationRefCount == 0)
2207330f729Sjoerg LLVMIRGeneration.stopTimer();
2217330f729Sjoerg }
2227330f729Sjoerg
2237330f729Sjoerg return true;
2247330f729Sjoerg }
2257330f729Sjoerg
HandleInlineFunctionDefinition(FunctionDecl * D)2267330f729Sjoerg void HandleInlineFunctionDefinition(FunctionDecl *D) override {
2277330f729Sjoerg PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
2287330f729Sjoerg Context->getSourceManager(),
2297330f729Sjoerg "LLVM IR generation of inline function");
230*e038c9c4Sjoerg if (TimerIsEnabled)
2317330f729Sjoerg LLVMIRGeneration.startTimer();
2327330f729Sjoerg
2337330f729Sjoerg Gen->HandleInlineFunctionDefinition(D);
2347330f729Sjoerg
235*e038c9c4Sjoerg if (TimerIsEnabled)
2367330f729Sjoerg LLVMIRGeneration.stopTimer();
2377330f729Sjoerg }
2387330f729Sjoerg
HandleInterestingDecl(DeclGroupRef D)2397330f729Sjoerg void HandleInterestingDecl(DeclGroupRef D) override {
2407330f729Sjoerg // Ignore interesting decls from the AST reader after IRGen is finished.
2417330f729Sjoerg if (!IRGenFinished)
2427330f729Sjoerg HandleTopLevelDecl(D);
2437330f729Sjoerg }
2447330f729Sjoerg
2457330f729Sjoerg // Links each entry in LinkModules into our module. Returns true on error.
LinkInModules()2467330f729Sjoerg bool LinkInModules() {
2477330f729Sjoerg for (auto &LM : LinkModules) {
2487330f729Sjoerg if (LM.PropagateAttrs)
249*e038c9c4Sjoerg for (Function &F : *LM.Module) {
250*e038c9c4Sjoerg // Skip intrinsics. Keep consistent with how intrinsics are created
251*e038c9c4Sjoerg // in LLVM IR.
252*e038c9c4Sjoerg if (F.isIntrinsic())
253*e038c9c4Sjoerg continue;
254*e038c9c4Sjoerg Gen->CGM().addDefaultFunctionDefinitionAttributes(F);
255*e038c9c4Sjoerg }
2567330f729Sjoerg
2577330f729Sjoerg CurLinkModule = LM.Module.get();
2587330f729Sjoerg
2597330f729Sjoerg bool Err;
2607330f729Sjoerg if (LM.Internalize) {
2617330f729Sjoerg Err = Linker::linkModules(
2627330f729Sjoerg *getModule(), std::move(LM.Module), LM.LinkFlags,
2637330f729Sjoerg [](llvm::Module &M, const llvm::StringSet<> &GVS) {
2647330f729Sjoerg internalizeModule(M, [&GVS](const llvm::GlobalValue &GV) {
2657330f729Sjoerg return !GV.hasName() || (GVS.count(GV.getName()) == 0);
2667330f729Sjoerg });
2677330f729Sjoerg });
2687330f729Sjoerg } else {
2697330f729Sjoerg Err = Linker::linkModules(*getModule(), std::move(LM.Module),
2707330f729Sjoerg LM.LinkFlags);
2717330f729Sjoerg }
2727330f729Sjoerg
2737330f729Sjoerg if (Err)
2747330f729Sjoerg return true;
2757330f729Sjoerg }
2767330f729Sjoerg return false; // success
2777330f729Sjoerg }
2787330f729Sjoerg
HandleTranslationUnit(ASTContext & C)2797330f729Sjoerg void HandleTranslationUnit(ASTContext &C) override {
2807330f729Sjoerg {
281*e038c9c4Sjoerg llvm::TimeTraceScope TimeScope("Frontend");
2827330f729Sjoerg PrettyStackTraceString CrashInfo("Per-file LLVM IR generation");
283*e038c9c4Sjoerg if (TimerIsEnabled) {
2847330f729Sjoerg LLVMIRGenerationRefCount += 1;
2857330f729Sjoerg if (LLVMIRGenerationRefCount == 1)
2867330f729Sjoerg LLVMIRGeneration.startTimer();
2877330f729Sjoerg }
2887330f729Sjoerg
2897330f729Sjoerg Gen->HandleTranslationUnit(C);
2907330f729Sjoerg
291*e038c9c4Sjoerg if (TimerIsEnabled) {
2927330f729Sjoerg LLVMIRGenerationRefCount -= 1;
2937330f729Sjoerg if (LLVMIRGenerationRefCount == 0)
2947330f729Sjoerg LLVMIRGeneration.stopTimer();
2957330f729Sjoerg }
2967330f729Sjoerg
2977330f729Sjoerg IRGenFinished = true;
2987330f729Sjoerg }
2997330f729Sjoerg
3007330f729Sjoerg // Silently ignore if we weren't initialized for some reason.
3017330f729Sjoerg if (!getModule())
3027330f729Sjoerg return;
3037330f729Sjoerg
3047330f729Sjoerg LLVMContext &Ctx = getModule()->getContext();
3057330f729Sjoerg std::unique_ptr<DiagnosticHandler> OldDiagnosticHandler =
3067330f729Sjoerg Ctx.getDiagnosticHandler();
3077330f729Sjoerg Ctx.setDiagnosticHandler(std::make_unique<ClangDiagnosticHandler>(
3087330f729Sjoerg CodeGenOpts, this));
3097330f729Sjoerg
3107330f729Sjoerg Expected<std::unique_ptr<llvm::ToolOutputFile>> OptRecordFileOrErr =
311*e038c9c4Sjoerg setupLLVMOptimizationRemarks(
312*e038c9c4Sjoerg Ctx, CodeGenOpts.OptRecordFile, CodeGenOpts.OptRecordPasses,
313*e038c9c4Sjoerg CodeGenOpts.OptRecordFormat, CodeGenOpts.DiagnosticsWithHotness,
3147330f729Sjoerg CodeGenOpts.DiagnosticsHotnessThreshold);
3157330f729Sjoerg
3167330f729Sjoerg if (Error E = OptRecordFileOrErr.takeError()) {
317*e038c9c4Sjoerg reportOptRecordError(std::move(E), Diags, CodeGenOpts);
3187330f729Sjoerg return;
3197330f729Sjoerg }
320*e038c9c4Sjoerg
3217330f729Sjoerg std::unique_ptr<llvm::ToolOutputFile> OptRecordFile =
3227330f729Sjoerg std::move(*OptRecordFileOrErr);
3237330f729Sjoerg
3247330f729Sjoerg if (OptRecordFile &&
3257330f729Sjoerg CodeGenOpts.getProfileUse() != CodeGenOptions::ProfileNone)
3267330f729Sjoerg Ctx.setDiagnosticsHotnessRequested(true);
3277330f729Sjoerg
3287330f729Sjoerg // Link each LinkModule into our module.
3297330f729Sjoerg if (LinkInModules())
3307330f729Sjoerg return;
3317330f729Sjoerg
3327330f729Sjoerg EmbedBitcode(getModule(), CodeGenOpts, llvm::MemoryBufferRef());
3337330f729Sjoerg
3347330f729Sjoerg EmitBackendOutput(Diags, HeaderSearchOpts, CodeGenOpts, TargetOpts,
335*e038c9c4Sjoerg LangOpts, C.getTargetInfo().getDataLayoutString(),
3367330f729Sjoerg getModule(), Action, std::move(AsmOutStream));
3377330f729Sjoerg
3387330f729Sjoerg Ctx.setDiagnosticHandler(std::move(OldDiagnosticHandler));
3397330f729Sjoerg
3407330f729Sjoerg if (OptRecordFile)
3417330f729Sjoerg OptRecordFile->keep();
3427330f729Sjoerg }
3437330f729Sjoerg
HandleTagDeclDefinition(TagDecl * D)3447330f729Sjoerg void HandleTagDeclDefinition(TagDecl *D) override {
3457330f729Sjoerg PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
3467330f729Sjoerg Context->getSourceManager(),
3477330f729Sjoerg "LLVM IR generation of declaration");
3487330f729Sjoerg Gen->HandleTagDeclDefinition(D);
3497330f729Sjoerg }
3507330f729Sjoerg
HandleTagDeclRequiredDefinition(const TagDecl * D)3517330f729Sjoerg void HandleTagDeclRequiredDefinition(const TagDecl *D) override {
3527330f729Sjoerg Gen->HandleTagDeclRequiredDefinition(D);
3537330f729Sjoerg }
3547330f729Sjoerg
CompleteTentativeDefinition(VarDecl * D)3557330f729Sjoerg void CompleteTentativeDefinition(VarDecl *D) override {
3567330f729Sjoerg Gen->CompleteTentativeDefinition(D);
3577330f729Sjoerg }
3587330f729Sjoerg
CompleteExternalDeclaration(VarDecl * D)359*e038c9c4Sjoerg void CompleteExternalDeclaration(VarDecl *D) override {
360*e038c9c4Sjoerg Gen->CompleteExternalDeclaration(D);
361*e038c9c4Sjoerg }
362*e038c9c4Sjoerg
AssignInheritanceModel(CXXRecordDecl * RD)3637330f729Sjoerg void AssignInheritanceModel(CXXRecordDecl *RD) override {
3647330f729Sjoerg Gen->AssignInheritanceModel(RD);
3657330f729Sjoerg }
3667330f729Sjoerg
HandleVTable(CXXRecordDecl * RD)3677330f729Sjoerg void HandleVTable(CXXRecordDecl *RD) override {
3687330f729Sjoerg Gen->HandleVTable(RD);
3697330f729Sjoerg }
3707330f729Sjoerg
3717330f729Sjoerg /// Get the best possible source location to represent a diagnostic that
3727330f729Sjoerg /// may have associated debug info.
3737330f729Sjoerg const FullSourceLoc
3747330f729Sjoerg getBestLocationFromDebugLoc(const llvm::DiagnosticInfoWithLocationBase &D,
3757330f729Sjoerg bool &BadDebugInfo, StringRef &Filename,
3767330f729Sjoerg unsigned &Line, unsigned &Column) const;
3777330f729Sjoerg
3787330f729Sjoerg void DiagnosticHandlerImpl(const llvm::DiagnosticInfo &DI);
3797330f729Sjoerg /// Specialized handler for InlineAsm diagnostic.
3807330f729Sjoerg /// \return True if the diagnostic has been successfully reported, false
3817330f729Sjoerg /// otherwise.
3827330f729Sjoerg bool InlineAsmDiagHandler(const llvm::DiagnosticInfoInlineAsm &D);
383*e038c9c4Sjoerg /// Specialized handler for diagnostics reported using SMDiagnostic.
384*e038c9c4Sjoerg void SrcMgrDiagHandler(const llvm::DiagnosticInfoSrcMgr &D);
3857330f729Sjoerg /// Specialized handler for StackSize diagnostic.
3867330f729Sjoerg /// \return True if the diagnostic has been successfully reported, false
3877330f729Sjoerg /// otherwise.
3887330f729Sjoerg bool StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D);
3897330f729Sjoerg /// Specialized handler for unsupported backend feature diagnostic.
3907330f729Sjoerg void UnsupportedDiagHandler(const llvm::DiagnosticInfoUnsupported &D);
3917330f729Sjoerg /// Specialized handlers for optimization remarks.
3927330f729Sjoerg /// Note that these handlers only accept remarks and they always handle
3937330f729Sjoerg /// them.
3947330f729Sjoerg void EmitOptimizationMessage(const llvm::DiagnosticInfoOptimizationBase &D,
3957330f729Sjoerg unsigned DiagID);
3967330f729Sjoerg void
3977330f729Sjoerg OptimizationRemarkHandler(const llvm::DiagnosticInfoOptimizationBase &D);
3987330f729Sjoerg void OptimizationRemarkHandler(
3997330f729Sjoerg const llvm::OptimizationRemarkAnalysisFPCommute &D);
4007330f729Sjoerg void OptimizationRemarkHandler(
4017330f729Sjoerg const llvm::OptimizationRemarkAnalysisAliasing &D);
4027330f729Sjoerg void OptimizationFailureHandler(
4037330f729Sjoerg const llvm::DiagnosticInfoOptimizationFailure &D);
4047330f729Sjoerg };
4057330f729Sjoerg
anchor()4067330f729Sjoerg void BackendConsumer::anchor() {}
4077330f729Sjoerg }
4087330f729Sjoerg
handleDiagnostics(const DiagnosticInfo & DI)4097330f729Sjoerg bool ClangDiagnosticHandler::handleDiagnostics(const DiagnosticInfo &DI) {
4107330f729Sjoerg BackendCon->DiagnosticHandlerImpl(DI);
4117330f729Sjoerg return true;
4127330f729Sjoerg }
4137330f729Sjoerg
4147330f729Sjoerg /// ConvertBackendLocation - Convert a location in a temporary llvm::SourceMgr
4157330f729Sjoerg /// buffer to be a valid FullSourceLoc.
ConvertBackendLocation(const llvm::SMDiagnostic & D,SourceManager & CSM)4167330f729Sjoerg static FullSourceLoc ConvertBackendLocation(const llvm::SMDiagnostic &D,
4177330f729Sjoerg SourceManager &CSM) {
4187330f729Sjoerg // Get both the clang and llvm source managers. The location is relative to
4197330f729Sjoerg // a memory buffer that the LLVM Source Manager is handling, we need to add
4207330f729Sjoerg // a copy to the Clang source manager.
4217330f729Sjoerg const llvm::SourceMgr &LSM = *D.getSourceMgr();
4227330f729Sjoerg
4237330f729Sjoerg // We need to copy the underlying LLVM memory buffer because llvm::SourceMgr
4247330f729Sjoerg // already owns its one and clang::SourceManager wants to own its one.
4257330f729Sjoerg const MemoryBuffer *LBuf =
4267330f729Sjoerg LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc()));
4277330f729Sjoerg
4287330f729Sjoerg // Create the copy and transfer ownership to clang::SourceManager.
4297330f729Sjoerg // TODO: Avoid copying files into memory.
4307330f729Sjoerg std::unique_ptr<llvm::MemoryBuffer> CBuf =
4317330f729Sjoerg llvm::MemoryBuffer::getMemBufferCopy(LBuf->getBuffer(),
4327330f729Sjoerg LBuf->getBufferIdentifier());
4337330f729Sjoerg // FIXME: Keep a file ID map instead of creating new IDs for each location.
4347330f729Sjoerg FileID FID = CSM.createFileID(std::move(CBuf));
4357330f729Sjoerg
4367330f729Sjoerg // Translate the offset into the file.
4377330f729Sjoerg unsigned Offset = D.getLoc().getPointer() - LBuf->getBufferStart();
4387330f729Sjoerg SourceLocation NewLoc =
4397330f729Sjoerg CSM.getLocForStartOfFile(FID).getLocWithOffset(Offset);
4407330f729Sjoerg return FullSourceLoc(NewLoc, CSM);
4417330f729Sjoerg }
4427330f729Sjoerg
4437330f729Sjoerg #define ComputeDiagID(Severity, GroupName, DiagID) \
4447330f729Sjoerg do { \
4457330f729Sjoerg switch (Severity) { \
4467330f729Sjoerg case llvm::DS_Error: \
4477330f729Sjoerg DiagID = diag::err_fe_##GroupName; \
4487330f729Sjoerg break; \
4497330f729Sjoerg case llvm::DS_Warning: \
4507330f729Sjoerg DiagID = diag::warn_fe_##GroupName; \
4517330f729Sjoerg break; \
4527330f729Sjoerg case llvm::DS_Remark: \
4537330f729Sjoerg llvm_unreachable("'remark' severity not expected"); \
4547330f729Sjoerg break; \
4557330f729Sjoerg case llvm::DS_Note: \
4567330f729Sjoerg DiagID = diag::note_fe_##GroupName; \
4577330f729Sjoerg break; \
4587330f729Sjoerg } \
4597330f729Sjoerg } while (false)
4607330f729Sjoerg
4617330f729Sjoerg #define ComputeDiagRemarkID(Severity, GroupName, DiagID) \
4627330f729Sjoerg do { \
4637330f729Sjoerg switch (Severity) { \
4647330f729Sjoerg case llvm::DS_Error: \
4657330f729Sjoerg DiagID = diag::err_fe_##GroupName; \
4667330f729Sjoerg break; \
4677330f729Sjoerg case llvm::DS_Warning: \
4687330f729Sjoerg DiagID = diag::warn_fe_##GroupName; \
4697330f729Sjoerg break; \
4707330f729Sjoerg case llvm::DS_Remark: \
4717330f729Sjoerg DiagID = diag::remark_fe_##GroupName; \
4727330f729Sjoerg break; \
4737330f729Sjoerg case llvm::DS_Note: \
4747330f729Sjoerg DiagID = diag::note_fe_##GroupName; \
4757330f729Sjoerg break; \
4767330f729Sjoerg } \
4777330f729Sjoerg } while (false)
4787330f729Sjoerg
SrcMgrDiagHandler(const llvm::DiagnosticInfoSrcMgr & DI)479*e038c9c4Sjoerg void BackendConsumer::SrcMgrDiagHandler(const llvm::DiagnosticInfoSrcMgr &DI) {
480*e038c9c4Sjoerg const llvm::SMDiagnostic &D = DI.getSMDiag();
481*e038c9c4Sjoerg
482*e038c9c4Sjoerg unsigned DiagID;
483*e038c9c4Sjoerg if (DI.isInlineAsmDiag())
484*e038c9c4Sjoerg ComputeDiagID(DI.getSeverity(), inline_asm, DiagID);
485*e038c9c4Sjoerg else
486*e038c9c4Sjoerg ComputeDiagID(DI.getSeverity(), source_mgr, DiagID);
487*e038c9c4Sjoerg
488*e038c9c4Sjoerg // This is for the empty BackendConsumer that uses the clang diagnostic
489*e038c9c4Sjoerg // handler for IR input files.
490*e038c9c4Sjoerg if (!Context) {
491*e038c9c4Sjoerg D.print(nullptr, llvm::errs());
492*e038c9c4Sjoerg Diags.Report(DiagID).AddString("cannot compile inline asm");
493*e038c9c4Sjoerg return;
494*e038c9c4Sjoerg }
495*e038c9c4Sjoerg
496*e038c9c4Sjoerg // There are a couple of different kinds of errors we could get here.
497*e038c9c4Sjoerg // First, we re-format the SMDiagnostic in terms of a clang diagnostic.
498*e038c9c4Sjoerg
499*e038c9c4Sjoerg // Strip "error: " off the start of the message string.
500*e038c9c4Sjoerg StringRef Message = D.getMessage();
501*e038c9c4Sjoerg (void)Message.consume_front("error: ");
502*e038c9c4Sjoerg
503*e038c9c4Sjoerg // If the SMDiagnostic has an inline asm source location, translate it.
504*e038c9c4Sjoerg FullSourceLoc Loc;
505*e038c9c4Sjoerg if (D.getLoc() != SMLoc())
506*e038c9c4Sjoerg Loc = ConvertBackendLocation(D, Context->getSourceManager());
507*e038c9c4Sjoerg
508*e038c9c4Sjoerg // If this problem has clang-level source location information, report the
509*e038c9c4Sjoerg // issue in the source with a note showing the instantiated
510*e038c9c4Sjoerg // code.
511*e038c9c4Sjoerg if (DI.isInlineAsmDiag()) {
512*e038c9c4Sjoerg SourceLocation LocCookie =
513*e038c9c4Sjoerg SourceLocation::getFromRawEncoding(DI.getLocCookie());
514*e038c9c4Sjoerg if (LocCookie.isValid()) {
515*e038c9c4Sjoerg Diags.Report(LocCookie, DiagID).AddString(Message);
516*e038c9c4Sjoerg
517*e038c9c4Sjoerg if (D.getLoc().isValid()) {
518*e038c9c4Sjoerg DiagnosticBuilder B = Diags.Report(Loc, diag::note_fe_inline_asm_here);
519*e038c9c4Sjoerg // Convert the SMDiagnostic ranges into SourceRange and attach them
520*e038c9c4Sjoerg // to the diagnostic.
521*e038c9c4Sjoerg for (const std::pair<unsigned, unsigned> &Range : D.getRanges()) {
522*e038c9c4Sjoerg unsigned Column = D.getColumnNo();
523*e038c9c4Sjoerg B << SourceRange(Loc.getLocWithOffset(Range.first - Column),
524*e038c9c4Sjoerg Loc.getLocWithOffset(Range.second - Column));
525*e038c9c4Sjoerg }
526*e038c9c4Sjoerg }
527*e038c9c4Sjoerg return;
528*e038c9c4Sjoerg }
529*e038c9c4Sjoerg }
530*e038c9c4Sjoerg
531*e038c9c4Sjoerg // Otherwise, report the backend issue as occurring in the generated .s file.
532*e038c9c4Sjoerg // If Loc is invalid, we still need to report the issue, it just gets no
533*e038c9c4Sjoerg // location info.
534*e038c9c4Sjoerg Diags.Report(Loc, DiagID).AddString(Message);
535*e038c9c4Sjoerg return;
536*e038c9c4Sjoerg }
537*e038c9c4Sjoerg
5387330f729Sjoerg bool
InlineAsmDiagHandler(const llvm::DiagnosticInfoInlineAsm & D)5397330f729Sjoerg BackendConsumer::InlineAsmDiagHandler(const llvm::DiagnosticInfoInlineAsm &D) {
5407330f729Sjoerg unsigned DiagID;
5417330f729Sjoerg ComputeDiagID(D.getSeverity(), inline_asm, DiagID);
5427330f729Sjoerg std::string Message = D.getMsgStr().str();
5437330f729Sjoerg
5447330f729Sjoerg // If this problem has clang-level source location information, report the
5457330f729Sjoerg // issue as being a problem in the source with a note showing the instantiated
5467330f729Sjoerg // code.
5477330f729Sjoerg SourceLocation LocCookie =
5487330f729Sjoerg SourceLocation::getFromRawEncoding(D.getLocCookie());
5497330f729Sjoerg if (LocCookie.isValid())
5507330f729Sjoerg Diags.Report(LocCookie, DiagID).AddString(Message);
5517330f729Sjoerg else {
5527330f729Sjoerg // Otherwise, report the backend diagnostic as occurring in the generated
5537330f729Sjoerg // .s file.
5547330f729Sjoerg // If Loc is invalid, we still need to report the diagnostic, it just gets
5557330f729Sjoerg // no location info.
5567330f729Sjoerg FullSourceLoc Loc;
5577330f729Sjoerg Diags.Report(Loc, DiagID).AddString(Message);
5587330f729Sjoerg }
5597330f729Sjoerg // We handled all the possible severities.
5607330f729Sjoerg return true;
5617330f729Sjoerg }
5627330f729Sjoerg
5637330f729Sjoerg bool
StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize & D)5647330f729Sjoerg BackendConsumer::StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D) {
5657330f729Sjoerg if (D.getSeverity() != llvm::DS_Warning)
5667330f729Sjoerg // For now, the only support we have for StackSize diagnostic is warning.
5677330f729Sjoerg // We do not know how to format other severities.
5687330f729Sjoerg return false;
5697330f729Sjoerg
5707330f729Sjoerg if (const Decl *ND = Gen->GetDeclForMangledName(D.getFunction().getName())) {
5717330f729Sjoerg // FIXME: Shouldn't need to truncate to uint32_t
5727330f729Sjoerg Diags.Report(ND->getASTContext().getFullLoc(ND->getLocation()),
5737330f729Sjoerg diag::warn_fe_frame_larger_than)
5747330f729Sjoerg << static_cast<uint32_t>(D.getStackSize()) << Decl::castToDeclContext(ND);
5757330f729Sjoerg return true;
5767330f729Sjoerg }
5777330f729Sjoerg
5787330f729Sjoerg return false;
5797330f729Sjoerg }
5807330f729Sjoerg
getBestLocationFromDebugLoc(const llvm::DiagnosticInfoWithLocationBase & D,bool & BadDebugInfo,StringRef & Filename,unsigned & Line,unsigned & Column) const5817330f729Sjoerg const FullSourceLoc BackendConsumer::getBestLocationFromDebugLoc(
5827330f729Sjoerg const llvm::DiagnosticInfoWithLocationBase &D, bool &BadDebugInfo,
5837330f729Sjoerg StringRef &Filename, unsigned &Line, unsigned &Column) const {
5847330f729Sjoerg SourceManager &SourceMgr = Context->getSourceManager();
5857330f729Sjoerg FileManager &FileMgr = SourceMgr.getFileManager();
5867330f729Sjoerg SourceLocation DILoc;
5877330f729Sjoerg
5887330f729Sjoerg if (D.isLocationAvailable()) {
5897330f729Sjoerg D.getLocation(Filename, Line, Column);
5907330f729Sjoerg if (Line > 0) {
5917330f729Sjoerg auto FE = FileMgr.getFile(Filename);
5927330f729Sjoerg if (!FE)
5937330f729Sjoerg FE = FileMgr.getFile(D.getAbsolutePath());
5947330f729Sjoerg if (FE) {
5957330f729Sjoerg // If -gcolumn-info was not used, Column will be 0. This upsets the
5967330f729Sjoerg // source manager, so pass 1 if Column is not set.
5977330f729Sjoerg DILoc = SourceMgr.translateFileLineCol(*FE, Line, Column ? Column : 1);
5987330f729Sjoerg }
5997330f729Sjoerg }
6007330f729Sjoerg BadDebugInfo = DILoc.isInvalid();
6017330f729Sjoerg }
6027330f729Sjoerg
6037330f729Sjoerg // If a location isn't available, try to approximate it using the associated
6047330f729Sjoerg // function definition. We use the definition's right brace to differentiate
6057330f729Sjoerg // from diagnostics that genuinely relate to the function itself.
6067330f729Sjoerg FullSourceLoc Loc(DILoc, SourceMgr);
6077330f729Sjoerg if (Loc.isInvalid())
6087330f729Sjoerg if (const Decl *FD = Gen->GetDeclForMangledName(D.getFunction().getName()))
6097330f729Sjoerg Loc = FD->getASTContext().getFullLoc(FD->getLocation());
6107330f729Sjoerg
6117330f729Sjoerg if (DILoc.isInvalid() && D.isLocationAvailable())
6127330f729Sjoerg // If we were not able to translate the file:line:col information
6137330f729Sjoerg // back to a SourceLocation, at least emit a note stating that
6147330f729Sjoerg // we could not translate this location. This can happen in the
6157330f729Sjoerg // case of #line directives.
6167330f729Sjoerg Diags.Report(Loc, diag::note_fe_backend_invalid_loc)
6177330f729Sjoerg << Filename << Line << Column;
6187330f729Sjoerg
6197330f729Sjoerg return Loc;
6207330f729Sjoerg }
6217330f729Sjoerg
UnsupportedDiagHandler(const llvm::DiagnosticInfoUnsupported & D)6227330f729Sjoerg void BackendConsumer::UnsupportedDiagHandler(
6237330f729Sjoerg const llvm::DiagnosticInfoUnsupported &D) {
624*e038c9c4Sjoerg // We only support warnings or errors.
625*e038c9c4Sjoerg assert(D.getSeverity() == llvm::DS_Error ||
626*e038c9c4Sjoerg D.getSeverity() == llvm::DS_Warning);
6277330f729Sjoerg
6287330f729Sjoerg StringRef Filename;
6297330f729Sjoerg unsigned Line, Column;
6307330f729Sjoerg bool BadDebugInfo = false;
631*e038c9c4Sjoerg FullSourceLoc Loc;
632*e038c9c4Sjoerg std::string Msg;
633*e038c9c4Sjoerg raw_string_ostream MsgStream(Msg);
6347330f729Sjoerg
635*e038c9c4Sjoerg // Context will be nullptr for IR input files, we will construct the diag
636*e038c9c4Sjoerg // message from llvm::DiagnosticInfoUnsupported.
637*e038c9c4Sjoerg if (Context != nullptr) {
638*e038c9c4Sjoerg Loc = getBestLocationFromDebugLoc(D, BadDebugInfo, Filename, Line, Column);
639*e038c9c4Sjoerg MsgStream << D.getMessage();
640*e038c9c4Sjoerg } else {
641*e038c9c4Sjoerg DiagnosticPrinterRawOStream DP(MsgStream);
642*e038c9c4Sjoerg D.print(DP);
6437330f729Sjoerg }
6447330f729Sjoerg
645*e038c9c4Sjoerg auto DiagType = D.getSeverity() == llvm::DS_Error
646*e038c9c4Sjoerg ? diag::err_fe_backend_unsupported
647*e038c9c4Sjoerg : diag::warn_fe_backend_unsupported;
648*e038c9c4Sjoerg Diags.Report(Loc, DiagType) << MsgStream.str();
6497330f729Sjoerg
6507330f729Sjoerg if (BadDebugInfo)
6517330f729Sjoerg // If we were not able to translate the file:line:col information
6527330f729Sjoerg // back to a SourceLocation, at least emit a note stating that
6537330f729Sjoerg // we could not translate this location. This can happen in the
6547330f729Sjoerg // case of #line directives.
6557330f729Sjoerg Diags.Report(Loc, diag::note_fe_backend_invalid_loc)
6567330f729Sjoerg << Filename << Line << Column;
6577330f729Sjoerg }
6587330f729Sjoerg
EmitOptimizationMessage(const llvm::DiagnosticInfoOptimizationBase & D,unsigned DiagID)6597330f729Sjoerg void BackendConsumer::EmitOptimizationMessage(
6607330f729Sjoerg const llvm::DiagnosticInfoOptimizationBase &D, unsigned DiagID) {
6617330f729Sjoerg // We only support warnings and remarks.
6627330f729Sjoerg assert(D.getSeverity() == llvm::DS_Remark ||
6637330f729Sjoerg D.getSeverity() == llvm::DS_Warning);
6647330f729Sjoerg
6657330f729Sjoerg StringRef Filename;
6667330f729Sjoerg unsigned Line, Column;
6677330f729Sjoerg bool BadDebugInfo = false;
668*e038c9c4Sjoerg FullSourceLoc Loc;
6697330f729Sjoerg std::string Msg;
6707330f729Sjoerg raw_string_ostream MsgStream(Msg);
671*e038c9c4Sjoerg
672*e038c9c4Sjoerg // Context will be nullptr for IR input files, we will construct the remark
673*e038c9c4Sjoerg // message from llvm::DiagnosticInfoOptimizationBase.
674*e038c9c4Sjoerg if (Context != nullptr) {
675*e038c9c4Sjoerg Loc = getBestLocationFromDebugLoc(D, BadDebugInfo, Filename, Line, Column);
6767330f729Sjoerg MsgStream << D.getMsg();
677*e038c9c4Sjoerg } else {
678*e038c9c4Sjoerg DiagnosticPrinterRawOStream DP(MsgStream);
679*e038c9c4Sjoerg D.print(DP);
680*e038c9c4Sjoerg }
6817330f729Sjoerg
6827330f729Sjoerg if (D.getHotness())
6837330f729Sjoerg MsgStream << " (hotness: " << *D.getHotness() << ")";
6847330f729Sjoerg
6857330f729Sjoerg Diags.Report(Loc, DiagID)
6867330f729Sjoerg << AddFlagValue(D.getPassName())
6877330f729Sjoerg << MsgStream.str();
6887330f729Sjoerg
6897330f729Sjoerg if (BadDebugInfo)
6907330f729Sjoerg // If we were not able to translate the file:line:col information
6917330f729Sjoerg // back to a SourceLocation, at least emit a note stating that
6927330f729Sjoerg // we could not translate this location. This can happen in the
6937330f729Sjoerg // case of #line directives.
6947330f729Sjoerg Diags.Report(Loc, diag::note_fe_backend_invalid_loc)
6957330f729Sjoerg << Filename << Line << Column;
6967330f729Sjoerg }
6977330f729Sjoerg
OptimizationRemarkHandler(const llvm::DiagnosticInfoOptimizationBase & D)6987330f729Sjoerg void BackendConsumer::OptimizationRemarkHandler(
6997330f729Sjoerg const llvm::DiagnosticInfoOptimizationBase &D) {
7007330f729Sjoerg // Without hotness information, don't show noisy remarks.
7017330f729Sjoerg if (D.isVerbose() && !D.getHotness())
7027330f729Sjoerg return;
7037330f729Sjoerg
7047330f729Sjoerg if (D.isPassed()) {
7057330f729Sjoerg // Optimization remarks are active only if the -Rpass flag has a regular
7067330f729Sjoerg // expression that matches the name of the pass name in \p D.
707*e038c9c4Sjoerg if (CodeGenOpts.OptimizationRemark.patternMatches(D.getPassName()))
7087330f729Sjoerg EmitOptimizationMessage(D, diag::remark_fe_backend_optimization_remark);
7097330f729Sjoerg } else if (D.isMissed()) {
7107330f729Sjoerg // Missed optimization remarks are active only if the -Rpass-missed
7117330f729Sjoerg // flag has a regular expression that matches the name of the pass
7127330f729Sjoerg // name in \p D.
713*e038c9c4Sjoerg if (CodeGenOpts.OptimizationRemarkMissed.patternMatches(D.getPassName()))
7147330f729Sjoerg EmitOptimizationMessage(
7157330f729Sjoerg D, diag::remark_fe_backend_optimization_remark_missed);
7167330f729Sjoerg } else {
7177330f729Sjoerg assert(D.isAnalysis() && "Unknown remark type");
7187330f729Sjoerg
7197330f729Sjoerg bool ShouldAlwaysPrint = false;
7207330f729Sjoerg if (auto *ORA = dyn_cast<llvm::OptimizationRemarkAnalysis>(&D))
7217330f729Sjoerg ShouldAlwaysPrint = ORA->shouldAlwaysPrint();
7227330f729Sjoerg
7237330f729Sjoerg if (ShouldAlwaysPrint ||
724*e038c9c4Sjoerg CodeGenOpts.OptimizationRemarkAnalysis.patternMatches(D.getPassName()))
7257330f729Sjoerg EmitOptimizationMessage(
7267330f729Sjoerg D, diag::remark_fe_backend_optimization_remark_analysis);
7277330f729Sjoerg }
7287330f729Sjoerg }
7297330f729Sjoerg
OptimizationRemarkHandler(const llvm::OptimizationRemarkAnalysisFPCommute & D)7307330f729Sjoerg void BackendConsumer::OptimizationRemarkHandler(
7317330f729Sjoerg const llvm::OptimizationRemarkAnalysisFPCommute &D) {
7327330f729Sjoerg // Optimization analysis remarks are active if the pass name is set to
7337330f729Sjoerg // llvm::DiagnosticInfo::AlwasyPrint or if the -Rpass-analysis flag has a
7347330f729Sjoerg // regular expression that matches the name of the pass name in \p D.
7357330f729Sjoerg
7367330f729Sjoerg if (D.shouldAlwaysPrint() ||
737*e038c9c4Sjoerg CodeGenOpts.OptimizationRemarkAnalysis.patternMatches(D.getPassName()))
7387330f729Sjoerg EmitOptimizationMessage(
7397330f729Sjoerg D, diag::remark_fe_backend_optimization_remark_analysis_fpcommute);
7407330f729Sjoerg }
7417330f729Sjoerg
OptimizationRemarkHandler(const llvm::OptimizationRemarkAnalysisAliasing & D)7427330f729Sjoerg void BackendConsumer::OptimizationRemarkHandler(
7437330f729Sjoerg const llvm::OptimizationRemarkAnalysisAliasing &D) {
7447330f729Sjoerg // Optimization analysis remarks are active if the pass name is set to
7457330f729Sjoerg // llvm::DiagnosticInfo::AlwasyPrint or if the -Rpass-analysis flag has a
7467330f729Sjoerg // regular expression that matches the name of the pass name in \p D.
7477330f729Sjoerg
7487330f729Sjoerg if (D.shouldAlwaysPrint() ||
749*e038c9c4Sjoerg CodeGenOpts.OptimizationRemarkAnalysis.patternMatches(D.getPassName()))
7507330f729Sjoerg EmitOptimizationMessage(
7517330f729Sjoerg D, diag::remark_fe_backend_optimization_remark_analysis_aliasing);
7527330f729Sjoerg }
7537330f729Sjoerg
OptimizationFailureHandler(const llvm::DiagnosticInfoOptimizationFailure & D)7547330f729Sjoerg void BackendConsumer::OptimizationFailureHandler(
7557330f729Sjoerg const llvm::DiagnosticInfoOptimizationFailure &D) {
7567330f729Sjoerg EmitOptimizationMessage(D, diag::warn_fe_backend_optimization_failure);
7577330f729Sjoerg }
7587330f729Sjoerg
7597330f729Sjoerg /// This function is invoked when the backend needs
7607330f729Sjoerg /// to report something to the user.
DiagnosticHandlerImpl(const DiagnosticInfo & DI)7617330f729Sjoerg void BackendConsumer::DiagnosticHandlerImpl(const DiagnosticInfo &DI) {
7627330f729Sjoerg unsigned DiagID = diag::err_fe_inline_asm;
7637330f729Sjoerg llvm::DiagnosticSeverity Severity = DI.getSeverity();
7647330f729Sjoerg // Get the diagnostic ID based.
7657330f729Sjoerg switch (DI.getKind()) {
7667330f729Sjoerg case llvm::DK_InlineAsm:
7677330f729Sjoerg if (InlineAsmDiagHandler(cast<DiagnosticInfoInlineAsm>(DI)))
7687330f729Sjoerg return;
7697330f729Sjoerg ComputeDiagID(Severity, inline_asm, DiagID);
7707330f729Sjoerg break;
771*e038c9c4Sjoerg case llvm::DK_SrcMgr:
772*e038c9c4Sjoerg SrcMgrDiagHandler(cast<DiagnosticInfoSrcMgr>(DI));
773*e038c9c4Sjoerg return;
7747330f729Sjoerg case llvm::DK_StackSize:
7757330f729Sjoerg if (StackSizeDiagHandler(cast<DiagnosticInfoStackSize>(DI)))
7767330f729Sjoerg return;
7777330f729Sjoerg ComputeDiagID(Severity, backend_frame_larger_than, DiagID);
7787330f729Sjoerg break;
7797330f729Sjoerg case DK_Linker:
7807330f729Sjoerg assert(CurLinkModule);
7817330f729Sjoerg // FIXME: stop eating the warnings and notes.
7827330f729Sjoerg if (Severity != DS_Error)
7837330f729Sjoerg return;
7847330f729Sjoerg DiagID = diag::err_fe_cannot_link_module;
7857330f729Sjoerg break;
7867330f729Sjoerg case llvm::DK_OptimizationRemark:
7877330f729Sjoerg // Optimization remarks are always handled completely by this
7887330f729Sjoerg // handler. There is no generic way of emitting them.
7897330f729Sjoerg OptimizationRemarkHandler(cast<OptimizationRemark>(DI));
7907330f729Sjoerg return;
7917330f729Sjoerg case llvm::DK_OptimizationRemarkMissed:
7927330f729Sjoerg // Optimization remarks are always handled completely by this
7937330f729Sjoerg // handler. There is no generic way of emitting them.
7947330f729Sjoerg OptimizationRemarkHandler(cast<OptimizationRemarkMissed>(DI));
7957330f729Sjoerg return;
7967330f729Sjoerg case llvm::DK_OptimizationRemarkAnalysis:
7977330f729Sjoerg // Optimization remarks are always handled completely by this
7987330f729Sjoerg // handler. There is no generic way of emitting them.
7997330f729Sjoerg OptimizationRemarkHandler(cast<OptimizationRemarkAnalysis>(DI));
8007330f729Sjoerg return;
8017330f729Sjoerg case llvm::DK_OptimizationRemarkAnalysisFPCommute:
8027330f729Sjoerg // Optimization remarks are always handled completely by this
8037330f729Sjoerg // handler. There is no generic way of emitting them.
8047330f729Sjoerg OptimizationRemarkHandler(cast<OptimizationRemarkAnalysisFPCommute>(DI));
8057330f729Sjoerg return;
8067330f729Sjoerg case llvm::DK_OptimizationRemarkAnalysisAliasing:
8077330f729Sjoerg // Optimization remarks are always handled completely by this
8087330f729Sjoerg // handler. There is no generic way of emitting them.
8097330f729Sjoerg OptimizationRemarkHandler(cast<OptimizationRemarkAnalysisAliasing>(DI));
8107330f729Sjoerg return;
8117330f729Sjoerg case llvm::DK_MachineOptimizationRemark:
8127330f729Sjoerg // Optimization remarks are always handled completely by this
8137330f729Sjoerg // handler. There is no generic way of emitting them.
8147330f729Sjoerg OptimizationRemarkHandler(cast<MachineOptimizationRemark>(DI));
8157330f729Sjoerg return;
8167330f729Sjoerg case llvm::DK_MachineOptimizationRemarkMissed:
8177330f729Sjoerg // Optimization remarks are always handled completely by this
8187330f729Sjoerg // handler. There is no generic way of emitting them.
8197330f729Sjoerg OptimizationRemarkHandler(cast<MachineOptimizationRemarkMissed>(DI));
8207330f729Sjoerg return;
8217330f729Sjoerg case llvm::DK_MachineOptimizationRemarkAnalysis:
8227330f729Sjoerg // Optimization remarks are always handled completely by this
8237330f729Sjoerg // handler. There is no generic way of emitting them.
8247330f729Sjoerg OptimizationRemarkHandler(cast<MachineOptimizationRemarkAnalysis>(DI));
8257330f729Sjoerg return;
8267330f729Sjoerg case llvm::DK_OptimizationFailure:
8277330f729Sjoerg // Optimization failures are always handled completely by this
8287330f729Sjoerg // handler.
8297330f729Sjoerg OptimizationFailureHandler(cast<DiagnosticInfoOptimizationFailure>(DI));
8307330f729Sjoerg return;
8317330f729Sjoerg case llvm::DK_Unsupported:
8327330f729Sjoerg UnsupportedDiagHandler(cast<DiagnosticInfoUnsupported>(DI));
8337330f729Sjoerg return;
8347330f729Sjoerg default:
8357330f729Sjoerg // Plugin IDs are not bound to any value as they are set dynamically.
8367330f729Sjoerg ComputeDiagRemarkID(Severity, backend_plugin, DiagID);
8377330f729Sjoerg break;
8387330f729Sjoerg }
8397330f729Sjoerg std::string MsgStorage;
8407330f729Sjoerg {
8417330f729Sjoerg raw_string_ostream Stream(MsgStorage);
8427330f729Sjoerg DiagnosticPrinterRawOStream DP(Stream);
8437330f729Sjoerg DI.print(DP);
8447330f729Sjoerg }
8457330f729Sjoerg
8467330f729Sjoerg if (DiagID == diag::err_fe_cannot_link_module) {
8477330f729Sjoerg Diags.Report(diag::err_fe_cannot_link_module)
8487330f729Sjoerg << CurLinkModule->getModuleIdentifier() << MsgStorage;
8497330f729Sjoerg return;
8507330f729Sjoerg }
8517330f729Sjoerg
8527330f729Sjoerg // Report the backend message using the usual diagnostic mechanism.
8537330f729Sjoerg FullSourceLoc Loc;
8547330f729Sjoerg Diags.Report(Loc, DiagID).AddString(MsgStorage);
8557330f729Sjoerg }
8567330f729Sjoerg #undef ComputeDiagID
8577330f729Sjoerg
CodeGenAction(unsigned _Act,LLVMContext * _VMContext)8587330f729Sjoerg CodeGenAction::CodeGenAction(unsigned _Act, LLVMContext *_VMContext)
8597330f729Sjoerg : Act(_Act), VMContext(_VMContext ? _VMContext : new LLVMContext),
8607330f729Sjoerg OwnsVMContext(!_VMContext) {}
8617330f729Sjoerg
~CodeGenAction()8627330f729Sjoerg CodeGenAction::~CodeGenAction() {
8637330f729Sjoerg TheModule.reset();
8647330f729Sjoerg if (OwnsVMContext)
8657330f729Sjoerg delete VMContext;
8667330f729Sjoerg }
8677330f729Sjoerg
hasIRSupport() const8687330f729Sjoerg bool CodeGenAction::hasIRSupport() const { return true; }
8697330f729Sjoerg
EndSourceFileAction()8707330f729Sjoerg void CodeGenAction::EndSourceFileAction() {
8717330f729Sjoerg // If the consumer creation failed, do nothing.
8727330f729Sjoerg if (!getCompilerInstance().hasASTConsumer())
8737330f729Sjoerg return;
8747330f729Sjoerg
8757330f729Sjoerg // Steal the module from the consumer.
8767330f729Sjoerg TheModule = BEConsumer->takeModule();
8777330f729Sjoerg }
8787330f729Sjoerg
takeModule()8797330f729Sjoerg std::unique_ptr<llvm::Module> CodeGenAction::takeModule() {
8807330f729Sjoerg return std::move(TheModule);
8817330f729Sjoerg }
8827330f729Sjoerg
takeLLVMContext()8837330f729Sjoerg llvm::LLVMContext *CodeGenAction::takeLLVMContext() {
8847330f729Sjoerg OwnsVMContext = false;
8857330f729Sjoerg return VMContext;
8867330f729Sjoerg }
8877330f729Sjoerg
getCodeGenerator() const888*e038c9c4Sjoerg CodeGenerator *CodeGenAction::getCodeGenerator() const {
889*e038c9c4Sjoerg return BEConsumer->getCodeGenerator();
890*e038c9c4Sjoerg }
891*e038c9c4Sjoerg
8927330f729Sjoerg static std::unique_ptr<raw_pwrite_stream>
GetOutputStream(CompilerInstance & CI,StringRef InFile,BackendAction Action)8937330f729Sjoerg GetOutputStream(CompilerInstance &CI, StringRef InFile, BackendAction Action) {
8947330f729Sjoerg switch (Action) {
8957330f729Sjoerg case Backend_EmitAssembly:
8967330f729Sjoerg return CI.createDefaultOutputFile(false, InFile, "s");
8977330f729Sjoerg case Backend_EmitLL:
8987330f729Sjoerg return CI.createDefaultOutputFile(false, InFile, "ll");
8997330f729Sjoerg case Backend_EmitBC:
9007330f729Sjoerg return CI.createDefaultOutputFile(true, InFile, "bc");
9017330f729Sjoerg case Backend_EmitNothing:
9027330f729Sjoerg return nullptr;
9037330f729Sjoerg case Backend_EmitMCNull:
9047330f729Sjoerg return CI.createNullOutputFile();
9057330f729Sjoerg case Backend_EmitObj:
9067330f729Sjoerg return CI.createDefaultOutputFile(true, InFile, "o");
9077330f729Sjoerg }
9087330f729Sjoerg
9097330f729Sjoerg llvm_unreachable("Invalid action!");
9107330f729Sjoerg }
9117330f729Sjoerg
9127330f729Sjoerg std::unique_ptr<ASTConsumer>
CreateASTConsumer(CompilerInstance & CI,StringRef InFile)9137330f729Sjoerg CodeGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
9147330f729Sjoerg BackendAction BA = static_cast<BackendAction>(Act);
9157330f729Sjoerg std::unique_ptr<raw_pwrite_stream> OS = CI.takeOutputStream();
9167330f729Sjoerg if (!OS)
9177330f729Sjoerg OS = GetOutputStream(CI, InFile, BA);
9187330f729Sjoerg
9197330f729Sjoerg if (BA != Backend_EmitNothing && !OS)
9207330f729Sjoerg return nullptr;
9217330f729Sjoerg
9227330f729Sjoerg // Load bitcode modules to link with, if we need to.
9237330f729Sjoerg if (LinkModules.empty())
9247330f729Sjoerg for (const CodeGenOptions::BitcodeFileToLink &F :
9257330f729Sjoerg CI.getCodeGenOpts().LinkBitcodeFiles) {
9267330f729Sjoerg auto BCBuf = CI.getFileManager().getBufferForFile(F.Filename);
9277330f729Sjoerg if (!BCBuf) {
9287330f729Sjoerg CI.getDiagnostics().Report(diag::err_cannot_open_file)
9297330f729Sjoerg << F.Filename << BCBuf.getError().message();
9307330f729Sjoerg LinkModules.clear();
9317330f729Sjoerg return nullptr;
9327330f729Sjoerg }
9337330f729Sjoerg
9347330f729Sjoerg Expected<std::unique_ptr<llvm::Module>> ModuleOrErr =
9357330f729Sjoerg getOwningLazyBitcodeModule(std::move(*BCBuf), *VMContext);
9367330f729Sjoerg if (!ModuleOrErr) {
9377330f729Sjoerg handleAllErrors(ModuleOrErr.takeError(), [&](ErrorInfoBase &EIB) {
9387330f729Sjoerg CI.getDiagnostics().Report(diag::err_cannot_open_file)
9397330f729Sjoerg << F.Filename << EIB.message();
9407330f729Sjoerg });
9417330f729Sjoerg LinkModules.clear();
9427330f729Sjoerg return nullptr;
9437330f729Sjoerg }
9447330f729Sjoerg LinkModules.push_back({std::move(ModuleOrErr.get()), F.PropagateAttrs,
9457330f729Sjoerg F.Internalize, F.LinkFlags});
9467330f729Sjoerg }
9477330f729Sjoerg
9487330f729Sjoerg CoverageSourceInfo *CoverageInfo = nullptr;
9497330f729Sjoerg // Add the preprocessor callback only when the coverage mapping is generated.
950*e038c9c4Sjoerg if (CI.getCodeGenOpts().CoverageMapping)
951*e038c9c4Sjoerg CoverageInfo = CodeGen::CoverageMappingModuleGen::setUpCoverageCallbacks(
952*e038c9c4Sjoerg CI.getPreprocessor());
9537330f729Sjoerg
9547330f729Sjoerg std::unique_ptr<BackendConsumer> Result(new BackendConsumer(
9557330f729Sjoerg BA, CI.getDiagnostics(), CI.getHeaderSearchOpts(),
9567330f729Sjoerg CI.getPreprocessorOpts(), CI.getCodeGenOpts(), CI.getTargetOpts(),
957*e038c9c4Sjoerg CI.getLangOpts(), std::string(InFile), std::move(LinkModules),
958*e038c9c4Sjoerg std::move(OS), *VMContext, CoverageInfo));
9597330f729Sjoerg BEConsumer = Result.get();
9607330f729Sjoerg
9617330f729Sjoerg // Enable generating macro debug info only when debug info is not disabled and
9627330f729Sjoerg // also macro debug info is enabled.
9637330f729Sjoerg if (CI.getCodeGenOpts().getDebugInfo() != codegenoptions::NoDebugInfo &&
9647330f729Sjoerg CI.getCodeGenOpts().MacroDebugInfo) {
9657330f729Sjoerg std::unique_ptr<PPCallbacks> Callbacks =
9667330f729Sjoerg std::make_unique<MacroPPCallbacks>(BEConsumer->getCodeGenerator(),
9677330f729Sjoerg CI.getPreprocessor());
9687330f729Sjoerg CI.getPreprocessor().addPPCallbacks(std::move(Callbacks));
9697330f729Sjoerg }
9707330f729Sjoerg
9717330f729Sjoerg return std::move(Result);
9727330f729Sjoerg }
9737330f729Sjoerg
9747330f729Sjoerg std::unique_ptr<llvm::Module>
loadModule(MemoryBufferRef MBRef)9757330f729Sjoerg CodeGenAction::loadModule(MemoryBufferRef MBRef) {
9767330f729Sjoerg CompilerInstance &CI = getCompilerInstance();
9777330f729Sjoerg SourceManager &SM = CI.getSourceManager();
9787330f729Sjoerg
9797330f729Sjoerg // For ThinLTO backend invocations, ensure that the context
9807330f729Sjoerg // merges types based on ODR identifiers. We also need to read
9817330f729Sjoerg // the correct module out of a multi-module bitcode file.
9827330f729Sjoerg if (!CI.getCodeGenOpts().ThinLTOIndexFile.empty()) {
9837330f729Sjoerg VMContext->enableDebugTypeODRUniquing();
9847330f729Sjoerg
9857330f729Sjoerg auto DiagErrors = [&](Error E) -> std::unique_ptr<llvm::Module> {
9867330f729Sjoerg unsigned DiagID =
9877330f729Sjoerg CI.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error, "%0");
9887330f729Sjoerg handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
9897330f729Sjoerg CI.getDiagnostics().Report(DiagID) << EIB.message();
9907330f729Sjoerg });
9917330f729Sjoerg return {};
9927330f729Sjoerg };
9937330f729Sjoerg
9947330f729Sjoerg Expected<std::vector<BitcodeModule>> BMsOrErr = getBitcodeModuleList(MBRef);
9957330f729Sjoerg if (!BMsOrErr)
9967330f729Sjoerg return DiagErrors(BMsOrErr.takeError());
997*e038c9c4Sjoerg BitcodeModule *Bm = llvm::lto::findThinLTOModule(*BMsOrErr);
9987330f729Sjoerg // We have nothing to do if the file contains no ThinLTO module. This is
9997330f729Sjoerg // possible if ThinLTO compilation was not able to split module. Content of
10007330f729Sjoerg // the file was already processed by indexing and will be passed to the
10017330f729Sjoerg // linker using merged object file.
10027330f729Sjoerg if (!Bm) {
10037330f729Sjoerg auto M = std::make_unique<llvm::Module>("empty", *VMContext);
10047330f729Sjoerg M->setTargetTriple(CI.getTargetOpts().Triple);
10057330f729Sjoerg return M;
10067330f729Sjoerg }
10077330f729Sjoerg Expected<std::unique_ptr<llvm::Module>> MOrErr =
10087330f729Sjoerg Bm->parseModule(*VMContext);
10097330f729Sjoerg if (!MOrErr)
10107330f729Sjoerg return DiagErrors(MOrErr.takeError());
10117330f729Sjoerg return std::move(*MOrErr);
10127330f729Sjoerg }
10137330f729Sjoerg
10147330f729Sjoerg llvm::SMDiagnostic Err;
10157330f729Sjoerg if (std::unique_ptr<llvm::Module> M = parseIR(MBRef, Err, *VMContext))
10167330f729Sjoerg return M;
10177330f729Sjoerg
10187330f729Sjoerg // Translate from the diagnostic info to the SourceManager location if
10197330f729Sjoerg // available.
10207330f729Sjoerg // TODO: Unify this with ConvertBackendLocation()
10217330f729Sjoerg SourceLocation Loc;
10227330f729Sjoerg if (Err.getLineNo() > 0) {
10237330f729Sjoerg assert(Err.getColumnNo() >= 0);
10247330f729Sjoerg Loc = SM.translateFileLineCol(SM.getFileEntryForID(SM.getMainFileID()),
10257330f729Sjoerg Err.getLineNo(), Err.getColumnNo() + 1);
10267330f729Sjoerg }
10277330f729Sjoerg
10287330f729Sjoerg // Strip off a leading diagnostic code if there is one.
10297330f729Sjoerg StringRef Msg = Err.getMessage();
10307330f729Sjoerg if (Msg.startswith("error: "))
10317330f729Sjoerg Msg = Msg.substr(7);
10327330f729Sjoerg
10337330f729Sjoerg unsigned DiagID =
10347330f729Sjoerg CI.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error, "%0");
10357330f729Sjoerg
10367330f729Sjoerg CI.getDiagnostics().Report(Loc, DiagID) << Msg;
10377330f729Sjoerg return {};
10387330f729Sjoerg }
10397330f729Sjoerg
ExecuteAction()10407330f729Sjoerg void CodeGenAction::ExecuteAction() {
1041*e038c9c4Sjoerg if (getCurrentFileKind().getLanguage() != Language::LLVM_IR) {
1042*e038c9c4Sjoerg this->ASTFrontendAction::ExecuteAction();
1043*e038c9c4Sjoerg return;
1044*e038c9c4Sjoerg }
1045*e038c9c4Sjoerg
10467330f729Sjoerg // If this is an IR file, we have to treat it specially.
10477330f729Sjoerg BackendAction BA = static_cast<BackendAction>(Act);
10487330f729Sjoerg CompilerInstance &CI = getCompilerInstance();
1049*e038c9c4Sjoerg auto &CodeGenOpts = CI.getCodeGenOpts();
1050*e038c9c4Sjoerg auto &Diagnostics = CI.getDiagnostics();
10517330f729Sjoerg std::unique_ptr<raw_pwrite_stream> OS =
10527330f729Sjoerg GetOutputStream(CI, getCurrentFile(), BA);
10537330f729Sjoerg if (BA != Backend_EmitNothing && !OS)
10547330f729Sjoerg return;
10557330f729Sjoerg
10567330f729Sjoerg SourceManager &SM = CI.getSourceManager();
10577330f729Sjoerg FileID FID = SM.getMainFileID();
1058*e038c9c4Sjoerg Optional<MemoryBufferRef> MainFile = SM.getBufferOrNone(FID);
1059*e038c9c4Sjoerg if (!MainFile)
10607330f729Sjoerg return;
10617330f729Sjoerg
10627330f729Sjoerg TheModule = loadModule(*MainFile);
10637330f729Sjoerg if (!TheModule)
10647330f729Sjoerg return;
10657330f729Sjoerg
10667330f729Sjoerg const TargetOptions &TargetOpts = CI.getTargetOpts();
10677330f729Sjoerg if (TheModule->getTargetTriple() != TargetOpts.Triple) {
1068*e038c9c4Sjoerg Diagnostics.Report(SourceLocation(), diag::warn_fe_override_module)
10697330f729Sjoerg << TargetOpts.Triple;
10707330f729Sjoerg TheModule->setTargetTriple(TargetOpts.Triple);
10717330f729Sjoerg }
10727330f729Sjoerg
1073*e038c9c4Sjoerg EmbedBitcode(TheModule.get(), CodeGenOpts, *MainFile);
10747330f729Sjoerg
10757330f729Sjoerg LLVMContext &Ctx = TheModule->getContext();
10767330f729Sjoerg
1077*e038c9c4Sjoerg // Restore any diagnostic handler previously set before returning from this
1078*e038c9c4Sjoerg // function.
1079*e038c9c4Sjoerg struct RAII {
1080*e038c9c4Sjoerg LLVMContext &Ctx;
1081*e038c9c4Sjoerg std::unique_ptr<DiagnosticHandler> PrevHandler = Ctx.getDiagnosticHandler();
1082*e038c9c4Sjoerg ~RAII() { Ctx.setDiagnosticHandler(std::move(PrevHandler)); }
1083*e038c9c4Sjoerg } _{Ctx};
1084*e038c9c4Sjoerg
1085*e038c9c4Sjoerg // Set clang diagnostic handler. To do this we need to create a fake
1086*e038c9c4Sjoerg // BackendConsumer.
1087*e038c9c4Sjoerg BackendConsumer Result(BA, CI.getDiagnostics(), CI.getHeaderSearchOpts(),
1088*e038c9c4Sjoerg CI.getPreprocessorOpts(), CI.getCodeGenOpts(),
1089*e038c9c4Sjoerg CI.getTargetOpts(), CI.getLangOpts(),
1090*e038c9c4Sjoerg std::move(LinkModules), *VMContext, nullptr);
1091*e038c9c4Sjoerg // PR44896: Force DiscardValueNames as false. DiscardValueNames cannot be
1092*e038c9c4Sjoerg // true here because the valued names are needed for reading textual IR.
1093*e038c9c4Sjoerg Ctx.setDiscardValueNames(false);
1094*e038c9c4Sjoerg Ctx.setDiagnosticHandler(
1095*e038c9c4Sjoerg std::make_unique<ClangDiagnosticHandler>(CodeGenOpts, &Result));
1096*e038c9c4Sjoerg
1097*e038c9c4Sjoerg Expected<std::unique_ptr<llvm::ToolOutputFile>> OptRecordFileOrErr =
1098*e038c9c4Sjoerg setupLLVMOptimizationRemarks(
1099*e038c9c4Sjoerg Ctx, CodeGenOpts.OptRecordFile, CodeGenOpts.OptRecordPasses,
1100*e038c9c4Sjoerg CodeGenOpts.OptRecordFormat, CodeGenOpts.DiagnosticsWithHotness,
1101*e038c9c4Sjoerg CodeGenOpts.DiagnosticsHotnessThreshold);
1102*e038c9c4Sjoerg
1103*e038c9c4Sjoerg if (Error E = OptRecordFileOrErr.takeError()) {
1104*e038c9c4Sjoerg reportOptRecordError(std::move(E), Diagnostics, CodeGenOpts);
11057330f729Sjoerg return;
11067330f729Sjoerg }
1107*e038c9c4Sjoerg std::unique_ptr<llvm::ToolOutputFile> OptRecordFile =
1108*e038c9c4Sjoerg std::move(*OptRecordFileOrErr);
11097330f729Sjoerg
1110*e038c9c4Sjoerg EmitBackendOutput(Diagnostics, CI.getHeaderSearchOpts(), CodeGenOpts,
1111*e038c9c4Sjoerg TargetOpts, CI.getLangOpts(),
1112*e038c9c4Sjoerg CI.getTarget().getDataLayoutString(), TheModule.get(), BA,
1113*e038c9c4Sjoerg std::move(OS));
1114*e038c9c4Sjoerg if (OptRecordFile)
1115*e038c9c4Sjoerg OptRecordFile->keep();
11167330f729Sjoerg }
11177330f729Sjoerg
11187330f729Sjoerg //
11197330f729Sjoerg
anchor()11207330f729Sjoerg void EmitAssemblyAction::anchor() { }
EmitAssemblyAction(llvm::LLVMContext * _VMContext)11217330f729Sjoerg EmitAssemblyAction::EmitAssemblyAction(llvm::LLVMContext *_VMContext)
11227330f729Sjoerg : CodeGenAction(Backend_EmitAssembly, _VMContext) {}
11237330f729Sjoerg
anchor()11247330f729Sjoerg void EmitBCAction::anchor() { }
EmitBCAction(llvm::LLVMContext * _VMContext)11257330f729Sjoerg EmitBCAction::EmitBCAction(llvm::LLVMContext *_VMContext)
11267330f729Sjoerg : CodeGenAction(Backend_EmitBC, _VMContext) {}
11277330f729Sjoerg
anchor()11287330f729Sjoerg void EmitLLVMAction::anchor() { }
EmitLLVMAction(llvm::LLVMContext * _VMContext)11297330f729Sjoerg EmitLLVMAction::EmitLLVMAction(llvm::LLVMContext *_VMContext)
11307330f729Sjoerg : CodeGenAction(Backend_EmitLL, _VMContext) {}
11317330f729Sjoerg
anchor()11327330f729Sjoerg void EmitLLVMOnlyAction::anchor() { }
EmitLLVMOnlyAction(llvm::LLVMContext * _VMContext)11337330f729Sjoerg EmitLLVMOnlyAction::EmitLLVMOnlyAction(llvm::LLVMContext *_VMContext)
11347330f729Sjoerg : CodeGenAction(Backend_EmitNothing, _VMContext) {}
11357330f729Sjoerg
anchor()11367330f729Sjoerg void EmitCodeGenOnlyAction::anchor() { }
EmitCodeGenOnlyAction(llvm::LLVMContext * _VMContext)11377330f729Sjoerg EmitCodeGenOnlyAction::EmitCodeGenOnlyAction(llvm::LLVMContext *_VMContext)
11387330f729Sjoerg : CodeGenAction(Backend_EmitMCNull, _VMContext) {}
11397330f729Sjoerg
anchor()11407330f729Sjoerg void EmitObjAction::anchor() { }
EmitObjAction(llvm::LLVMContext * _VMContext)11417330f729Sjoerg EmitObjAction::EmitObjAction(llvm::LLVMContext *_VMContext)
11427330f729Sjoerg : CodeGenAction(Backend_EmitObj, _VMContext) {}
1143